├── .gitattributes ├── .gitignore ├── .reuse └── dep5 ├── CHANGELOG ├── CODE_OF_CONDUCT.md ├── COPYING ├── LICENSE ├── LICENSES ├── GPL-3.0-or-later.txt └── LicenseRef-BSD-3-Clause-Almost.txt ├── Makefile ├── README.md ├── attributes.freebsd ├── attributes.linux ├── attributes.macos ├── attributes.netbsd ├── attributes.openbsd ├── attributes.reserve ├── configure ├── gcov_summary ├── md2html ├── rawhide.conf ├── rawhide.conf.5.pod ├── rawhide.spec ├── rh.1.pod ├── rh.c ├── rh.h ├── rhcmds.c ├── rhcmds.h ├── rhdata.c ├── rhdata.h ├── rhdir.c ├── rhdir.h ├── rherr.c ├── rherr.h ├── rhparse.c ├── rhparse.h ├── rhstr.c ├── rhstr.h ├── runtests ├── samples ├── .rh.sh ├── README ├── brevity.rh └── rawhide.conf-tiny └── tests ├── .common ├── .new ├── t01 ├── t02 ├── t03 ├── t04 ├── t05 ├── t06 ├── t07 ├── t08 ├── t09 ├── t10 ├── t11 ├── t12 ├── t13 ├── t14 ├── t15 ├── t16 ├── t17 ├── t18 ├── t19 ├── t20 ├── t21 ├── t22 ├── t23 ├── t24 ├── t25 ├── t26 ├── t27 ├── t28 ├── t29 └── t30 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Pretend that tests are vendored to exclude them from the language stats. 2 | # Using linguist-detectable=false would be preferable, but that doesn't 3 | # work on codeberg. Without this, linguist thinks the main language is 4 | # shell, because there's twice as much test code as real code. 5 | 6 | tests/* linguist-vendored 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.sw? 2 | tags 3 | *.o 4 | rh 5 | *.html 6 | *.1 7 | *.5 8 | -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: rawhide 3 | Upstream-Contact: raf 4 | Source: https://raf.org/rawhide 5 | 6 | Files: * 7 | Copyright: 1990 Ken Stauffer, 2022-2023 raf 8 | License: GPL-3.0-or-later 9 | 10 | Files: rhstr.c 11 | Copyright: 1990 Ken Stauffer, 2022-2023 raf 12 | 1998 Todd C. Miller 13 | License: GPL-3.0-or-later and LicenseRef-BSD-3-Clause-Almost 14 | 15 | Files: rh.1.pod 16 | Copyright: 1990 Ken Stauffer, 2022-2023 raf 17 | 1990-2022 Free Software Foundation, Inc 18 | License: GPL-3.0-or-later 19 | 20 | #License: LicenseRef-BSD-3-Clause-Almost 21 | #Redistribution and use in source and binary forms, with or without 22 | #modification, are permitted provided that the following conditions 23 | #are met: 24 | #1. Redistributions of source code must retain the above copyright 25 | # notice, this list of conditions and the following disclaimer. 26 | #2. Redistributions in binary form must reproduce the above copyright 27 | # notice, this list of conditions and the following disclaimer in the 28 | # documentation and/or other materials provided with the distribution. 29 | #3. The name of the author may not be used to endorse or promote products 30 | # derived from this software without specific prior written permission. 31 | #. 32 | #THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 33 | #INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 34 | #AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 35 | #THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 36 | #EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 37 | #PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 38 | #OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 39 | #WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 40 | #OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 41 | #ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 3.3 (20231013) 2 | 3 | - Makefile - Place env CFLAGS after explicit flags so they can override the explicit flags 4 | - configure - Fix --prefix= buglet (only worked if it was the first argument) 5 | - Makefile - Include env CPPFLAGS (just in case) 6 | - configure - Add --macports-prefix for macports with non-default prefix 7 | - configure - Add missing --etcdir and fix --destdir and --mandir 8 | - tests - Adapt to identify new adduser/addgroup help message 9 | - Add body pattern modifiers: .body .ibody .rebody .reibody 10 | - .reuse/dep5 - Make more accurate (strlcpy/strlcat not exactly BSD-3-Clause) 11 | - pcre2 - Stop using the PCRE2_NEVER_BACKSLASH_C option 12 | - configure - Remove 'when present' from pcre2 message for consistency 13 | - configure/tests - Replace `which` with `command -v` (more consistent) 14 | - tests - Make RAWHIDE_TEST_MULTIBYTE_USER_GROUP message shorter 15 | - tests - On FreeBSD chflags uappnd fails on zfs so test with sappnd 16 | - Add -j option (same as -L "%j\n") 17 | - configure - Add --enable-ubsan --enable-asan (undefined behaviour/address sanitizers) 18 | - doc - Show explicit -f- (as distinct from: -f fname) in --help output and SYNOPSIS 19 | - doc - Add rhs/rht/rhz etc. shell functions (rh/-r/-l/-v sorted (via jq) by path/mtime/size) 20 | - doc - Make rawhide.conf(5) manual entry fit in 80 columns again 21 | - doc - Update grammar to include recently added pattern modifiers 22 | - Fix -L %j access_control_list_verbose on FreeBSD/Solaris (wasn't verbose) 23 | - Revoke any setuid/setgid privileges at the start 24 | 25 | 3.2 (20230609) 26 | 27 | - Add support for attr (flags) on FreeBSD, OpenBSD, NetBSD, and macOS 28 | - Add ./configure --default (to avoid needing the details in Makefile) 29 | - Change --help pattern modifiers layout to improve readability 30 | - Remove explicit PCRE2 JIT compilation (had introduced uninitialized reads) 31 | - Add file type pattern modifiers: .what .iwhat .rewhat .reiwhat 32 | - Add MIME type pattern modifiers: .mime .imime .remime .reimime 33 | - Add -L %w (file type description) %W (MIME type) 34 | - Add to -L %j (JSON) output fields: filetype mimetype 35 | 36 | 3.1 (20221011) 37 | 38 | - Add built-in symbols for Linux ext2-style file attributes: attr proj gen 39 | - Add real /etc/rawhide.conf.d/attributes (for Linux with libe2p installed) 40 | - Add reference file fields: attr proj gen attribute project generation 41 | - Add -L %e %J %I conversions (Linux ext2-style file attributes project generation) 42 | - Add to -L %j (JSON) output, Linux ext2-style file attributes project generation 43 | - Add replacing "/".i "/".re "/".rei with implicit "/".ipath "/".repath "/".reipath 44 | - Add identifying pattern modifiers by unique prefixes (e.g., "/".p for "/".path) 45 | - Add "make default" target (extracted from make dist, to undo ./configure) 46 | - Fix -l column width buglet when user/group names contain multi-byte characters 47 | - Fix max path length buglet when crossing filesystem boundaries during traversal 48 | - Allow multiple -f options (but not multiple -f- because stdin can't be read twice) 49 | - Allow -f option argument to be a directory or to have a corresponding .d directory 50 | - Cache test-related getenv values that were being checked many times in normal use 51 | - Add a few more tests to maximize coverage within reason (97.04% on my Debian dev VM) 52 | - Add explicit PCRE2 JIT compilation (not noticeably faster - maybe default behaviour) 53 | 54 | 3.0 (20220330) 55 | 56 | - Update (after 32 years!) to compile and work again (ISO/IEC C, POSIX) 57 | - Remove internal getopt/glob_match, replacing with standard getopt/fnmatch 58 | - Remove MANIFEST (empty) 59 | - Remove META (only relevant for the original comp.source.unix release) 60 | - Add LICENSE COPYING CHANGELOG CODE_OF_CONDUCT.md 61 | - Change -h option so it terminates (was documented behaviour but still wrong) 62 | - Fix insecure multiple potential buffer overruns 63 | - Fix insecure -x shell command injection 64 | - Improve syntax error messages (more informative) 65 | - Increase static code/data/stack space by three orders of magnitude 66 | - Increase identifier length limit to 200 67 | - Add @groupname and @@ expression notation 68 | - Add support for underscore in function/parameter names 69 | - Add support for dot, dash, and underscore in user/group names 70 | - Add support for ~/.rhrc.d/*, /etc/rawhide.conf, and /etc/rawhide.conf.d/* 71 | - Add -N and -n options to suppress system-wide config and user-specific config 72 | - Add // and # single-line comment styles 73 | - Add built-in stat field symbols: blksize blocks 74 | - Change built-in symbols: hours/days/weeks to hour/day/week 75 | - Add built-in number symbols: second minute month year 76 | - Change to default "-e 1" expression to match everything (rather than stdin) 77 | - Add "-f -" convention to read from stdin (now that it's no longer the default) 78 | - Add error reporting during directory traversal (stderr and exit status) 79 | - Interpret two-digit years as being in the current century 80 | - Add built-in number symbols: IRWXU IRUSR IWUSR IXUSR 81 | - Add built-in number symbols: IRWXG IRGRP IWGRP IXGRP 82 | - Add built-in number symbols: IRWXO IROTH IWOTH IXOTH 83 | - Add /etc/rawhide.conf "standard" library (nice names for things, handy functions) 84 | - Remove example rhrc (subsumed by /etc/rawhide.conf) 85 | - Change built-in symbol NOW to now (not backwards compatible!) NOW { now } 86 | - Make "return" and ";" optional in functions (always redundant, more compact) 87 | - Make rh exit with failure status if any -x command exits with failure status 88 | - Add many ruthless tests 89 | - Add -V (version) option 90 | - Add --help and --version options 91 | - Add -0 option (nul-separated output) for use with xargs -0 92 | - Make "-e" optional for lean flexible cmdline (expr can appear among dir args) 93 | - Fix built-in prune over-pruning (wasn't reset until after siblings done) 94 | - Add built-in symbol: exit (terminate immediately - usage: 'expr ? exit : 0') 95 | - Make "return" a keyword token rather than a built-in symbol 96 | - Fix "glob" string tokeniser to handle "\"" 97 | - Fix inaccurate [yyyy/mm/dd] to time_t conversion (use standard mktime) 98 | - Add support for datetimes: [yyyy/mm/dd hh:mm:ss] (ss and mm:ss are optional) 99 | - Make "*" match leading dot (POSIX/GNU find compatible, but not Solaris find) 100 | - Test on Debian, Ubuntu, Fedora, FreeBSD, OpenBSD, NetBSD, macOS, Solaris, Cygwin 101 | - Move some functions from rh.c/rhparse.c to more appropriate modules 102 | - Fix crash on attempt to divide by zero (and modulo) 103 | - Add support for doors (IFDOOR) on Solaris 104 | - Add hexadecimal number literals (0xff) 105 | - Add options -m # (minimum depth) and -M # (maximum depth) 106 | - Fix/Add short-circuit semantics for || and && operators (for "expr && exit") 107 | - Add built-in symbols: nouser nogroup 108 | - Minimize the number of race conditions during traversal (fstatat/openat/fdopendir) 109 | - Add built-in symbols: readable writable executable (faccessat/access) 110 | - Add -X 'cmd' option (like -x with safe cd for minimal race conditions) 111 | - Automatically remove cwd and other non-absolute dirs from $PATH when -X is used 112 | - Add configure script to adjust binary/config/manpage installation locations 113 | - Gzip manual entries when installing on systems that prefer it 114 | - Add -? 'spec' option (debug: cmdline parser traversal exec all extra) 115 | - Add "/path".mtime syntax for comparison against reference files 116 | - Add -D option (depth-first traversal) 117 | - Add -U option (unlink) 118 | - Add heuristic to better identify expr/path when no -e and path doesn't exist 119 | - Make -l (without -v) more like ls -l (add nlink username groupname mtime) 120 | - Add output column options: -d -i -B -s -g -o -a -u -c (mostly ls-compatible) 121 | - Make -v option include all the output columns 122 | - Add other output format options: -H -I -T -# 123 | - Add name output format options: -Q -E -b -q -p -t -F (mostly ls-compatible) 124 | - Change -H and -I to round up (ls-compatible output) 125 | - Add -HH and -II to round half up (more accurate) 126 | - Remove rh.man (troff) in favour of POD format (for html and troff output) 127 | - Re-document everything: README.md rh.1.pod rawhide.conf.5.pod 128 | - Add built-in symbol: today (last midnight local time) 129 | - Add "pattern".modifier syntax for glob modifiers: .i .path .ipath .link .ilink 130 | - Add -1 option (single filesystem - don't cross filesystem boundaries) 131 | - Add built-ins for symlink targets: texists tdev tino tmode tnlink tuid tgid ... 132 | - Add -y option (follow symlinks on the cmdline and in reference files) 133 | - Add -Y option (follow symlinks encountered while searching as well) 134 | - Add $RAWHIDE_REPORT_BROKEN_SYMLINKS to treat broken symlinks as an error 135 | - Add -S option (space column: blocks * 512) 136 | - Add -L 'format' option (output details in user-supplied printf-like format) 137 | - Add defense against terminal escape injection for stdout/stderr (but not debug) 138 | - Add pcre2 pattern modifiers: .re .repath .relink .rei .reipath .reilink 139 | - Add access control list (ACL) pattern modifiers: .acl .iacl .reacl .reiacl 140 | - Add -L %z format (access control list) 141 | - Add extended attribute (EA) pattern modifiers: .ea .iea .reea .reiea 142 | - Add -L %x format (extended attributes) 143 | - Add -L %Z format (selinux context - via ea (not via libselinux)) 144 | - Add "cmd".sh "pattern" modifier syntax to execute shell commands via system() 145 | - Add empty string "".mtime syntax to concisely refer to the last reference file path 146 | - Change size of (readable) directories to num of entries (excluding . and ..) (so empty() works) 147 | - Add decimal token size/scale units suffixes: K M G T P E k m g t p e 148 | - Replace "long" with "long long" everywhere (sorry 1990s!) to get 64-bit numbers on 32-bit systems 149 | - Add memory/file descriptor checking (valgrind): make test with VALGRIND=1 or vg=1 (30s -> 40m) 150 | - Change size of readable directories for -l and -L %s to the number of entries (excluding . and ..) 151 | - Add ACL/EA indicator to -l type/perm column: acl='+' ea='@' both='*' neither=' ' 152 | - Change prune to return 1 not 0 (but make expr 0 overall) so (bad && prune || good) is now possible 153 | - "Fix" %S (for -x/-X/"cmd".sh) so it's "/" for / (was empty) 154 | - Add configure --enable-ndebug --disable-ndebug (stripped binary 10% (12K) smaller with NDEBUG) 155 | - Add RAWHIDE_COLUMN_WIDTH_* env vars for people who don't like columns that widen on demand 156 | - Add configure --static=SIZE ("large" is default, "small" is 10%, "tiny" is 1%, all fine choices) 157 | - Add -L %X format (ACL/EA indicator like in rh -l) 158 | - Add built-in field symbols: major minor rmajor rminor tmajor tminor trmajor trminor 159 | - Add reference file fields: .major .minor .rmajor .rminor 160 | - Add -L %B (blksize) %E (rdev) %r (rdev minor) %R (rdev major) %v (dev minor) %V (dev major) 161 | - Add configure --disable-major (just for preparing the source distribution) 162 | - Add $RAWHIDE_CONFIG and $RAWHIDE_RC (not just for testing, and/but not for root) 163 | - Add configure --enable-mangz --disable-mangz (just so distribution can default to non-gzipped) 164 | - Add to ACL/EA indicator '.' for selinux (if nothing more interesting) (-l and -L %X) 165 | - Add LICENSES/* and .reuse/dep5 (REUSE 3.0 compliant) 166 | - Add built-in symbol: trim (like prune but doesn't prevent the current candidate from matching) 167 | - Change -r to mean -m1 -M1 (was originally just -M1, this is much better) 168 | - Fix -U combined with -y/-Y and symlinks to directories (was attempting rmdir for symlink) 169 | - Add $RAWHIDE_DONT_REPORT_CYCLES to suppress reporting filesystem cycles 170 | - Add gcov test coverage measurement (96.20% overall - remainder manually scrutinized) 171 | - Add configure --enable-gcov --disable-gcov 172 | - Add gcov_summary 173 | - Fix defense against terminal escape injection for stderr when stdout piped to a non-terminal 174 | - Treat "" that contains / as implicit "".path (so that "/" just works) 175 | - Add support for non-ASCII characters (UTF-8/ISO-8859-*) in function/parameter/user/group names 176 | - Don't \ quote non-ASCII characters (UTF-8/ISO-8859-*) in shell command %s %S interpolation 177 | - Add -L %j format (JSON) 178 | - Fix handling of SIGINT/SIGQUIT in -x/-X/"cmd".sh sub-processes (didn't terminate rh as well) 179 | - Add configure --disable-cc-other (just for preparing the source distribution) 180 | - Add make help 181 | - Add make gcov 182 | - Add samples/{README,.rh.sh,brevity.rh,rawhide.conf-tiny} 183 | - Add /etc/rawhide.conf.d/attributes to reserve some identifiers for the next version 184 | 185 | 2.0 (19900218) 186 | 187 | - Initial commit (from comp.sources.unix by Ken Stauffer) 188 | CREDITS 189 | Ken Stauffer - Original author. 190 | Guy Harris - Corrected many portability problems. 191 | David MacKenzie - Manual revisions. Added getopt and glob matching. 192 | Norm Hutchinson - Fixed ungetit(). 193 | 194 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual identity 11 | and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the 27 | overall community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at raf@raf.org. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 126 | at [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | 134 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | COPYING 2 | ======= 3 | rawhide - find files using pretty C expressions 4 | https://raf.org/rawhide 5 | https://github.com/raforg/rawhide 6 | https://codeberg.org/raforg/rawhide 7 | 8 | Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with this program; if not, see . 22 | 23 | $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ 24 | $OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $ 25 | Copyright (c) 1998 Todd C. Miller 26 | 27 | All rights reserved. 28 | 29 | Redistribution and use in source and binary forms, with or without 30 | modification, are permitted provided that the following conditions 31 | are met: 32 | 1. Redistributions of source code must retain the above copyright 33 | notice, this list of conditions and the following disclaimer. 34 | 2. Redistributions in binary form must reproduce the above copyright 35 | notice, this list of conditions and the following disclaimer in the 36 | documentation and/or other materials provided with the distribution. 37 | 3. The name of the author may not be used to endorse or promote products 38 | derived from this software without specific prior written permission. 39 | 40 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 41 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 42 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 43 | THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 44 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 45 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 46 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 47 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 48 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 49 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50 | 51 | -------------------------------------------------------------------------------- 52 | 53 | URL: https://raf.org/rawhide 54 | GIT: https://github.com/raforg/rawhide 55 | GIT: https://codeberg.org/raforg/rawhide 56 | Date: 20231013 57 | Authors: 1990 Ken Stauffer, 2022-2023 raf 58 | 59 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-BSD-3-Clause-Almost.txt: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 1. Redistributions of source code must retain the above copyright 5 | notice, this list of conditions and the following disclaimer. 6 | 2. Redistributions in binary form must reproduce the above copyright 7 | notice, this list of conditions and the following disclaimer in the 8 | documentation and/or other materials provided with the distribution. 9 | 3. The name of the author may not be used to endorse or promote products 10 | derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 13 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 14 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 15 | THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 16 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 18 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 19 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 20 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 21 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | -------------------------------------------------------------------------------- /attributes.freebsd: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf.d/attributes (FreeBSD) 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | /* 5 | This file defines aliases for the built-in symbols for FreeBSD file 6 | flags, and the related constants and predicates. See . 7 | */ 8 | 9 | // Aliases for the FreeBSD file flags built-ins 10 | 11 | flag { attr } 12 | flags { attr } 13 | attrs { attr } 14 | attribute { attr } 15 | attributes { attr } 16 | project { 0 } 17 | generation { 0 } 18 | 19 | // Flag constants from 20 | 21 | # Super-user and owner changeable flags 22 | 23 | UF_SETTABLE { 0x0000ffff } # mask of owner changeable flags 24 | UF_NODUMP { 0x00000001 } # do not dump file 25 | UF_IMMUTABLE { 0x00000002 } # file may not be changed 26 | UF_APPEND { 0x00000004 } # writes to file may only append 27 | UF_OPAQUE { 0x00000008 } # directory is opaque wrt. union 28 | 29 | UF_NOUNLINK { 0x00000010 } # file may not be removed or renamed 30 | UF_SYSTEM { 0x00000080 } # Windows system file bit 31 | UF_SPARSE { 0x00000100 } # sparse file 32 | UF_OFFLINE { 0x00000200 } # file is offline 33 | UF_REPARSE { 0x00000400 } # Windows reparse point file bit 34 | UF_ARCHIVE { 0x00000800 } # file needs to be archived 35 | UF_READONLY { 0x00001000 } # Windows readonly file bit 36 | UF_HIDDEN { 0x00008000 } # file is hidden [same as macOS] 37 | 38 | # Super-user changeable flags 39 | 40 | SF_SETTABLE { 0xffff0000 } # mask of superuser changeable flags 41 | SF_ARCHIVED { 0x00010000 } # file is archived 42 | SF_IMMUTABLE { 0x00020000 } # file may not be changed 43 | SF_APPEND { 0x00040000 } # writes to file may only append 44 | SF_NOUNLINK { 0x00100000 } # file may not be removed or renamed 45 | SF_SNAPSHOT { 0x00200000 } # snapshot inode 46 | 47 | // Flag predicates (canonical, aliases) 48 | 49 | arch { attr & SF_ARCHIVED } 50 | archived { attr & SF_ARCHIVED } 51 | nodump { attr & UF_NODUMP } 52 | opaque { attr & UF_OPAQUE } 53 | sappnd { attr & SF_APPEND } 54 | sappend { attr & SF_APPEND } 55 | schg { attr & UF_IMMUTABLE } 56 | schange { attr & UF_IMMUTABLE } 57 | simmutable { attr & UF_IMMUTABLE } 58 | snapshot { attr & SF_SNAPSHOT } 59 | sunlnk { attr & SF_NOUNLINK } 60 | sunlink { attr & SF_NOUNLINK } 61 | uappnd { attr & UF_APPEND } 62 | uappend { attr & UF_APPEND } 63 | uarch { attr & UF_ARCHIVE } 64 | uarchive { attr & UF_ARCHIVE } 65 | uchg { attr & SF_IMMUTABLE } 66 | uchange { attr & SF_IMMUTABLE } 67 | uimmutable { attr & SF_IMMUTABLE } 68 | uhidden { attr & UF_HIDDEN } 69 | hidden { attr & UF_HIDDEN } 70 | uoffline { attr & UF_OFFLINE } 71 | offline { attr & UF_OFFLINE } 72 | urdonly { attr & UF_READONLY } 73 | rdonly { attr & UF_READONLY } 74 | readonly { attr & UF_READONLY } 75 | usparse { attr & UF_SPARSE } 76 | sparse { attr & UF_SPARSE } 77 | usystem { attr & UF_SYSTEM } 78 | system { attr & UF_SYSTEM } 79 | ureparse { attr & UF_REPARSE } 80 | reparse { attr & UF_REPARSE } 81 | uunlnk { attr & UF_NOUNLINK } 82 | uunlink { attr & UF_NOUNLINK } 83 | 84 | append { uappend | sappend } 85 | immutable { uimmutable | simmutable } 86 | nounlink { uunlink | sunlink } 87 | unlink { uunlink | sunlink } 88 | 89 | -------------------------------------------------------------------------------- /attributes.linux: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf.d/attributes (Linux) 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | /* 5 | This file defines aliases for the built-in symbols for the 6 | Linux ext2-style file attributes, and the related constants 7 | and predicates. See and . 8 | */ 9 | 10 | // Aliases for the Linux ext2-style attribute built-ins 11 | 12 | flag { attr } 13 | flags { attr } 14 | attrs { attr } 15 | attribute { attr } 16 | attributes { attr } 17 | project { proj } 18 | generation { gen } 19 | 20 | // Attribute constants from 21 | 22 | ATTR_SECRM { 0x00000001 } # Secure deletion 23 | ATTR_UNRM { 0x00000002 } # Undelete 24 | ATTR_COMPR { 0x00000004 } # Compress file 25 | ATTR_SYNC { 0x00000008 } # Synchronous updates 26 | ATTR_IMMUTABLE { 0x00000010 } # Immutable file 27 | ATTR_APPEND { 0x00000020 } # Writes to file may only append 28 | ATTR_NODUMP { 0x00000040 } # Do not dump file 29 | ATTR_NOATIME { 0x00000080 } # Do not update atime 30 | ATTR_DIRTY { 0x00000100 } 31 | ATTR_COMPRBLK { 0x00000200 } # One or more compressed clusters 32 | ATTR_NOCOMPR { 0x00000400 } # Access raw compressed data 33 | ATTR_ENCRYPT { 0x00000800 } # Encrypted 34 | ATTR_BTREE { 0x00001000 } # Btree format directory 35 | ATTR_INDEX { 0x00001000 } # Hash-indexed directory 36 | ATTR_IMAGIC { 0x00002000 } 37 | ATTR_JOURNAL_DATA { 0x00004000 } # File data should be journaled 38 | ATTR_NOTAIL { 0x00008000 } # File tail should not be merged 39 | ATTR_DIRSYNC { 0x00010000 } # Synchronous dir modifications 40 | ATTR_TOPDIR { 0x00020000 } # Top of directory hierarchies 41 | ATTR_HUGE_FILE { 0x00040000 } # Set to each huge file 42 | ATTR_EXTENTS { 0x00080000 } # Inode uses extents 43 | ATTR_VERITY { 0x00100000 } # Verity protected inode 44 | ATTR_EA_INODE { 0x00200000 } # Inode used for large EA 45 | ATTR_NOCOW { 0x00800000 } # Do not cow file 46 | ATTR_SNAPFILE { 0x01000000 } # Inode is a snapshot 47 | ATTR_DAX { 0x02000000 } # Inode is DAX 48 | ATTR_SNAPFILE_DELETED { 0x04000000 } # Snapshot is being deleted 49 | ATTR_SNAPFILE_SHRUNK { 0x08000000 } # Snapshot shrink has completed 50 | ATTR_INLINE_DATA { 0x10000000 } # Inode has inline data 51 | ATTR_PROJINHERIT { 0x20000000 } # Create with parents projid 52 | ATTR_CASEFOLD { 0x40000000 } # Casefolded file 53 | 54 | // Attribute predicates (canonical, aliases) 55 | 56 | secrm { attr & ATTR_SECRM } 57 | unrm { attr & ATTR_UNRM } 58 | compr { attr & ATTR_COMPR } 59 | sync { attr & ATTR_SYNC } 60 | immutable { attr & ATTR_IMMUTABLE } 61 | append { attr & ATTR_APPEND } 62 | nodump { attr & ATTR_NODUMP } 63 | noatime { attr & ATTR_NOATIME } 64 | dirty { attr & ATTR_DIRTY } 65 | comprblk { attr & ATTR_COMPRBLK } 66 | nocompr { attr & ATTR_NOCOMPR } 67 | encrypt { attr & ATTR_ENCRYPT } 68 | btree { attr & ATTR_BTREE } 69 | index { attr & ATTR_INDEX } 70 | imagic { attr & ATTR_IMAGIC } 71 | journal_data { attr & ATTR_JOURNAL_DATA } 72 | notail { attr & ATTR_NOTAIL } 73 | dirsync { attr & ATTR_DIRSYNC } 74 | topdir { attr & ATTR_TOPDIR } 75 | huge_file { attr & ATTR_HUGE_FILE } 76 | extents { attr & ATTR_EXTENTS } 77 | verity { attr & ATTR_VERITY } 78 | ea_inode { attr & ATTR_EA_INODE } 79 | nocow { attr & ATTR_NOCOW } 80 | snapfile { attr & ATTR_SNAPFILE } 81 | dax { attr & ATTR_DAX } 82 | snapfile_deleted { attr & ATTR_SNAPFILE_DELETED } 83 | snapfile_shrunk { attr & ATTR_SNAPFILE_SHRUNK } 84 | inline_data { attr & ATTR_INLINE_DATA } 85 | projinherit { attr & ATTR_PROJINHERIT } 86 | casefold { attr & ATTR_CASEFOLD } 87 | 88 | secure_deletion { secrm } 89 | undelete { unrm } 90 | compressed { compr } 91 | synchronous { sync } 92 | append_only { append } 93 | nocompression { nocompr } 94 | encrypted { encrypt } 95 | indexed { index } 96 | direct_access { dax } 97 | inherit_project { projinherit } 98 | 99 | attr_s { secrm } 100 | attr_u { unrm } 101 | attr_c { compr } 102 | attr_S { sync } 103 | attr_i { immutable } 104 | attr_a { append } 105 | attr_d { nodump } 106 | attr_A { noatime } 107 | attr_m { nocompr } 108 | attr_E { encrypt } 109 | attr_I { index } 110 | attr_j { journal_data } 111 | attr_t { notail } 112 | attr_D { dirsync } 113 | attr_T { topdir } 114 | attr_e { extents } 115 | attr_V { verity } 116 | attr_C { nocow } 117 | attr_x { dax } 118 | attr_N { inline_data } 119 | attr_P { projinherit } 120 | attr_F { casefold } 121 | 122 | -------------------------------------------------------------------------------- /attributes.macos: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf.d/attributes (macOS) 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | /* 5 | This file defines aliases for the built-in symbols for macOS file 6 | flags, and the related constants and predicates. See . 7 | */ 8 | 9 | // Aliases for the macOS file flags built-ins 10 | 11 | flag { attr } 12 | flags { attr } 13 | attrs { attr } 14 | attribute { attr } 15 | attributes { attr } 16 | project { 0 } 17 | generation { 0 } 18 | 19 | // Flag constants from 20 | 21 | # Super-user and owner changeable flags 22 | 23 | UF_SETTABLE { 0x0000ffff } # mask of owner changeable flags 24 | UF_NODUMP { 0x00000001 } # do not dump file 25 | UF_IMMUTABLE { 0x00000002 } # file may not be changed 26 | UF_APPEND { 0x00000004 } # writes to file may only append 27 | UF_OPAQUE { 0x00000008 } # directory is opaque wrt. union 28 | 29 | UF_COMPRESSED { 0x00000020 } # file is compressed (some file-systems) 30 | UF_TRACKED { 0x00000040 } # notifications no longer issued 31 | UF_DATAVAULT { 0x00000080 } # entitlement required for reading and writing 32 | UF_HIDDEN { 0x00008000 } # hint that this item should not be displayed in a GUI 33 | 34 | # Super-user changeable flags 35 | 36 | SF_SUPPORTED { 0x009f0000 } # mask of superuser supported flags 37 | SF_SETTABLE { 0x3fff0000 } # mask of superuser changeable flags 38 | SF_SYNTHETIC { 0xc0000000 } # mask of system read-only synthetic flags */ 39 | SF_ARCHIVED { 0x00010000 } # file is archived 40 | SF_IMMUTABLE { 0x00020000 } # file may not be changed 41 | SF_APPEND { 0x00040000 } # writes to file may only append 42 | SF_RESTRICTED { 0x00080000 } # entitlement required for writing */ 43 | SF_NOUNLINK { 0x00100000 } # Item may not be removed, renamed or mounted on */ 44 | SF_FIRMLINK { 0x00800000 } # file is a firmlink 45 | SF_DATALESS { 0x40000000 } # file is dataless object 46 | 47 | // Flag predicates (canonical, aliases) 48 | 49 | arch { attr & SF_ARCHIVED } 50 | archived { attr & SF_ARCHIVED } 51 | nodump { attr & UF_NODUMP } 52 | opaque { attr & UF_OPAQUE } 53 | compressed { attr & UF_COMPRESSED } 54 | tracked { attr & UF_TRACKED } 55 | datavault { attr & UF_DATAVAULT } 56 | hidden { attr & UF_HIDDEN } 57 | sappnd { attr & SF_APPEND } 58 | sappend { attr & SF_APPEND } 59 | schg { attr & UF_IMMUTABLE } 60 | schange { attr & UF_IMMUTABLE } 61 | simmutable { attr & UF_IMMUTABLE } 62 | uappnd { attr & UF_APPEND } 63 | uappend { attr & UF_APPEND } 64 | uchg { attr & SF_IMMUTABLE } 65 | uchange { attr & SF_IMMUTABLE } 66 | uimmutable { attr & SF_IMMUTABLE } 67 | restricted { attr & SF_RESTRICTED } 68 | nounlink { attr & SF_NOUNLINK } 69 | unlink { attr & SF_NOUNLINK } 70 | firmlink { attr & SF_FIRMLINK } 71 | dataless { attr & SF_DATALESS } 72 | 73 | append { uappend | sappend } 74 | immutable { uimmutable | simmutable } 75 | 76 | -------------------------------------------------------------------------------- /attributes.netbsd: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf.d/attributes (NetBSD) 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | /* 5 | This file defines aliases for the built-in symbols for NetBSD file 6 | flags, and the related constants and predicates. See . 7 | */ 8 | 9 | // Aliases for the NetBSD file flags built-ins 10 | 11 | flag { attr } 12 | flags { attr } 13 | attrs { attr } 14 | attribute { attr } 15 | attributes { attr } 16 | project { 0 } 17 | generation { 0 } 18 | 19 | // Flag constants from 20 | 21 | # Super-user and owner changeable flags 22 | 23 | UF_SETTABLE { 0x0000ffff } # mask of owner changeable flags 24 | UF_NODUMP { 0x00000001 } # do not dump file 25 | UF_IMMUTABLE { 0x00000002 } # file may not be changed 26 | UF_APPEND { 0x00000004 } # writes to file may only append 27 | UF_OPAQUE { 0x00000008 } # directory is opaque wrt. union 28 | 29 | # Super-user changeable flags 30 | 31 | SF_SETTABLE { 0xffff0000 } # mask of superuser changeable flags 32 | SF_ARCHIVED { 0x00010000 } # file is archived 33 | SF_IMMUTABLE { 0x00020000 } # file may not be changed 34 | SF_APPEND { 0x00040000 } # writes to file may only append 35 | SF_SNAPSHOT { 0x00200000 } # snapshot inode 36 | SF_LOG { 0x00400000 } # WAPBL log file inode 37 | SF_SNAPINVAL { 0x00800000 } # snapshot is invalid 38 | 39 | // Flag predicates (canonical, aliases) 40 | 41 | arch { attr & SF_ARCHIVED } 42 | archived { attr & SF_ARCHIVED } 43 | nodump { attr & UF_NODUMP } 44 | opaque { attr & UF_OPAQUE } 45 | sappnd { attr & SF_APPEND } 46 | sappend { attr & SF_APPEND } 47 | schg { attr & UF_IMMUTABLE } 48 | schange { attr & UF_IMMUTABLE } 49 | simmutable { attr & UF_IMMUTABLE } 50 | snapshot { attr & SF_SNAPSHOT } 51 | uappnd { attr & UF_APPEND } 52 | uappend { attr & UF_APPEND } 53 | uchg { attr & SF_IMMUTABLE } 54 | uchange { attr & SF_IMMUTABLE } 55 | uimmutable { attr & SF_IMMUTABLE } 56 | wapbl { attr & SF_LOG } 57 | snapinval { attr & SF_SNAPINVAL } 58 | 59 | append { uappend | sappend } 60 | immutable { uimmutable | simmutable } 61 | 62 | -------------------------------------------------------------------------------- /attributes.openbsd: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf.d/attributes (OpenBSD) 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | /* 5 | This file defines aliases for the built-in symbols for OpenBSD file 6 | flags, and the related constants and predicates. See . 7 | */ 8 | 9 | // Aliases for the OpenBSD file flags built-ins 10 | 11 | flag { attr } 12 | flags { attr } 13 | attrs { attr } 14 | attribute { attr } 15 | attributes { attr } 16 | project { 0 } 17 | generation { 0 } 18 | 19 | // Flag constants from 20 | 21 | # Super-user and owner changeable flags 22 | 23 | UF_SETTABLE { 0x0000ffff } # mask of owner changeable flags 24 | UF_NODUMP { 0x00000001 } # do not dump file 25 | UF_IMMUTABLE { 0x00000002 } # file may not be changed 26 | UF_APPEND { 0x00000004 } # writes to file may only append 27 | UF_OPAQUE { 0x00000008 } # directory is opaque wrt. union 28 | 29 | # Super-user changeable flags 30 | 31 | SF_SETTABLE { 0xffff0000 } # mask of superuser changeable flags 32 | SF_ARCHIVED { 0x00010000 } # file is archived 33 | SF_IMMUTABLE { 0x00020000 } # file may not be changed 34 | SF_APPEND { 0x00040000 } # writes to file may only append 35 | 36 | // Flag predicates (canonical, aliases) 37 | 38 | arch { attr & SF_ARCHIVED } 39 | archived { attr & SF_ARCHIVED } 40 | nodump { attr & UF_NODUMP } 41 | opaque { attr & UF_OPAQUE } 42 | sappnd { attr & SF_APPEND } 43 | sappend { attr & SF_APPEND } 44 | schg { attr & UF_IMMUTABLE } 45 | schange { attr & UF_IMMUTABLE } 46 | simmutable { attr & UF_IMMUTABLE } 47 | uappnd { attr & UF_APPEND } 48 | uappend { attr & UF_APPEND } 49 | uchg { attr & SF_IMMUTABLE } 50 | uchange { attr & SF_IMMUTABLE } 51 | uimmutable { attr & SF_IMMUTABLE } 52 | 53 | append { uappend | sappend } 54 | immutable { uimmutable | simmutable } 55 | 56 | -------------------------------------------------------------------------------- /attributes.reserve: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf.d/attributes (Linux without libe2p) 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | /* 5 | This file defines some empty functions just to reserve identifiers for 6 | the potential built-in symbols for Linux ext2-style file attributes 7 | on Linux systems that don't have libe2p installed (but might later). 8 | Don't modify this file. It might be replaced. 9 | */ 10 | 11 | // Place-holders for the Linux ext2-style attribute built-ins 12 | 13 | flag { 0 } 14 | flags { 0 } 15 | attr { 0 } 16 | proj { 0 } 17 | gen { 0 } 18 | 19 | // Aliases for the Linux ext2-style attribute built-ins 20 | 21 | attrs { 0 } 22 | attribute { 0 } 23 | attributes { 0 } 24 | project { 0 } 25 | generation { 0 } 26 | 27 | // Attribute constants from 28 | 29 | ATTR_SECRM { 0 } 30 | ATTR_UNRM { 0 } 31 | ATTR_COMPR { 0 } 32 | ATTR_SYNC { 0 } 33 | ATTR_IMMUTABLE { 0 } 34 | ATTR_APPEND { 0 } 35 | ATTR_NODUMP { 0 } 36 | ATTR_NOATIME { 0 } 37 | ATTR_DIRTY { 0 } 38 | ATTR_COMPRBLK { 0 } 39 | ATTR_NOCOMPR { 0 } 40 | ATTR_ENCRYPT { 0 } 41 | ATTR_BTREE { 0 } 42 | ATTR_INDEX { 0 } 43 | ATTR_IMAGIC { 0 } 44 | ATTR_JOURNAL_DATA { 0 } 45 | ATTR_NOTAIL { 0 } 46 | ATTR_DIRSYNC { 0 } 47 | ATTR_TOPDIR { 0 } 48 | ATTR_HUGE_FILE { 0 } 49 | ATTR_EXTENTS { 0 } 50 | ATTR_VERITY { 0 } 51 | ATTR_EA_INODE { 0 } 52 | ATTR_NOCOW { 0 } 53 | ATTR_SNAPFILE { 0 } 54 | ATTR_DAX { 0 } 55 | ATTR_SNAPFILE_DELETED { 0 } 56 | ATTR_SNAPFILE_SHRUNK { 0 } 57 | ATTR_INLINE_DATA { 0 } 58 | ATTR_PROJINHERIT { 0 } 59 | ATTR_CASEFOLD { 0 } 60 | 61 | // Attribute predicates (canonical, aliases) 62 | 63 | secrm { 0 } 64 | unrm { 0 } 65 | compr { 0 } 66 | sync { 0 } 67 | immutable { 0 } 68 | append { 0 } 69 | nodump { 0 } 70 | noatime { 0 } 71 | dirty { 0 } 72 | comprblk { 0 } 73 | nocompr { 0 } 74 | encrypt { 0 } 75 | btree { 0 } 76 | index { 0 } 77 | imagic { 0 } 78 | journal_data { 0 } 79 | notail { 0 } 80 | dirsync { 0 } 81 | topdir { 0 } 82 | huge_file { 0 } 83 | extents { 0 } 84 | verity { 0 } 85 | ea_inode { 0 } 86 | nocow { 0 } 87 | snapfile { 0 } 88 | dax { 0 } 89 | snapfile_deleted { 0 } 90 | snapfile_shrunk { 0 } 91 | inline_data { 0 } 92 | projinherit { 0 } 93 | casefold { 0 } 94 | 95 | secure_deletion { 0 } 96 | undelete { 0 } 97 | compressed { 0 } 98 | synchronous { 0 } 99 | append_only { 0 } 100 | nocompression { 0 } 101 | encrypted { 0 } 102 | indexed { 0 } 103 | direct_access { 0 } 104 | inherit_project { 0 } 105 | 106 | attr_s { 0 } 107 | attr_u { 0 } 108 | attr_c { 0 } 109 | attr_S { 0 } 110 | attr_i { 0 } 111 | attr_a { 0 } 112 | attr_d { 0 } 113 | attr_A { 0 } 114 | attr_m { 0 } 115 | attr_E { 0 } 116 | attr_I { 0 } 117 | attr_j { 0 } 118 | attr_t { 0 } 119 | attr_D { 0 } 120 | attr_T { 0 } 121 | attr_e { 0 } 122 | attr_V { 0 } 123 | attr_C { 0 } 124 | attr_x { 0 } 125 | attr_N { 0 } 126 | attr_P { 0 } 127 | attr_F { 0 } 128 | 129 | -------------------------------------------------------------------------------- /gcov_summary: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use warnings; 3 | use strict; 4 | 5 | # rawhide - find files using pretty C expressions 6 | # https://raf.org/rawhide 7 | # https://github.com/raforg/rawhide 8 | # https://codeberg.org/raforg/rawhide 9 | # 10 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 11 | # 12 | # This program is free software; you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation; either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # This program is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with this program; if not, see . 24 | # 25 | # 20231013 raf 26 | 27 | # gcov_summary - Summarise the contents of *.c.gcov (first run gcov *.c) 28 | 29 | my $lines; 30 | my $covered; 31 | my $total_lines = 0; 32 | my $total_covered = 0; 33 | 34 | for my $fname(<*.c.gcov>) 35 | { 36 | $lines = 0; 37 | $covered = 0; 38 | 39 | open my $fh, '<', $fname or die "$0: failed to open $fname for reading: $!\n"; 40 | 41 | while (<$fh>) 42 | { 43 | next if /^\s+-:/; 44 | ++$lines; 45 | ++$covered if /^\s*\d+\*?:/; 46 | ++$total_lines; 47 | ++$total_covered if /^\s*\d+\*?:/; 48 | } 49 | 50 | close $fh; 51 | 52 | printf "%-10s %4d lines, %4d covered, %-3.2f%%\n", 53 | substr($fname, 0, -5), $lines, $covered, ($covered / $lines) * 100.0 54 | if $lines; 55 | } 56 | 57 | printf "%-10s %4d lines, %4d covered, %-3.2f%%\n", 58 | 'Total', $total_lines, $total_covered, ($total_covered / $total_lines) * 100.0 59 | if $lines; 60 | 61 | # vi:set ts=4 sw=4: 62 | -------------------------------------------------------------------------------- /md2html: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | # md2html - Convert a markdown file into a complete HTML document file 26 | 27 | fatal() { echo "$@" >&2; exit 1; } 28 | 29 | [ -z "$1" ] && fatal "usage: $0 infile.md [outfile.html [title]]" 30 | 31 | src="$1" 32 | base="${1%.*}" 33 | dst="${2:-$base.html}" 34 | title="${3:-$base}" 35 | 36 | html="`python3 -m markdown --encoding=utf-8 --output_format=html5 \"$src\"`" 37 | [ $? != 0 -o -z "$html" ] && fatal "$0: Failed to run: python3 -m markdown" 38 | 39 | echo "\n\n$title\n\n$html\n\n" > "$dst" 40 | -------------------------------------------------------------------------------- /rawhide.conf: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf: rh system-wide configuration. 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | 5 | /* 6 | This file constitutes the rawhide standard library. 7 | 8 | On some systems, this file could be somewhere other than /etc 9 | (e.g., /usr/local/etc, /opt/local/etc, /usr/pkg/etc). 10 | 11 | You can modify this file, and/or place additional files 12 | in the /etc/rawhide.conf.d directory. 13 | They'll be read after this file, in lexicographic order. 14 | Any files whose names start with dot are skipped. 15 | 16 | You can also create your own user-specific rawhide 17 | functions in ~/.rhrc and ~/.rhrc.d/*. They'll be read 18 | by rh in the same manner after these system-wide files. 19 | */ 20 | 21 | 22 | 23 | // File types (canonical, aliases) 24 | 25 | type { mode & IFMT } 26 | 27 | reg { type == IFREG } 28 | dir { type == IFDIR } 29 | blk { type == IFBLK } 30 | chr { type == IFCHR } 31 | lnk { type == IFLNK } 32 | sock { type == IFSOCK } 33 | fifo { type == IFIFO } 34 | door { type == IFDOOR } # Solaris 35 | 36 | file { reg } 37 | directory { dir } 38 | block { blk } 39 | char { chr } 40 | device { blk || chr } 41 | symlink { lnk } 42 | link { lnk } 43 | socket { sock } 44 | namedpipe { fifo } 45 | pipe { fifo } 46 | 47 | f { reg } 48 | d { dir } 49 | b { blk } 50 | c { chr } 51 | l { lnk } 52 | s { sock } 53 | p { fifo } 54 | D { door } # Solaris 55 | 56 | 57 | // File permissions (canonical, aliases, helpers) 58 | 59 | perm { mode & ~IFMT } 60 | 61 | ur { perm & IRUSR } 62 | uw { perm & IWUSR } 63 | ux { perm & IXUSR } 64 | gr { perm & IRGRP } 65 | gw { perm & IWGRP } 66 | gx { perm & IXGRP } 67 | or { perm & IROTH } 68 | ow { perm & IWOTH } 69 | ox { perm & IXOTH } 70 | wr { perm & IROTH } 71 | ww { perm & IWOTH } 72 | wx { perm & IXOTH } 73 | 74 | user_readable { ur } 75 | user_writable { uw } 76 | user_executable { ux } 77 | group_readable { gr } 78 | group_writable { gw } 79 | group_executable { gx } 80 | other_readable { or } 81 | other_writable { ow } 82 | other_executable { ox } 83 | world_readable { wr } 84 | world_writable { ww } 85 | world_executable { wx } 86 | 87 | 88 | suid { perm & ISUID } 89 | sgid { perm & ISGID } 90 | svtx { perm & ISVTX } 91 | 92 | setuid { suid } 93 | setgid { sgid } 94 | sticky { svtx } 95 | 96 | 97 | all(bitmask) { (perm & bitmask) == bitmask } 98 | any(bitmask) { perm & bitmask } 99 | none(bitmask) { !any(bitmask) } 100 | 101 | allr { all(IRUSR | IRGRP | IROTH) } 102 | allw { all(IWUSR | IWGRP | IWOTH) } 103 | allx { all(IXUSR | IXGRP | IXOTH) } 104 | anyr { any(IRUSR | IRGRP | IROTH) } 105 | anyw { any(IWUSR | IWGRP | IWOTH) } 106 | anyx { any(IXUSR | IXGRP | IXOTH) } 107 | noner { !anyr } 108 | nonew { !anyw } 109 | nonex { !anyx } 110 | 111 | all_readable { allr } 112 | all_writable { allw } 113 | all_executable { allx } 114 | any_readable { anyr } 115 | any_writable { anyw } 116 | any_executable { anyx } 117 | none_readable { noner } 118 | none_writable { nonew } 119 | none_executable { nonex } 120 | 121 | 122 | // Aliases for built-ins 123 | 124 | inode { ino } 125 | nlinks { nlink } 126 | user { uid } 127 | group { gid } 128 | space { blocks * 512 } 129 | accessed { atime } 130 | modified { mtime } # Refers to the contents 131 | changed { ctime } # Refers to the inode 132 | len { strlen } 133 | sz { size } 134 | 135 | seconds { second } 136 | minutes { minute } 137 | hours { hour } 138 | days { day } 139 | weeks { week } 140 | months { month } 141 | years { year } 142 | quit { exit } 143 | 144 | imayread { readable } # Uses access(2) not perm 145 | imaywrite { writable } # Uses access(2) not perm 146 | imayexec { executable } # Uses access(2) not perm 147 | 148 | ir { readable } 149 | iw { writable } 150 | ix { executable } 151 | 152 | 153 | // File types for symlink targets (canonical, aliases) 154 | 155 | ttype { tmode & IFMT } 156 | 157 | treg { ttype == IFREG } 158 | tdir { ttype == IFDIR } 159 | tblk { ttype == IFBLK } 160 | tchr { ttype == IFCHR } 161 | tsock { ttype == IFSOCK } 162 | tfifo { ttype == IFIFO } 163 | tdoor { ttype == IFDOOR } # Solaris 164 | 165 | tfile { treg } 166 | tdirectory { tdir } 167 | tblock { tblk } 168 | tchar { tchr } 169 | tdevice { tblk || tchr } 170 | tsocket { tsock } 171 | tnamedpipe { tfifo } 172 | tpipe { tfifo } 173 | 174 | tf { treg } 175 | td { tdir } 176 | tb { tblk } 177 | tc { tchr } 178 | ts { tsock } 179 | tp { tfifo } 180 | tD { tdoor } # Solaris 181 | 182 | target_type { ttype } 183 | 184 | target_reg { treg } 185 | target_dir { tdir } 186 | target_blk { tblk } 187 | target_chr { tchr } 188 | target_sock { tsock } 189 | target_fifo { tfifo } 190 | target_door { tdoor } # Solaris 191 | 192 | target_file { treg } 193 | target_directory { tdir } 194 | target_block { tblk } 195 | target_char { tchr } 196 | target_device { tblk || tchr } 197 | target_socket { tsock } 198 | target_namedpipe { tfifo } 199 | target_pipe { tfifo } 200 | 201 | target_f { treg } 202 | target_d { tdir } 203 | target_b { tblk } 204 | target_c { tchr } 205 | target_s { tsock } 206 | target_p { tfifo } 207 | target_D { tdoor } 208 | 209 | 210 | // File permissions for symlink targets (canonical, aliases, helpers) 211 | 212 | tperm { tmode & ~IFMT } 213 | 214 | tur { tperm & IRUSR } 215 | tuw { tperm & IWUSR } 216 | tux { tperm & IXUSR } 217 | tgr { tperm & IRGRP } 218 | tgw { tperm & IWGRP } 219 | tgx { tperm & IXGRP } 220 | tor { tperm & IROTH } 221 | tow { tperm & IWOTH } 222 | tox { tperm & IXOTH } 223 | twr { tperm & IROTH } 224 | tww { tperm & IWOTH } 225 | twx { tperm & IXOTH } 226 | 227 | target_perm { tperm } 228 | 229 | target_ur { tur } 230 | target_uw { tuw } 231 | target_ux { tux } 232 | target_gr { tgr } 233 | target_gw { tgw } 234 | target_gx { tgx } 235 | target_or { tor } 236 | target_ow { tow } 237 | target_ox { tox } 238 | target_wr { twr } 239 | target_ww { tww } 240 | target_wx { twx } 241 | 242 | target_user_readable { tur } 243 | target_user_writable { tuw } 244 | target_user_executable { tux } 245 | target_group_readable { tgr } 246 | target_group_writable { tgw } 247 | target_group_executable { tgx } 248 | target_other_readable { tor } 249 | target_other_writable { tow } 250 | target_other_executable { tox } 251 | target_world_readable { twr } 252 | target_world_writable { tww } 253 | target_world_executable { twx } 254 | 255 | 256 | tsuid { tperm & ISUID } 257 | tsgid { tperm & ISGID } 258 | tsvtx { tperm & ISVTX } 259 | 260 | tsetuid { tsuid } 261 | tsetgid { tsgid } 262 | tsticky { tsvtx } 263 | 264 | target_suid { tsuid } 265 | target_sgid { tsgid } 266 | target_svtx { tsvtx } 267 | 268 | target_setuid { tsuid } 269 | target_setgid { tsgid } 270 | target_sticky { tsvtx } 271 | 272 | 273 | tall(bitmask) { (tperm & bitmask) == bitmask } 274 | tany(bitmask) { tperm & bitmask } 275 | tnone(bitmask) { !tany(bitmask) } 276 | 277 | tallr { tall(IRUSR | IRGRP | IROTH) } 278 | tallw { tall(IWUSR | IWGRP | IWOTH) } 279 | tallx { tall(IXUSR | IXGRP | IXOTH) } 280 | tanyr { tany(IRUSR | IRGRP | IROTH) } 281 | tanyw { tany(IWUSR | IWGRP | IWOTH) } 282 | tanyx { tany(IXUSR | IXGRP | IXOTH) } 283 | tnoner { !tanyr } 284 | tnonew { !tanyw } 285 | tnonex { !tanyx } 286 | 287 | target_all(bitmask) { tall(bitmask) } 288 | target_any(bitmask) { tany(bitmask) } 289 | target_none(bitmask) { tnone(bitmask) } 290 | 291 | target_allr { tallr } 292 | target_allw { tallw } 293 | target_allx { tallx } 294 | target_anyr { tanyr } 295 | target_anyw { tanyw } 296 | target_anyx { tanyx } 297 | target_noner { tnoner } 298 | target_nonew { tnonew } 299 | target_nonex { tnonex } 300 | 301 | target_all_readable { tallr } 302 | target_all_writable { tallw } 303 | target_all_executable { tallx } 304 | target_any_readable { tanyr } 305 | target_any_writable { tanyw } 306 | target_any_executable { tanyx } 307 | target_none_readable { tnoner } 308 | target_none_writable { tnonew } 309 | target_none_executable { tnonex } 310 | 311 | 312 | // Aliases for symlink target built-ins 313 | 314 | target_exists { texists } 315 | target_dev { tdev } 316 | target_ino { tino } 317 | target_mode { tmode } 318 | target_nlink { tnlink } 319 | target_uid { tuid } 320 | target_gid { tgid } 321 | target_rdev { trdev } 322 | target_size { tsize } 323 | target_blksize { tblksize } 324 | target_blocks { tblocks } 325 | target_atime { tatime } 326 | target_mtime { tmtime } 327 | target_ctime { tctime } 328 | target_strlen { tstrlen } 329 | 330 | tinode { tino } 331 | tnlinks { tnlink } 332 | tuser { tuid } 333 | tgroup { tgid } 334 | tspace { tblocks * 512 } 335 | taccessed { tatime } 336 | tmodified { tmtime } # Refers to the target's contents 337 | tchanged { tctime } # Refers to the target's inode 338 | tlen { tstrlen } 339 | tsz { tsize } 340 | 341 | target_inode { tinode } 342 | target_nlinks { tnlinks } 343 | target_user { tuser } 344 | target_group { tgroup } 345 | target_space { tspace } 346 | target_accessed { taccessed } 347 | target_modified { tmodified } 348 | target_changed { tchanged } 349 | target_len { tlen } 350 | target_sz { tsz } 351 | 352 | 353 | // Aliases for size units 354 | 355 | KiB { 1K } 356 | MiB { 1M } 357 | GiB { 1G } 358 | TiB { 1T } 359 | PiB { 1P } 360 | EiB { 1E } 361 | 362 | KB { 1k } 363 | MB { 1m } 364 | GB { 1g } 365 | TB { 1t } 366 | PB { 1p } 367 | EB { 1e } 368 | 369 | 370 | // Miscellaneous helper functions 371 | 372 | empty { size == 0 } # Only for files and readable directories 373 | roots { uid == 0 } 374 | mine { uid == $$ } 375 | ours { gid == @@ } 376 | broken { symlink && !texists } 377 | dangling { broken } 378 | gmtoday { now - now % day } 379 | 380 | ago(sec) { now - sec } 381 | old(sec) { mtime <= ago(sec) } 382 | past(sec) { mtime >= ago(sec) } 383 | future { mtime > now } 384 | 385 | min(x, y) { (x < y) ? x : y } 386 | max(x, y) { (x > y) ? x : y } 387 | abs(x) { (x < 0) ? -x : x } 388 | 389 | 390 | // Examples 391 | 392 | // Complex tests can be very readable (and/or very concise) 393 | // rootshell { setuid && roots && (group_writable | other_writable) } 394 | // rootshell { suid && roots && (gw | ow) } 395 | // csrc { "*.[ch]" || "[Mm]akefile" } 396 | // oldaout { "a.out" && f && old(week) } 397 | // oldcore { "^core(\.\d+)?$".re && f && old(week) } 398 | // bad { oldaout || oldcore || "*.BAK" || "*.CKP" || (gw | ow) } 399 | // Note: Read "<" and ">" as before/after, not as less/more than 400 | // recent { modified >= ago(hour) } 401 | 402 | // Silly recursive functions are possible (but not mutual recursion) 403 | // sqrt1(n, odd) { (n <= 0) ? 0 : sqrt1(n - odd, odd + 2) + 1 } 404 | // sqrt(n) { sqrt1(n, 1) } 405 | // prime1(n, i) { (i * i > n) ? 1 : !(n % i) ? 0 : prime1(n, i + 2) } 406 | // prime(n) { (n < 2) ? 0 : !(n % 2) ? n == 2 : prime1(n, 3) } 407 | // factorial(x) { (x > 0) ? x * factorial(x - 1) : 1 } 408 | // ack(x, y) { !x ? y+1 : !y ? ack(x-1, 1) : ack(x-1, ack(x, y-1)) } 409 | 410 | 411 | -------------------------------------------------------------------------------- /rawhide.spec: -------------------------------------------------------------------------------- 1 | %define dist alt 2 | 3 | Name: rawhide 4 | Version: 3.3 5 | Release: %{?dist}1 6 | Summary: find files using pretty C expressions 7 | License: GPL-3.0-or-later 8 | URL: https://raf.org/rawhide 9 | Group: File tools 10 | Source: https://github.com/raforg/rawhide/releases/download/v%{version}/%{name}-%{version}.tar.gz 11 | BuildRequires: gcc 12 | BuildRequires: make 13 | BuildRequires: libe2fs-devel 14 | BuildRequires: libpcre2-devel 15 | BuildRequires: libacl-devel 16 | BuildRequires: libmagic-devel 17 | BuildRequires: libattr-devel 18 | Requires: libe2fs >= 1.46 19 | Requires: libpcre2 >= 10.43 20 | Requires: libacl >= 2.3 21 | Requires: libmagic >= 5.45 22 | Requires: libattr >= 2.5 23 | 24 | %description 25 | Rawhide (rh) lets you search for files on the command line using expressions and user-defined functions in a mini-language inspired by C. It's like find(1), but more fun to use. 26 | 27 | %prep 28 | %setup -q 29 | %autopatch -p1 30 | 31 | %build 32 | ./configure 33 | make %{?_smp_mflags} 34 | 35 | %install 36 | rm -rf $RPM_BUILD_ROOT 37 | %make_install DESTDIR=%buildroot PREFIX=%_prefix MANDIR=%_mandir INFODIR=%_infodir install 38 | 39 | %files 40 | %doc README.md COPYING CHANGELOG LICENSE 41 | %{_bindir}/rh 42 | %{_mandir}/man1/rh.1* 43 | %{_mandir}/man5/rawhide.conf.5* 44 | %config(noreplace) %_sysconfdir/rawhide.conf 45 | %config(noreplace) %_sysconfdir/rawhide.conf.d/attributes 46 | 47 | %changelog 48 | -------------------------------------------------------------------------------- /rhcmds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #ifndef RAWHIDE_RHCMDS_H 26 | #define RAWHIDE_RHCMDS_H 27 | 28 | void c_le(llong i); 29 | void c_lt(llong i); 30 | void c_ge(llong i); 31 | void c_gt(llong i); 32 | void c_ne(llong i); 33 | void c_eq(llong i); 34 | void c_bitor(llong i); 35 | void c_bitand(llong i); 36 | void c_bitxor(llong i); 37 | void c_lshift(llong i); 38 | void c_rshift(llong i); 39 | void c_plus(llong i); 40 | void c_mul(llong i); 41 | void c_minus(llong i); 42 | void c_div(llong i); 43 | void c_mod(llong i); 44 | void c_not(llong i); 45 | void c_bitnot(llong i); 46 | void c_uniminus(llong i); 47 | void c_qm(llong i); 48 | void c_colon(llong i); 49 | void c_param(llong i); 50 | void c_func(llong i); 51 | void c_return(llong i); 52 | void c_number(llong i); 53 | void c_dev(llong i); 54 | void c_major(llong i); 55 | void c_minor(llong i); 56 | void c_ino(llong i); 57 | void c_mode(llong i); 58 | void c_nlink(llong i); 59 | void c_uid(llong i); 60 | void c_gid(llong i); 61 | void c_rdev(llong i); 62 | void c_rmajor(llong i); 63 | void c_rminor(llong i); 64 | void c_size(llong i); 65 | void c_blksize(llong i); 66 | void c_blocks(llong i); 67 | void c_atime(llong i); 68 | void c_mtime(llong i); 69 | void c_ctime(llong i); 70 | unsigned long get_attr(void); 71 | unsigned long get_proj(void); 72 | unsigned long get_gen(void); 73 | #if HAVE_ATTR || HAVE_FLAGS 74 | void c_attr(llong i); 75 | #endif 76 | #if HAVE_ATTR 77 | void c_proj(llong i); 78 | void c_gen(llong i); 79 | #endif 80 | void c_depth(llong i); 81 | void c_prune(llong i); 82 | void c_trim(llong i); 83 | void c_exit(llong i); 84 | void c_strlen(llong i); 85 | void c_nouser(llong i); 86 | void c_nogroup(llong i); 87 | void c_readable(llong i); 88 | void c_writable(llong i); 89 | void c_executable(llong i); 90 | void c_glob(llong i); 91 | void c_path(llong i); 92 | void c_link(llong i); 93 | #ifdef FNM_CASEFOLD 94 | void c_i(llong i); 95 | void c_ipath(llong i); 96 | void c_ilink(llong i); 97 | #endif 98 | #ifdef HAVE_PCRE2 99 | void pcre2_cache_free(void); 100 | void c_re(llong i); 101 | void c_repath(llong i); 102 | void c_relink(llong i); 103 | void c_rei(llong i); 104 | void c_reipath(llong i); 105 | void c_reilink(llong i); 106 | #endif 107 | #ifdef HAVE_MAGIC 108 | void c_what(llong i); 109 | #ifdef FNM_CASEFOLD 110 | void c_iwhat(llong i); 111 | #endif 112 | #ifdef HAVE_PCRE2 113 | void c_rewhat(llong i); 114 | void c_reiwhat(llong i); 115 | #endif 116 | #endif 117 | #ifdef HAVE_MAGIC 118 | void c_mime(llong i); 119 | #ifdef FNM_CASEFOLD 120 | void c_imime(llong i); 121 | #endif 122 | #ifdef HAVE_PCRE2 123 | void c_remime(llong i); 124 | void c_reimime(llong i); 125 | #endif 126 | #endif 127 | void c_body(llong i); 128 | #ifdef FNM_CASEFOLD 129 | void c_ibody(llong i); 130 | #endif 131 | #ifdef HAVE_PCRE2 132 | void c_rebody(llong i); 133 | void c_reibody(llong i); 134 | #endif 135 | #ifdef HAVE_ACL 136 | void c_acl(llong i); 137 | #ifdef FNM_CASEFOLD 138 | void c_iacl(llong i); 139 | #endif 140 | #ifdef HAVE_PCRE2 141 | void c_reacl(llong i); 142 | void c_reiacl(llong i); 143 | #endif 144 | #endif 145 | #ifdef HAVE_EA 146 | void c_ea(llong i); 147 | #ifdef FNM_CASEFOLD 148 | void c_iea(llong i); 149 | #endif 150 | #ifdef HAVE_PCRE2 151 | void c_reea(llong i); 152 | void c_reiea(llong i); 153 | #endif 154 | #endif 155 | void c_sh(llong i); 156 | 157 | void r_exists(llong i); 158 | void r_dev(llong i); 159 | void r_major(llong i); 160 | void r_minor(llong i); 161 | void r_ino(llong i); 162 | void r_mode(llong i); 163 | void r_nlink(llong i); 164 | void r_uid(llong i); 165 | void r_gid(llong i); 166 | void r_rdev(llong i); 167 | void r_rmajor(llong i); 168 | void r_rminor(llong i); 169 | void r_size(llong i); 170 | void r_blksize(llong i); 171 | void r_blocks(llong i); 172 | void r_atime(llong i); 173 | void r_mtime(llong i); 174 | void r_ctime(llong i); 175 | #if HAVE_ATTR || HAVE_FLAGS 176 | void r_attr(llong i); 177 | #endif 178 | #if HAVE_ATTR 179 | void r_proj(llong i); 180 | void r_gen(llong i); 181 | #endif 182 | void r_strlen(llong i); 183 | void r_type(llong i); 184 | void r_perm(llong i); 185 | 186 | void t_exists(llong i); 187 | void t_dev(llong i); 188 | void t_major(llong i); 189 | void t_minor(llong i); 190 | void t_ino(llong i); 191 | void t_mode(llong i); 192 | void t_nlink(llong i); 193 | void t_uid(llong i); 194 | void t_gid(llong i); 195 | void t_rdev(llong i); 196 | void t_rmajor(llong i); 197 | void t_rminor(llong i); 198 | void t_size(llong i); 199 | void t_blksize(llong i); 200 | void t_blocks(llong i); 201 | void t_atime(llong i); 202 | void t_mtime(llong i); 203 | void t_ctime(llong i); 204 | void t_strlen(llong i); 205 | 206 | char *read_symlink(void); 207 | void prepare_target(void); 208 | const char *get_what(void); 209 | const char *get_mime(void); 210 | char *get_body(void); 211 | char *get_acl(int); 212 | char *get_ea(int); 213 | void set_dirsize(void); 214 | int has_real_acl(void); 215 | int has_real_ea(void); 216 | 217 | #ifndef NDEBUG 218 | char *instruction_name(void (*func)(llong)); 219 | #endif 220 | 221 | #endif 222 | -------------------------------------------------------------------------------- /rhdata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #ifndef RAWHIDE_RHDATA_H 26 | #define RAWHIDE_RHDATA_H 27 | 28 | void rawhide_init(void); 29 | void rawhide_finish(void); 30 | symbol_t *insert_symbol(char *name, int toktype, llong val); 31 | symbol_t *locate_symbol(char *name); 32 | symbol_t *locate_patmod_prefix(char *name); 33 | int rawhide_instruction(void (*func)(llong), llong value); 34 | llong rawhide_execute(void); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /rhdir.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #ifndef RAWHIDE_RHDIR_H 26 | #define RAWHIDE_RHDIR_H 27 | 28 | llong env_int(char *envname, llong min_value, llong max_value, llong default_value); 29 | int rawhide_search(char *fpath); 30 | int following_symlinks(void); 31 | const char *modestr(struct stat *statbuf); 32 | void visitf_default(void); 33 | void visitf_long(void); 34 | void visitf_execute(void); 35 | void visitf_execute_local(void); 36 | void visitf_unlink(void); 37 | void visitf_format(void); 38 | int syscmd(const char *cmd); 39 | int remove_danger_from_path(void); 40 | int interpolate_command(const char *srccmd, char *command, int cmdbufsize); 41 | int chdir_local(int do_debug); 42 | 43 | #define CMDBUFSIZE 8192 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /rherr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #define _FILE_OFFSET_BITS 64 /* For 64-bit off_t on 32-bit systems (Not AIX) */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "rh.h" 35 | 36 | /* 37 | 38 | int error(const char *format, ...); 39 | 40 | Outputs an error message to stderr (prefixed by the program name). 41 | The format parameter is a printf-like format string. 42 | Subsequent arguments must satisfy its conversions. 43 | Returns -1. 44 | 45 | */ 46 | 47 | int error(const char *format, ...) 48 | { 49 | va_list args; 50 | 51 | va_start(args, format); 52 | fprintf(stderr, "%s: ", prog_name); 53 | vfprintf(stderr, format, args); 54 | fprintf(stderr, "\n"); 55 | va_end(args); 56 | 57 | return -1; 58 | } 59 | 60 | /* 61 | 62 | int errorsys(const char *format, ...); 63 | 64 | Outputs an error message to stderr (prefixed by the program name), 65 | including a trailing errno string. 66 | The format parameter is a printf-like format string. 67 | Subsequent arguments must satisfy its conversions. 68 | Returns -1. 69 | 70 | */ 71 | 72 | int errorsys(const char *format, ...) 73 | { 74 | va_list args; 75 | 76 | va_start(args, format); 77 | fprintf(stderr, "%s: ", prog_name); 78 | vfprintf(stderr, format, args); 79 | fprintf(stderr, ": %s\n", strerror(errno)); 80 | va_end(args); 81 | 82 | return -1; 83 | } 84 | 85 | /* 86 | 87 | void fatal(const char *format, ...); 88 | 89 | Outputs an error message to stderr (prefixed by the program name), 90 | then exits with a non-zero failure exit status. 91 | The format parameter is a printf-like format string. 92 | Subsequent arguments must satisfy its conversions. 93 | 94 | */ 95 | 96 | void fatal(const char *format, ...) 97 | { 98 | va_list args; 99 | 100 | va_start(args, format); 101 | fprintf(stderr, "%s: ", prog_name); 102 | vfprintf(stderr, format, args); 103 | fprintf(stderr, "\n"); 104 | va_end(args); 105 | 106 | exit(EXIT_FAILURE); 107 | } 108 | 109 | /* 110 | 111 | void fatalsys(const char *format, ...); 112 | 113 | Outputs an error message to stderr (prefixed by the program name) 114 | including a trailing errno string, then exits with a non-zero 115 | failure exit status. The format parameter is a printf-like format string. 116 | Subsequent arguments must satisfy its conversions. 117 | 118 | */ 119 | 120 | void fatalsys(const char *format, ...) 121 | { 122 | va_list args; 123 | 124 | va_start(args, format); 125 | fprintf(stderr, "%s: ", prog_name); 126 | vfprintf(stderr, format, args); 127 | fprintf(stderr, ": %s\n", strerror(errno)); 128 | va_end(args); 129 | 130 | exit(EXIT_FAILURE); 131 | } 132 | 133 | /* vi:set ts=4 sw=4: */ 134 | -------------------------------------------------------------------------------- /rherr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #ifndef RAWHIDE_RHERR_H 26 | #define RAWHIDE_RHERR_H 27 | 28 | int error(const char *format, ...); 29 | int errorsys(const char *format, ...); 30 | void fatal(const char *format, ...); 31 | void fatalsys(const char *format, ...); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /rhparse.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #ifndef RAWHIDE_RHPARSE_H 26 | #define RAWHIDE_RHPARSE_H 27 | 28 | void parse_program(void); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /rhstr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | /* 26 | $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ 27 | $OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $ 28 | Copyright (c) 1998 Todd C. Miller 29 | 30 | All rights reserved. 31 | 32 | Redistribution and use in source and binary forms, with or without 33 | modification, are permitted provided that the following conditions 34 | are met: 35 | 1. Redistributions of source code must retain the above copyright 36 | notice, this list of conditions and the following disclaimer. 37 | 2. Redistributions in binary form must reproduce the above copyright 38 | notice, this list of conditions and the following disclaimer in the 39 | documentation and/or other materials provided with the distribution. 40 | 3. The name of the author may not be used to endorse or promote products 41 | derived from this software without specific prior written permission. 42 | 43 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 44 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 45 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 46 | THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 47 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 48 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 49 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 51 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 52 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 | */ 54 | 55 | #define _FILE_OFFSET_BITS 64 /* For 64-bit off_t on 32-bit systems (Not AIX) */ 56 | 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #include "rh.h" 63 | #include "rhstr.h" 64 | 65 | /* 66 | 67 | size_t strlcpy(char *dst, const char *src, size_t size); 68 | 69 | Copy src to dst (which is size bytes). The result will be no longer than 70 | size-1 bytes, and will be nul-terminated (unless size is zero). This is like 71 | strncpy, but it always terminates the string with a nul byte (so it's safer) 72 | and it doesn't fill the remainder of the buffer with nul bytes (so it's 73 | faster). Returns the length of src (If this is >= size, truncation 74 | occurred). Use this rather than strcpy or strncpy. 75 | 76 | */ 77 | 78 | #ifndef strlcpy /* macOS */ 79 | size_t strlcpy(char *dst, const char *src, size_t size) 80 | { 81 | const char *s = src; 82 | char *d = dst; 83 | size_t n = size; 84 | 85 | if (n) 86 | while (--n && (*d++ = *s++)) 87 | {} 88 | 89 | if (n == 0) 90 | { 91 | if (size) 92 | *d = '\0'; 93 | 94 | while (*s++) 95 | {} 96 | } 97 | 98 | return s - src - 1; 99 | } 100 | #endif 101 | 102 | /* 103 | 104 | size_t strlcat(char *dst, const char *src, size_t size); 105 | 106 | Appends src to dst (which is size bytes). The result will be no longer than 107 | size-1 bytes, and will be nul-terminated (unless size is zero). This is like 108 | strncat but the last argument is the size of the buffer not the amount of 109 | space available (so it's more intuitive and hence safer). Returns the sum of 110 | the lengths of src and dst (If this is >= size, truncation occurred). Use 111 | this rather than strcat or strncat. 112 | 113 | */ 114 | 115 | #ifndef strlcat /* macOS */ 116 | size_t strlcat(char *dst, const char *src, size_t size) 117 | { 118 | const char *s = src; 119 | char *d = dst; 120 | size_t n = size; 121 | size_t dlen = 0; 122 | 123 | while (n-- && *d) 124 | ++d; 125 | 126 | dlen = d - dst; 127 | 128 | if (++n == 0) 129 | { 130 | while (*s++) 131 | {} 132 | 133 | return dlen + s - src - 1; 134 | } 135 | 136 | for (; *s; ++s) 137 | if (n - 1) 138 | --n, *d++ = *s; 139 | 140 | *d = '\0'; 141 | 142 | return dlen + s - src; 143 | } 144 | #endif 145 | 146 | /* 147 | 148 | int ssnprintf(char *str, ssize_t size, const char *format, ...); 149 | 150 | A snprintf wrapper whose size parameter is signed so we can detect negative 151 | size remaining and not overwrite the buffer. When that happens, return zero. 152 | 153 | */ 154 | 155 | int ssnprintf(char *str, ssize_t size, const char *format, ...) 156 | { 157 | va_list args; 158 | int rc; 159 | 160 | if (size <= 0) 161 | return 0; 162 | 163 | va_start(args, format); 164 | rc = vsnprintf(str, (size_t)size, format, args); 165 | va_end(args); 166 | 167 | return rc; 168 | } 169 | 170 | /* 171 | 172 | int cescape(char *dst, ssize_t dstsz, const char *src, ssize_t srcsz, int opts); 173 | 174 | Copy src to dst using C escapes. At most dstsz bytes are written. 175 | If srcsz is -1, src is nul-terminated. Otherwise, the given number 176 | of bytes are processed. The opts bitmask can contain CESCAPE_QUOTES (to quote "), 177 | CESCAPE_HEX (to use hex not octal), CESCAPE_JSON (for \uxxxx ctrls and no \a\v), 178 | and CESCAPE_BIN (to hex all 8bit). 179 | 180 | */ 181 | 182 | int cescape(char *dst, ssize_t dstsz, const char *src, ssize_t srcsz, int opts) 183 | { 184 | static char *escape = "\013\007\010\011\012\014\015\\"; 185 | static char *escaped = "vabtnfr\\"; 186 | char *e; 187 | int i, pos = 0; 188 | int j = (opts & CESCAPE_JSON) == CESCAPE_JSON ? 2 : 0; 189 | 190 | for (i = 0; (srcsz == -1) ? src[i] : i < srcsz; ++i) 191 | { 192 | if (src[i] == '\0') 193 | pos += ssnprintf(dst + pos, dstsz - pos, "\\0"); 194 | else if ((e = strchr(escape + j, src[i]))) 195 | pos += ssnprintf(dst + pos, dstsz - pos, "\\%c", (escaped + j)[e - (escape + j)]); 196 | else if (isquotable(src[i])) 197 | pos += ssnprintf(dst + pos, dstsz - pos, (j) ? "\\u00%02x" : (opts & CESCAPE_HEX) ? "\\x%02x" : "\\%03o", (unsigned char)src[i]); 198 | else if ((opts & CESCAPE_QUOTES) && src[i] == '"') 199 | pos += ssnprintf(dst + pos, dstsz - pos, "\\\""); 200 | else if ((opts & CESCAPE_BIN) == CESCAPE_BIN && (src[i] & 0x80)) 201 | pos += ssnprintf(dst + pos, dstsz - pos, "\\x%02x", (unsigned char)src[i]); 202 | else 203 | pos += ssnprintf(dst + pos, dstsz - pos, "%c", (unsigned char)src[i]); 204 | } 205 | 206 | return pos; 207 | } 208 | 209 | /* Sanitise text for errors */ 210 | 211 | static const char *sanitise(char *buf, size_t sz, const char *str) 212 | { 213 | char *s; 214 | 215 | if (!attr.ttyerr) 216 | return str; 217 | 218 | for (s = buf; (s - buf) < (sz - 1) && *str; ++str) 219 | *s++ = isquotable(*str) ? '?' : *str; 220 | 221 | *s = '\0'; 222 | 223 | return buf; 224 | } 225 | 226 | const char *ok(const char *str) 227 | { 228 | static char buf[8192]; 229 | 230 | return sanitise(buf, 8192, str); 231 | } 232 | 233 | /* The same, to allow two uses in one statement */ 234 | 235 | const char *ok2(const char *str) 236 | { 237 | static char buf[8192]; 238 | 239 | return sanitise(buf, 8192, str); 240 | } 241 | 242 | /* The same, for when it's not nul-terminated */ 243 | 244 | const char *oklen(const char *str, size_t len) 245 | { 246 | static char buf[1024]; 247 | char *s; 248 | 249 | for (s = buf; len > 0; ++str, --len) 250 | *s++ = (attr.ttyerr && isquotable(*str)) ? '?' : *str; 251 | 252 | *s = '\0'; 253 | 254 | return buf; 255 | } 256 | 257 | /* vi:set ts=4 sw=4: */ 258 | -------------------------------------------------------------------------------- /rhstr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rawhide - find files using pretty C expressions 3 | * https://raf.org/rawhide 4 | * https://github.com/raforg/rawhide 5 | * https://codeberg.org/raforg/rawhide 6 | * 7 | * Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, see . 21 | * 22 | * 20231013 raf 23 | */ 24 | 25 | #ifndef RAWHIDE_RHSTR_H 26 | #define RAWHIDE_RHSTR_H 27 | 28 | #include /* For ssize_t on Debian6 */ 29 | #include 30 | #include 31 | 32 | #ifndef strlcpy /* For macOS */ 33 | size_t strlcpy(char *dst, const char *src, size_t size); 34 | #endif 35 | #ifndef strlcat /* For macOS */ 36 | size_t strlcat(char *dst, const char *src, size_t size); 37 | #endif 38 | 39 | int ssnprintf(char *str, ssize_t size, const char *format, ...); 40 | int cescape(char *dst, ssize_t dstsize, const char *src, ssize_t srcsize, int options); 41 | const char *ok(const char *s); 42 | const char *ok2(const char *s); 43 | const char *oklen(const char *s, size_t len); 44 | 45 | #define CESCAPE_QUOTES 1 46 | #define CESCAPE_HEX 2 47 | #define CESCAPE_JSON 5 48 | #define CESCAPE_BIN 10 49 | 50 | #define isquotable(c) iscntrl((int)(unsigned char)(c)) 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /runtests: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | # runtests - Run all of the rawhide tests 26 | 27 | suites=0 28 | errors=0 29 | list= 30 | 31 | for t in tests/t* 32 | do 33 | ./$t 34 | rc=$? 35 | if [ "$rc" != 0 ] 36 | then 37 | rc=1 38 | case "$list" in ?*) list="$list ${t#tests/}";; *) list="${t#tests/}";; esac 39 | fi 40 | suites="`expr $suites + 1`" 41 | errors="`expr $errors + $rc`" 42 | done 43 | 44 | if [ $suites -gt 0 -a $errors -eq 0 ] 45 | then 46 | echo All test suites passed 47 | else 48 | echo "$errors/$suites test suites failed ($list)" 49 | fi 50 | 51 | # vi:set ts=4 sw=4: 52 | -------------------------------------------------------------------------------- /samples/.rh.sh: -------------------------------------------------------------------------------- 1 | # rawhide - find files using pretty C expressions 2 | # https://raf.org/rawhide 3 | # https://github.com/raforg/rawhide 4 | # https://codeberg.org/raforg/rawhide 5 | # 6 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, see . 20 | # 21 | # 20231013 raf 22 | 23 | # .rh.sh - Some command line shell syntactic sugar to save keystrokes 24 | 25 | # rq - rh with automatic "" around the first argument 26 | # usage: rq pattern [options] [path...] 27 | # e.g.: rq '*.c' instead of rh '"*.c"' 28 | rq() { rq_pat="$1"; shift && rh -e "\"$rq_pat\"" "$@"; } 29 | 30 | # rql - rh -l with automatic "" around the first argument 31 | # usage: rql pattern [options] [path...] 32 | # e.g.: rql '*.c' instead of rh -l '"*.c"' 33 | rql() { rql_pat="$1"; shift && rh -le "\"$rql_pat\"" "$@"; } 34 | 35 | # rqv - rh -v with automatic "" around the first argument 36 | # usage: rqv pattern [options] [path...] 37 | # e.g.: rqv '*.c' instead of rh -v '"*.c"' 38 | rqv() { rqv_pat="$1"; shift && rh -ve "\"$rqv_pat\"" "$@"; } 39 | 40 | 41 | # ri - rh with automatic "".i around the first argument 42 | # usage: ri pattern [options] [path...] 43 | # e.g.: ri '*.c' instead of rh '"*.c".i' 44 | ri() { ri_pat="$1"; shift && rh -e "\"$ri_pat\".i" "$@"; } 45 | 46 | # ril - rh -l with automatic "".i around the first argument 47 | # usage: ril pattern [options] [path...] 48 | # e.g.: ril '*.c' instead of rh -l '"*.c".i' 49 | ril() { ril_pat="$1"; shift && rh -le "\"$ril_pat\".i" "$@"; } 50 | 51 | # riv - rh -v with automatic "".i around the first argument 52 | # usage: riv pattern [options] [path...] 53 | # e.g.: riv '*.c' instead of rh -v '"*.c".i' 54 | riv() { riv_pat="$1"; shift && rh -ve "\"$riv_pat\".i" "$@"; } 55 | 56 | 57 | # re - rh with automatic "".re around the first argument 58 | # usage: re pattern [options] [path...] 59 | # e.g.: re '\.c$' instead of rh '"\.c$".re' 60 | re() { re_pat="$1"; shift && rh -e "\"$re_pat\".re" "$@"; } 61 | 62 | # rel - rh -l with automatic "".re around the first argument 63 | # usage: rel pattern [options] [path...] 64 | # e.g.: rel '\.c$' instead of rh -l '"\.c$".re' 65 | rel() { rel_pat="$1"; shift && rh -le "\"$rel_pat\".re" "$@"; } 66 | 67 | # rev - rh -v with automatic "".re around the first argument 68 | # usage: rev pattern [options] [path...] 69 | # e.g.: rev '\.c$' instead of rh -v '"\.c$".re' 70 | rev() { rev_pat="$1"; shift && rh -ve "\"$rev_pat\".re" "$@"; } 71 | 72 | 73 | # rei - rh with automatic "".rei around the first argument 74 | # usage: rei pattern [options] [path...] 75 | # e.g.: rei '\.c$' instead of rh '"\.c$".rei' 76 | rei() { rei_pat="$1"; shift && rh -e "\"$rei_pat\".rei" "$@"; } 77 | 78 | # reil - rh -l with automatic "".rei around the first argument 79 | # usage: reil pattern [options] [path...] 80 | # e.g.: reil '\.c$' instead of rh -l '"\.c$".rei' 81 | reil() { reil_pat="$1"; shift && rh -le "\"$reil_pat\".rei" "$@"; } 82 | 83 | # reiv - rh -v with automatic "".rei around the first argument 84 | # usage: reiv pattern [options] [path...] 85 | # e.g.: reiv '\.c$' instead of rh -v '"\.c$".rei' 86 | reiv() { reiv_pat="$1"; shift && rh -ve "\"$reiv_pat\".rei" "$@"; } 87 | 88 | 89 | alias rl='rh -rl' # rh -l version of ls -lA (unsorted) 90 | alias rlr='rh -l' # rh -l version of ls -lAR (unsorted) 91 | 92 | alias rv='rh -rv' # rh -v version of ls -lA (unsorted) 93 | alias rvr='rh -v' # rh -v version of ls -lAR (unsorted) 94 | 95 | alias rj='rh -j' 96 | 97 | alias r0='rh -0' 98 | 99 | alias r1='rh -1' 100 | alias r1l='rh -1l' 101 | alias r1v='rh -1v' 102 | 103 | alias ry='rh -y' 104 | alias ryl='rh -yl' 105 | alias ryv='rh -yv' 106 | 107 | alias rY='rh -Y' 108 | alias rYl='rh -Yl' 109 | alias rYv='rh -Yv' 110 | 111 | 112 | # jqs - (helper) use jq to sort rh -j by path 113 | # usage: jq arguments that don't conflict with -s 114 | # e.g.: rh -j | jqs -r 115 | jqs() { jq -s "$@" 'sort_by(.path) | .[].path'; } 116 | 117 | # jqt - (helper) use jq to sort rh -j by mtime, most recent first 118 | # usage: jq arguments that don't conflict with -s 119 | # e.g.: rh -j | jqt -r 120 | jqt() { jq -s "$@" 'sort_by(-.mtime_unix,.path) | .[].path'; } 121 | 122 | # jqz - (helper) use jq to sort rh -j by size 123 | # usage: jq arguments that don't conflict with -s 124 | # e.g.: rh -j | jqz -r 125 | jqz() { jq -s "$@" 'sort_by(.size,.path) | .[].path'; } 126 | 127 | # rhs - plain rh sorted by path (like ls -1AR) 128 | # usage: rh arguments that don't conflict with -j 129 | # e.g.: rhs f 130 | rhs() { rh -j "$@" | jqs -r; } 131 | 132 | # rht - plain rh sorted by mtime, most recent first (like ls -1ARt) 133 | # usage: rh arguments that don't conflict with -j 134 | # e.g.: rht f 135 | rht() { rh -j "$@" | jqt -r; } 136 | 137 | # rhz - plain rh sorted by size (like ls -1AR but sorted by size) 138 | # usage: rh arguments that don't conflict with -j 139 | # e.g.: rhz 'size > 1M' 140 | rhz() { rh -j "$@" | jqz -r; } 141 | 142 | # rls - rh -rl sorted by path (like ls -lA) 143 | # usage: rh arguments that don't conflict with -r or -j 144 | # e.g.: rls f 145 | rls() { eval rh -lM0 $(rh -rj "$@" | jqs); } 146 | 147 | # rlt - rh -rl sorted by mtime, most recent first (like ls -lAt) 148 | # usage: rh arguments that don't conflict with -r or -j 149 | # e.g.: rlt f 150 | rlt() { eval rh -lM0 $(rh -rj "$@" | jqt); } 151 | 152 | # rlz - rh -rl sorted by size (like ls -lA but sorted by size) 153 | # usage: rh arguments that don't conflict with -r or -j 154 | # e.g.: rlz 'size > 1M' 155 | rlz() { eval rh -lM0 $(rh -rj "$@" | jqz); } 156 | 157 | # rlrs - rh -l sorted by path (like ls -lAR) 158 | # usage: rh arguments that don't conflict with -j 159 | # e.g.: rlrs f 160 | rlrs() { eval rh -lM0 $(rh -j "$@" | jqs); } 161 | 162 | # rlrt - rh -l sorted by mtime, most recent first (like ls -lARt) 163 | # usage: rh arguments that don't conflict with -r or -j 164 | # e.g.: rlrt f 165 | rlrt() { eval rh -lM0 $(rh -j "$@" | jqt); } 166 | 167 | # rlrz - rh -l sorted by size (like ls -lAR but sorted by size) 168 | # usage: rh arguments that don't conflict with -r or -j 169 | # e.g.: rlrz 'size > 1M' 170 | rlrz() { eval rh -lM0 $(rh -j "$@" | jqz); } 171 | 172 | # rvs - rh -rv sorted by path (like ls -lA) 173 | # usage: rh arguments that don't conflict with -r or -j 174 | # e.g.: rvs f 175 | rvs() { eval rh -vM0 $(rh -rj "$@" | jqs); } 176 | 177 | # rvt - rh -rv sorted by mtime, most recent first (like ls -lAt) 178 | # usage: rh arguments that don't conflict with -r or -j 179 | # e.g.: rvt f 180 | rvt() { eval rh -vM0 $(rh -rj "$@" | jqt); } 181 | 182 | # rvz - rh -rv sorted by size (like ls -lA but sorted by size) 183 | # usage: rh arguments that don't conflict with -r or -j 184 | # e.g.: rvz 'size > 1M' 185 | rvz() { eval rh -vM0 $(rh -rj "$@" | jqz); } 186 | 187 | # rvrs - rh -v sorted by path (like ls -lAR) 188 | # usage: rh arguments that don't conflict with -j 189 | # e.g.: rvrs f 190 | rvrs() { eval rh -vM0 $(rh -j "$@" | jqs); } 191 | 192 | # rvrt - rh -v sorted by mtime, most recent first (like ls -lARt) 193 | # usage: rh arguments that don't conflict with -r or -j 194 | # e.g.: rvrt f 195 | rvrt() { eval rh -vM0 $(rh -j "$@" | jqt); } 196 | 197 | # rvrz - rh -v sorted by size (like ls -lAR but sorted by size) 198 | # usage: rh arguments that don't conflict with -r or -j 199 | # e.g.: rvrz 'size > 1M' 200 | rvrz() { eval rh -vM0 $(rh -j "$@" | jqz); } 201 | 202 | 203 | # export RAWHIDE_CONFIG=/etc/rawhide.conf 204 | # export RAWHIDE_RC="$HOME"/.rhrc 205 | # export RAWHIDE_COLUMN_WIDTH_DEV_MAJOR=1 206 | # export RAWHIDE_COLUMN_WIDTH_DEV_MINOR=1 207 | # export RAWHIDE_COLUMN_WIDTH_INODE=6 208 | # export RAWHIDE_COLUMN_WIDTH_BLKSIZE=1 209 | # export RAWHIDE_COLUMN_WIDTH_BLOCKS=2 210 | # export RAWHIDE_COLUMN_WIDTH_SPACE=6 211 | # export RAWHIDE_COLUMN_WIDTH_SPACE_UNITS=4 212 | # export RAWHIDE_COLUMN_WIDTH_NLINK=1 213 | # export RAWHIDE_COLUMN_WIDTH_USER=3 214 | # export RAWHIDE_COLUMN_WIDTH_GROUP=3 215 | # export RAWHIDE_COLUMN_WIDTH_SIZE=6 216 | # export RAWHIDE_COLUMN_WIDTH_SIZE_UNITS=4 217 | # export RAWHIDE_COLUMN_WIDTH_RDEV_MAJOR=2 218 | # export RAWHIDE_COLUMN_WIDTH_RDEV_MINOR=3 219 | 220 | # #export RAWHIDE_REPORT_BROKEN_SYMLINKS=1 221 | # #export RAWHIDE_DONT_REPORT_CYCLES=1 222 | # #export RAWHIDE_PCRE2_NOT_UTF8_DEFAULT=1 223 | # #export RAWHIDE_PCRE2_UTF8_DEFAULT=1 224 | # #export RAWHIDE_PCRE2_DOTALL_ALWAYS=1 225 | # #export RAWHIDE_PCRE2_MULTILINE_ALWAYS=1 226 | # #export RAWHIDE_SOLARIS_ACL_NO_TRIVIAL=1 227 | # #export RAWHIDE_SOLARIS_EA_NO_SUNWATTR=1 228 | # #export RAWHIDE_SOLARIS_EA_NO_STATINFO=1 229 | # #export RAWHIDE_EA_SIZE=4096 # On Solaris: 65536 230 | 231 | 232 | -------------------------------------------------------------------------------- /samples/README: -------------------------------------------------------------------------------- 1 | This samples directory contains: 2 | 3 | .rh.sh 4 | ------ 5 | Copy this to ~ and source it from your shell config (e.g., sh, ksh, zsh, bash) 6 | to define the functions rq rql rqv ri ril riv re rel rev rei reil reiv 7 | and the aliases rl rlr rv rvr rj r0 r1 r1l r1v ry ryl ryv rY rYl rYv. 8 | It also contains commented-out environment variables that affect rh. 9 | See rh(1) for details. 10 | 11 | cp samples/.rh.sh ~ 12 | echo '. ~/.rh.sh' >> ~/.profile 13 | 14 | brevity.rh 15 | ---------- 16 | Copy this to ~/.rhrc.d to define the functions i n u g a m su sg nu ng 17 | r w x q sec mn hr dy wk mth yr. See rawhide.conf(5) for details. 18 | 19 | cp samples/brevity.sh ~/.rhrc.d 20 | 21 | rawhide.conf-tiny 22 | ----------------- 23 | This is a smaller version of /etc/rawhide.conf that excludes most of the 24 | longer alternative names for things. Longer alternative names for some 25 | built-ins remain. This might be preferable for resource-constrained systems. 26 | Consider replacing rawhide.conf with this, if you configure --static=tiny. 27 | You don't have to, but with --static=tiny, the default /etc/rawhide.conf 28 | will consume half of the data space, but that's probably fine. 29 | 30 | cp -p samples/rawhide.conf-tiny ./rawhide.conf 31 | ./configure --static=tiny 32 | make 33 | sudo make install 34 | 35 | -------------------------------------------------------------------------------- /samples/brevity.rh: -------------------------------------------------------------------------------- 1 | # brevity.rh: Optional aliases for greater brevity. 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | // Brevity (aliases) 5 | 6 | i { ino } 7 | n { nlink } 8 | u { uid } 9 | g { gid } 10 | a { atime } 11 | m { mtime } 12 | 13 | su { suid } 14 | sg { sgid } 15 | 16 | nu { nouser } 17 | ng { nogroup } 18 | 19 | r { readable } 20 | w { writable } 21 | x { executable } 22 | 23 | q { exit } 24 | 25 | sec { second } 26 | mn { minute } 27 | hr { hour } 28 | dy { day } 29 | wk { week } 30 | mth { month } 31 | yr { year } 32 | 33 | -------------------------------------------------------------------------------- /samples/rawhide.conf-tiny: -------------------------------------------------------------------------------- 1 | # /etc/rawhide.conf: rh system-wide configuration. 2 | # See rh(1) and rawhide.conf(5) for more information. 3 | 4 | 5 | /* 6 | This file constitutes the rawhide standard library. 7 | 8 | Actually, this is a smaller version of the library that 9 | excludes most of the longer alternative names for things. 10 | This might be preferable for resource-constrained systems. 11 | Particularly when rawhide is configured with --static=tiny. 12 | 13 | You can modify this file, and/or place additional 14 | files in the /etc/rawhide.conf.d directory. 15 | They'll be read after this file, in lexicographic order. 16 | Any files whose names start with dot are skipped. 17 | 18 | On some systems, this file could be somewhere other than /etc 19 | (e.g., /usr/local/etc, /opt/local/etc, /usr/pkg/etc). 20 | 21 | You can also create your own user-specific rawhide 22 | functions in ~/.rhrc and ~/.rhrc.d/*. They'll be 23 | read by rh after these system-wide files. 24 | Any files whose names start with dot are skipped. 25 | */ 26 | 27 | 28 | 29 | // File types (canonical, aliases) 30 | 31 | type { mode & IFMT } 32 | 33 | f { type == IFREG } 34 | d { type == IFDIR } 35 | b { type == IFBLK } 36 | c { type == IFCHR } 37 | l { type == IFLNK } 38 | s { type == IFSOCK } 39 | p { type == IFIFO } 40 | D { type == IFDOOR } # Solaris 41 | 42 | // File permissions (canonical, aliases, helpers) 43 | 44 | perm { mode & ~IFMT } 45 | 46 | ur { perm & IRUSR } 47 | uw { perm & IWUSR } 48 | ux { perm & IXUSR } 49 | gr { perm & IRGRP } 50 | gw { perm & IWGRP } 51 | gx { perm & IXGRP } 52 | or { perm & IROTH } 53 | ow { perm & IWOTH } 54 | ox { perm & IXOTH } 55 | wr { perm & IROTH } 56 | ww { perm & IWOTH } 57 | wx { perm & IXOTH } 58 | 59 | suid { perm & ISUID } 60 | sgid { perm & ISGID } 61 | svtx { perm & ISVTX } 62 | 63 | setuid { suid } 64 | setgid { sgid } 65 | sticky { svtx } 66 | 67 | 68 | all(bitmask) { (perm & bitmask) == bitmask } 69 | any(bitmask) { perm & bitmask } 70 | none(bitmask) { !any(bitmask) } 71 | 72 | allr { all(IRUSR | IRGRP | IROTH) } 73 | allw { all(IWUSR | IWGRP | IWOTH) } 74 | allx { all(IXUSR | IXGRP | IXOTH) } 75 | anyr { any(IRUSR | IRGRP | IROTH) } 76 | anyw { any(IWUSR | IWGRP | IWOTH) } 77 | anyx { any(IXUSR | IXGRP | IXOTH) } 78 | noner { !anyr } 79 | nonew { !anyw } 80 | nonex { !anyx } 81 | 82 | 83 | // Aliases for built-ins 84 | 85 | inode { ino } 86 | nlinks { nlink } 87 | user { uid } 88 | group { gid } 89 | space { blocks * 512 } 90 | accessed { atime } 91 | modified { mtime } # Refers to the contents 92 | changed { ctime } # Refers to the inode 93 | len { strlen } 94 | sz { size } 95 | 96 | seconds { second } 97 | minutes { minute } 98 | hours { hour } 99 | days { day } 100 | weeks { week } 101 | months { month } 102 | years { year } 103 | quit { exit } 104 | 105 | imayread { readable } # Uses access(2) not perm 106 | imaywrite { writable } # Uses access(2) not perm 107 | imayexec { executable } # Uses access(2) not perm 108 | 109 | ir { readable } 110 | iw { writable } 111 | ix { executable } 112 | 113 | 114 | // File types for symlink targets (canonical, aliases) 115 | 116 | ttype { tmode & IFMT } 117 | 118 | tf { ttype == IFREG } 119 | td { ttype == IFDIR } 120 | tb { ttype == IFBLK } 121 | tc { ttype == IFCHR } 122 | tl { ttype == IFLNK } # Impossible 123 | ts { ttype == IFSOCK } 124 | tp { ttype == IFIFO } 125 | tD { ttype == IFDOOR } # Solaris 126 | 127 | 128 | // File permissions for symlink targets (canonical, aliases, helpers) 129 | 130 | tperm { tmode & ~IFMT } 131 | 132 | tur { tperm & IRUSR } 133 | tuw { tperm & IWUSR } 134 | tux { tperm & IXUSR } 135 | tgr { tperm & IRGRP } 136 | tgw { tperm & IWGRP } 137 | tgx { tperm & IXGRP } 138 | tor { tperm & IROTH } 139 | tow { tperm & IWOTH } 140 | tox { tperm & IXOTH } 141 | twr { tperm & IROTH } 142 | tww { tperm & IWOTH } 143 | twx { tperm & IXOTH } 144 | 145 | 146 | tsuid { tperm & ISUID } 147 | tsgid { tperm & ISGID } 148 | tsvtx { tperm & ISVTX } 149 | 150 | tsetuid { tsuid } 151 | tsetgid { tsgid } 152 | tsticky { tsvtx } 153 | 154 | 155 | tall(bitmask) { (tperm & bitmask) == bitmask } 156 | tany(bitmask) { tperm & bitmask } 157 | tnone(bitmask) { !tany(bitmask) } 158 | 159 | tallr { tall(IRUSR | IRGRP | IROTH) } 160 | tallw { tall(IWUSR | IWGRP | IWOTH) } 161 | tallx { tall(IXUSR | IXGRP | IXOTH) } 162 | tanyr { tany(IRUSR | IRGRP | IROTH) } 163 | tanyw { tany(IWUSR | IWGRP | IWOTH) } 164 | tanyx { tany(IXUSR | IXGRP | IXOTH) } 165 | tnoner { !tanyr } 166 | tnonew { !tanyw } 167 | tnonex { !tanyx } 168 | 169 | 170 | // Aliases for symlink target built-ins 171 | 172 | tinode { tino } 173 | tnlinks { tnlink } 174 | tuser { tuid } 175 | tgroup { tgid } 176 | tspace { tblocks * 512 } 177 | taccessed { tatime } 178 | tmodified { tmtime } # Refers to the target's contents 179 | tchanged { tctime } # Refers to the target's inode 180 | tlen { tstrlen } 181 | tsz { tsize } 182 | 183 | 184 | // Miscellaneous helper functions 185 | 186 | empty { size == 0 } # Only for files and readable directories 187 | roots { uid == 0 } 188 | mine { uid == $$ } 189 | ours { gid == @@ } 190 | broken { l && !texists } 191 | dangling { broken } 192 | gmtoday { now - now % day } 193 | 194 | ago(sec) { now - sec } 195 | old(sec) { mtime <= ago(sec) } 196 | past(sec) { mtime >= ago(sec) } 197 | future { mtime > now } 198 | 199 | min(x, y) { (x < y) ? x : y } 200 | max(x, y) { (x > y) ? x : y } 201 | abs(x) { (x < 0) ? -x : x } 202 | 203 | -------------------------------------------------------------------------------- /tests/.common: -------------------------------------------------------------------------------- 1 | # rawhide - find files using pretty C expressions 2 | # https://raf.org/rawhide 3 | # https://github.com/raforg/rawhide 4 | # https://codeberg.org/raforg/rawhide 5 | # 6 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, see . 20 | # 21 | # 20231013 raf 22 | 23 | # tests/.common - Test helpers 24 | 25 | # Make sure that rh is compiled first (but not necessarily up to date) 26 | 27 | [ -x ./rh ] || make || exit 1 28 | 29 | umask 022 30 | 31 | # Erase any environment variables that affect rawhide 32 | 33 | unset RAWHIDE_CONFIG 34 | unset RAWHIDE_RC 35 | unset RAWHIDE_PCRE2_NOT_UTF8_DEFAULT 36 | unset RAWHIDE_PCRE2_UTF8_DEFAULT 37 | unset RAWHIDE_PCRE2_DOTALL_ALWAYS 38 | unset RAWHIDE_PCRE2_MULTILINE_ALWAYS 39 | unset RAWHIDE_SOLARIS_ACL_NO_TRIVIAL 40 | unset RAWHIDE_SOLARIS_EA_NO_SUNWATTR 41 | unset RAWHIDE_SOLARIS_EA_NO_STATINFO 42 | unset RAWHIDE_EA_SIZE 43 | unset RAWHIDE_REPORT_BROKEN_SYMLINKS 44 | unset RAWHIDE_DONT_REPORT_CYCLES 45 | # Setting these to 1, rather than unsetting them, increases test coverage slightly 46 | RAWHIDE_COLUMN_WIDTH_DEV_MAJOR=1; export RAWHIDE_COLUMN_WIDTH_DEV_MAJOR 47 | RAWHIDE_COLUMN_WIDTH_DEV_MINOR=1; export RAWHIDE_COLUMN_WIDTH_DEV_MINOR 48 | RAWHIDE_COLUMN_WIDTH_INODE=1; export RAWHIDE_COLUMN_WIDTH_INODE 49 | RAWHIDE_COLUMN_WIDTH_BLKSIZE=1; export RAWHIDE_COLUMN_WIDTH_BLKSIZE 50 | RAWHIDE_COLUMN_WIDTH_BLOCKS=1; export RAWHIDE_COLUMN_WIDTH_BLOCKS 51 | RAWHIDE_COLUMN_WIDTH_SPACE=1; export RAWHIDE_COLUMN_WIDTH_SPACE 52 | RAWHIDE_COLUMN_WIDTH_SPACE_UNITS=1; export RAWHIDE_COLUMN_WIDTH_SPACE_UNITS 53 | RAWHIDE_COLUMN_WIDTH_NLINK=1; export RAWHIDE_COLUMN_WIDTH_NLINK 54 | RAWHIDE_COLUMN_WIDTH_USER=1; export RAWHIDE_COLUMN_WIDTH_USER 55 | RAWHIDE_COLUMN_WIDTH_GROUP=1; export RAWHIDE_COLUMN_WIDTH_GROUP 56 | RAWHIDE_COLUMN_WIDTH_SIZE=1; export RAWHIDE_COLUMN_WIDTH_SIZE 57 | RAWHIDE_COLUMN_WIDTH_SIZE_UNITS=1; export RAWHIDE_COLUMN_WIDTH_SIZE_UNITS 58 | RAWHIDE_COLUMN_WIDTH_RDEV_MAJOR=1; export RAWHIDE_COLUMN_WIDTH_RDEV_MAJOR 59 | RAWHIDE_COLUMN_WIDTH_RDEV_MINOR=1; export RAWHIDE_COLUMN_WIDTH_RDEV_MINOR 60 | 61 | # The default rh command for testing (and some other versions) 62 | 63 | saved_pwd="`pwd`" 64 | 65 | # Set VALGRIND=1 or vg=1 to produce valgrind.out (takes 40 minutes here) 66 | # Set VALGRIND_OPTIONS or vgopts to any additional valgrind options (e.g., --track-origins=yes) 67 | 68 | [ "x$vg" = x1 ] && VALGRIND=1 69 | [ -n "$vgopts" ] && VALGRIND_OPTIONS="$vgopts" 70 | 71 | if [ x"$VALGRIND" = x1 ] 72 | then 73 | valgrind="`command -v valgrind`" 74 | 75 | if [ -n "$valgrind" ] 76 | then 77 | valgrind="$valgrind --log-fd=9 --show-error-list=yes --leak-check=full --track-fds=yes --show-leak-kinds=all $VALGRIND_OPTIONS " 78 | exec 9>>"$saved_pwd/valgrind.out" 79 | else 80 | echo "valgrind not found" >&1 81 | exit 1 82 | fi 83 | fi 84 | 85 | default_rh="${valgrind}./rh -Nn -f rawhide.conf" 86 | explicit_rh="${valgrind}$saved_pwd/rh -Nn -f $saved_pwd/rawhide.conf" 87 | builtin_rh="${valgrind}./rh -Nn" 88 | rh="$default_rh" 89 | 90 | # Prepare 91 | 92 | t="${0##*/}" 93 | d=tests/.$t 94 | errors=0 95 | tests=0 96 | fails=0 97 | 98 | rm -rf $d 99 | mkdir $d 100 | 101 | count_error() 102 | { 103 | errors="`expr $errors + 1`" 104 | } 105 | 106 | count_test() 107 | { 108 | tests="`expr $tests + 1`" 109 | } 110 | 111 | count_fail() 112 | { 113 | fails="`expr $fails + 1`" 114 | } 115 | 116 | # Cleanup 117 | 118 | finish() 119 | { 120 | rm -rf $d 121 | report 122 | } 123 | 124 | # Default hooks for test_rawhide() 125 | 126 | test_rawhide_pre_hook() { true; } 127 | test_rawhide_post_hook() { true; } 128 | 129 | # Run rh and check its outputs against expectations 130 | 131 | test_rawhide() 132 | { 133 | cmd="$1" 134 | expected_stdout="$2" # Used by printf 135 | expected_stderr="$3" # Used by printf 136 | expected_rc="$4" 137 | desc="$5" # Used by echo 138 | 139 | count_test 140 | failed=0 141 | 142 | stdout=tests/$t.out 143 | stderr=tests/$t.err 144 | 145 | [ -n "$expected_stdout" ] && printf "$expected_stdout" > $stdout.expected || touch $stdout.expected 146 | [ -n "$expected_stderr" ] && printf "$expected_stderr" > $stderr.expected || touch $stderr.expected 147 | 148 | test_rawhide_pre_hook 149 | 150 | /bin/sh -c "$cmd" >$stdout 2>$stderr 151 | rc=$? 152 | 153 | test_rawhide_post_hook 154 | 155 | if [ x"$DEBUG" = x1 ] 156 | then 157 | echo "====================" 158 | [ -n "$find_cmd" ] && echo "$find_cmd [exit=$expected_rc]" 159 | echo "$cmd [exit=$rc]" 160 | echo "=== $stdout.expected" 161 | cat $stdout.expected 162 | echo "=== $stdout" 163 | cat $stdout 164 | echo "=== $stderr.expected" 165 | cat $stderr.expected 166 | echo "=== $stderr" 167 | cat $stderr 168 | echo "===" 169 | fi 170 | 171 | diff -u $stdout.expected $stdout >/dev/null 172 | if [ $? != 0 ] 173 | then 174 | echo "TEST $t fail ($label - $desc - stdout)" 175 | echo "$cmd" 176 | diff -u $stdout.expected $stdout 177 | errors=1 178 | failed=1 179 | else 180 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stdout)" 181 | fi 182 | 183 | diff -u $stderr.expected $stderr >/dev/null 184 | if [ $? != 0 ] 185 | then 186 | echo "TEST $t fail ($label - $desc - stderr)" 187 | echo "$cmd" 188 | diff -u $stderr.expected $stderr 189 | errors=1 190 | failed=1 191 | else 192 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stderr)" 193 | fi 194 | 195 | if [ $rc != $expected_rc ] 196 | then 197 | echo "TEST $t fail ($label - $desc - exit status)" 198 | echo "$cmd" 199 | echo "rc=$rc expected=$expected_rc" 200 | errors=1 201 | failed=1 202 | else 203 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - exit status)" 204 | fi 205 | 206 | rm -r $stdout $stderr $stdout.expected $stderr.expected 207 | [ "$failed" = 1 ] && count_fail 208 | } 209 | 210 | # Run rh and check its outputs against a choice of two expectations 211 | 212 | test_rawhide_either() 213 | { 214 | cmd="$1" 215 | expected_stdout="$2" # Used by printf 216 | expected_stdout_2="$3" # Used by printf 217 | expected_stderr="$4" # Used by printf 218 | expected_rc="$5" 219 | desc="$6" # Used by echo 220 | 221 | count_test 222 | failed=0 223 | 224 | stdout=tests/$t.out 225 | stderr=tests/$t.err 226 | 227 | [ -n "$expected_stdout" ] && printf "$expected_stdout" > $stdout.expected || touch $stdout.expected 228 | [ -n "$expected_stdout_2" ] && printf "$expected_stdout_2" > $stdout.expected_2 || touch $stdout.expected_2 229 | [ -n "$expected_stderr" ] && printf "$expected_stderr" > $stderr.expected || touch $stderr.expected 230 | 231 | test_rawhide_pre_hook 232 | 233 | /bin/sh -c "$cmd" >$stdout 2>$stderr 234 | rc=$? 235 | 236 | test_rawhide_post_hook 237 | 238 | if [ x"$DEBUG" = x1 ] 239 | then 240 | echo "====================" 241 | [ -n "$find_cmd" ] && echo "$find_cmd [exit=$expected_rc]" 242 | echo "$cmd [exit=$rc]" 243 | echo "=== $stdout.expected" 244 | cat $stdout.expected 245 | echo "=== $stdout.expected_2" 246 | cat $stdout.expected_2 247 | echo "=== $stdout" 248 | cat $stdout 249 | echo "=== $stderr.expected" 250 | cat $stderr.expected 251 | echo "=== $stderr" 252 | cat $stderr 253 | echo "===" 254 | fi 255 | 256 | diff -u $stdout.expected $stdout >/dev/null 257 | if [ $? != 0 ] 258 | then 259 | diff -u $stdout.expected_2 $stdout >/dev/null 260 | if [ $? != 0 ] 261 | then 262 | echo "TEST $t fail ($label - $desc - stdout)" 263 | echo "$cmd" 264 | diff -u $stdout.expected $stdout 265 | diff -u $stdout.expected_2 $stdout 266 | errors=1 267 | failed=1 268 | else 269 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stdout)" 270 | fi 271 | else 272 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stdout)" 273 | fi 274 | 275 | diff -u $stderr.expected $stderr >/dev/null 276 | if [ $? != 0 ] 277 | then 278 | echo "TEST $t fail ($label - $desc - stderr)" 279 | echo "$cmd" 280 | diff -u $stderr.expected $stderr 281 | errors=1 282 | failed=1 283 | else 284 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stderr)" 285 | fi 286 | 287 | if [ $rc != $expected_rc ] 288 | then 289 | echo "TEST $t fail ($label - $desc - exit status)" 290 | echo "$cmd" 291 | echo "rc=$rc expected=$expected_rc" 292 | errors=1 293 | failed=1 294 | else 295 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - exit status)" 296 | fi 297 | 298 | rm -r $stdout $stderr $stdout.expected $stdout.expected_2 $stderr.expected 299 | [ "$failed" = 1 ] && count_fail 300 | } 301 | 302 | # Report test success/failure 303 | 304 | report() 305 | { 306 | if [ $errors = 0 ] 307 | then 308 | if [ $tests = 1 ] 309 | then 310 | echo "$t: The $tests test passed ($label)" 311 | else 312 | echo "$t: All $tests tests passed ($label)" 313 | fi 314 | else 315 | echo "$t: $fails/$tests tests failed ($label)" 316 | fi 317 | } 318 | 319 | # Hooks for comparing rh against find 320 | 321 | test_rh_find_pre_hook() 322 | { 323 | /bin/sh -c "$find_cmd" >$stdout.expected 2>$stderr.expected 324 | expected_rc=$? 325 | } 326 | 327 | test_rawhide_find() 328 | { 329 | cmd="$1" 330 | find_cmd="$2" 331 | desc="$3" 332 | 333 | expected_stdout="" 334 | expected_stderr="" 335 | expected_rc="" 336 | 337 | test_rawhide "$cmd" "$expected_stdout" "$expected_stderr" "$expected_rc" "$desc" 338 | } 339 | 340 | # Hooks to cd into a directory and back out again 341 | 342 | test_rh_cd_pre_hook() 343 | { 344 | saved_stdout=$stdout 345 | saved_stderr=$stderr 346 | stdout="$saved_pwd/$stdout" 347 | stderr="$saved_pwd/$stderr" 348 | cd ./$d 349 | } 350 | 351 | test_rh_cd_post_hook() 352 | { 353 | stdout=$saved_stdout 354 | stderr=$saved_stderr 355 | cd "$saved_pwd" 356 | } 357 | 358 | # Post hook to sort stdout 359 | 360 | test_rh_sort_post_hook() 361 | { 362 | LANG=C sort $stdout > $stdout.sorted 363 | mv $stdout.sorted $stdout 364 | LANG=C sort $stderr > $stderr.sorted 365 | mv $stderr.sorted $stderr 366 | } 367 | 368 | # Post hook to smooth out differences in getopt error messages (no longer used) 369 | 370 | test_rh_getopt_errors_post_hook() 371 | { 372 | sed \ 373 | -e "s/option requires an argument -- \(.\)$/option requires an argument -- '\1'/" \ 374 | -e "s/illegal option -- \(.\)/invalid option -- '\1'/" $stderr > $stderr.tmp && mv $stderr.tmp $stderr 375 | 376 | } 377 | 378 | # Post hook to replace $stdout with just its first line 379 | 380 | test_rh_first_line_post_hook() 381 | { 382 | head -1 < $stdout > $stdout.tmp && mv $stdout.tmp $stdout 383 | } 384 | 385 | # Post hook to translate errno text from Solaris's versions 386 | # to everywhere else's versions. Musl needs a translation as well. 387 | 388 | test_rh_errno_post_hook() 389 | { 390 | sed \ 391 | -e 's/Not owner/Operation not permitted/' \ 392 | -e 's/Insufficient privileges/Operation not permitted/' \ 393 | -e 's/File exists/Directory not empty/' \ 394 | -e 's/Number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS/Too many levels of symbolic links/' \ 395 | -e 's/Symbolic link loop/Too many levels of symbolic links/' \ 396 | -e 's/Undefined error: 0/Success/' \ 397 | -e 's/No error: 0/Success/' \ 398 | -e 's/Error 0/Success/' \ 399 | $stderr > $stderr.tmp && mv $stderr.tmp $stderr 400 | } 401 | 402 | # Return whether or not the local find supports -mindepth (Solaris doesn't) 403 | 404 | find_has_mindepth() 405 | { 406 | find --help 2>&1 | grep -q mindepth 407 | return $? 408 | } 409 | 410 | test_rawhide_grep() 411 | { 412 | cmd="$1" 413 | expected_stdout_pattern="$2" # Used by grep 414 | expected_stderr="$3" # Used by printf 415 | expected_rc="$4" 416 | desc="$5" # Used by echo 417 | 418 | count_test 419 | failed=0 420 | 421 | stdout=tests/$t.out 422 | stderr=tests/$t.err 423 | 424 | [ -n "$expected_stderr" ] && printf "$expected_stderr" > $stderr.expected || touch $stderr.expected 425 | 426 | test_rawhide_pre_hook 427 | 428 | /bin/sh -c "$cmd" >$stdout 2>$stderr 429 | rc=$? 430 | 431 | test_rawhide_post_hook 432 | 433 | if [ x"$DEBUG" = x1 ] 434 | then 435 | echo "====================" 436 | [ -n "$find_cmd" ] && echo "$find_cmd [exit=$expected_rc]" 437 | echo "$cmd [exit=$rc]" 438 | echo "=== stdout.expected" 439 | echo $expected_stdout_pattern 440 | echo "=== $stdout" 441 | cat $stdout 442 | echo "=== $stderr.expected" 443 | cat $stderr.expected 444 | echo "=== $stderr" 445 | cat $stderr 446 | echo "===" 447 | fi 448 | 449 | [ -x /usr/xpg4/bin/grep ] && grep=/usr/xpg4/bin/grep || grep=grep # For Solaris 450 | $grep -E -v "$expected_stdout_pattern" < $stdout >/dev/null 451 | if [ $? = 0 ] 452 | then 453 | echo "TEST $t fail ($label - $desc - stdout)" 454 | echo "$cmd" 455 | echo "$expected_stdout_pattern" 456 | $grep -E -v "$expected_stdout_pattern" < $stdout 457 | errors=1 458 | failed=1 459 | else 460 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stdout)" 461 | fi 462 | 463 | diff -u $stderr.expected $stderr >/dev/null 464 | if [ $? != 0 ] 465 | then 466 | echo "TEST $t fail ($label - $desc - stderr)" 467 | echo "$cmd" 468 | diff -u $stderr.expected $stderr 469 | errors=1 470 | failed=1 471 | else 472 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - stderr)" 473 | fi 474 | 475 | if [ $rc != $expected_rc ] 476 | then 477 | echo "TEST $t fail ($label - $desc - exit status)" 478 | echo "$cmd" 479 | echo "rc=$rc expected=$expected_rc" 480 | errors=1 481 | failed=1 482 | else 483 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $desc - exit status)" 484 | fi 485 | 486 | rm -r $stdout $stderr $stderr.expected 487 | [ "$failed" = 1 ] && count_fail 488 | } 489 | 490 | # vi:set ts=4 sw=4: 491 | -------------------------------------------------------------------------------- /tests/.new: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="TEST_SUITE_DESCRIPTION" 28 | 29 | # mkdir $d/... 30 | # touch $d/... 31 | 32 | 33 | # test_rawhide "CMD" "STDOUT" "STDERR" RC "DESC" 34 | # test_rawhide "$rh ... $d" "" "" 0 "" 35 | 36 | 37 | # test_rawhide_pre_hook() { test_rh_find_pre_hook; } 38 | # test_rawhide_find "CMD" "FIND_CMD" "DESC" 39 | # test_rawhide_find "" "" "" 40 | 41 | finish 42 | 43 | exit $errors 44 | 45 | # vi:set ts=4 sw=4: 46 | -------------------------------------------------------------------------------- /tests/t01: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-x/-X %s/%S prevent shell command injection" 28 | 29 | touch $d/"cmdinjtest; cd tests >&- 2>&-; cd .$t >&- 2>&-; echo 'oops! command injection succeeded' > cmdinjtest.out" 30 | 31 | label2="-x %s" 32 | count_test 33 | $rh -e f -x 'file %s' $d >/dev/null 34 | rc=$? 35 | 36 | if [ -f $d/cmdinjtest.out ] 37 | then 38 | echo "TEST $t fail ($label - $label2)" 39 | echo $d/cmdinjtest.out: 40 | cat $d/cmdinjtest.out 41 | count_fail 42 | errors=1 43 | elif [ $rc != 0 ] 44 | then 45 | echo "TEST $t fail ($label - $label2)" 46 | count_fail 47 | errors=1 48 | else 49 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $label2)" 50 | fi 51 | 52 | label2="-x %S" 53 | count_test 54 | $rh -e f -x "file $d/%S" $d >/dev/null 55 | rc=$? 56 | 57 | if [ -f $d/cmdinjtest.out ] 58 | then 59 | echo "TEST $t fail ($label - $label2)" 60 | echo $d/cmdinjtest.out: 61 | cat $d/cmdinjtest.out 62 | count_fail 63 | errors=1 64 | elif [ $rc != 0 ] 65 | then 66 | echo "TEST $t fail ($label - $label2)" 67 | count_fail 68 | errors=1 69 | else 70 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $label2)" 71 | fi 72 | 73 | label2="-X %s" 74 | count_test 75 | $rh -e f -X "cd $saved_pwd && file %s" $d >/dev/null 76 | rc=$? 77 | 78 | if [ -f $d/cmdinjtest.out ] 79 | then 80 | echo "TEST $t fail ($label - $label2)" 81 | echo $d/cmdinjtest.out: 82 | cat $d/cmdinjtest.out 83 | count_fail 84 | errors=1 85 | elif [ $rc != 0 ] 86 | then 87 | echo "TEST $t fail ($label - $label2)" 88 | count_fail 89 | errors=1 90 | else 91 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $label2)" 92 | fi 93 | 94 | label2="-X %S" 95 | count_test 96 | $rh -e f -X 'file %S' $d >/dev/null 97 | rc=$? 98 | 99 | if [ -f $d/cmdinjtest.out ] 100 | then 101 | echo "TEST $t fail ($label - $label2)" 102 | echo $d/cmdinjtest.out: 103 | cat $d/cmdinjtest.out 104 | count_fail 105 | errors=1 106 | elif [ $rc != 0 ] 107 | then 108 | echo "TEST $t fail ($label - $label2)" 109 | count_fail 110 | errors=1 111 | else 112 | [ x"$quiet" = x1 ] || echo "TEST $t pass ($label - $label2)" 113 | fi 114 | 115 | # Extra tricky 116 | 117 | # These tests (by Stéphane Chazelas) show how `` is more dangerous 118 | # than $() when interpolation of %s/%S is done by quoting with 119 | # backslashes (which is the method that used to be used by rh). 120 | # When a pathname contains backticks, those backticks were backslashed 121 | # by rh, but those backslashes would be processed within any backticks 122 | # in the shell command, and so the contents of the internal backticks 123 | # would be executed by the shell when parsing the final resulting command. 124 | # 125 | # The first two (commented out) tests show the original behaviour with 126 | # `` when interpolation was done by quoting. The next two show the new 127 | # fixed behaviour where %s/%S are passed as positional arguments to sh -c 128 | # as "$1"/"$2" thus eliminating the problem that it isn't actually possible 129 | # to interpolate by quoting because the context in which the interpolation 130 | # happens affects which method of quoting is needed, and it's impossible to 131 | # know what context(s) will be used without actually parsing the shell 132 | # command (which is not an option). The last two tests show the equivalent 133 | # shell command using $() rather than `` which worked safely with both 134 | # methods of interpolation. 135 | 136 | rh2="${valgrind}`pwd`/rh -Nn -f `pwd`/rawhide.conf" 137 | mkdir $d/'`$X`' 138 | touch $d/'`$X`'/f 139 | #test_rawhide "X='echo tricky' $rh -m1 -e 'd && !empty && \"[ -n \\\"\`$rh2 -ref -- %S\`\\\" ]\".sh' $d" "" "rh: fstatat tricky: No such file or directory\n" 0 "backtick cmd with backticks in %S and arbitrary cmd with space in env (orig unsafe)" 140 | #test_rawhide "X='/sbin/reboot-not-really' $rh -m1 -e 'd && !empty && \"[ -n \\\"\`$rh2 -ref -- %S\`\\\" ]\".sh' $d" "$d/\`\$X\`\n" "sh: 1: /sbin/reboot-not-really: not found\n" 0 "backtick cmd with backticks in %S and arbitrary cmd with slash in env (orig unsafe)" 141 | test_rawhide "X='echo tricky' $rh -m1 -e 'd && !empty && \"[ -n \\\"\`$rh2 -ref -- %S\`\\\" ]\".sh' $d" "$d/\`\$X\`\n" "" 0 "backtick cmd with backticks in %S and arbitrary cmd with space in env (safe)" 142 | test_rawhide "X='/sbin/reboot-not-really' $rh -m1 -e 'd && !empty && \"[ -n \\\"\`$rh2 -ref -- %S\`\\\" ]\".sh' $d" "$d/\`\$X\`\n" "" 0 "backtick cmd with backticks in %S and arbitrary cmd with slash in env (safe)" 143 | test_rawhide "X='echo tricky' $rh -m1 -e 'd && !empty && \"[ -n \\\"\$($rh2 -ref -- %S)\\\" ]\".sh' $d" "$d/\`\$X\`\n" "" 0 "\$() cmd with backticks in %S and arbitrary cmd with space in env (safe)" 144 | test_rawhide "X='/sbin/reboot-not-really' $rh -m1 -e 'd && !empty && \"[ -n \\\"\$($rh2 -ref -- %S)\\\" ]\".sh' $d" "$d/\`\$X\`\n" "" 0 "\$() cmd with backticks in %S and arbitrary cmd with slash in env (safe)" 145 | 146 | finish 147 | 148 | exit $errors 149 | 150 | # vi:set ts=4 sw=4: 151 | -------------------------------------------------------------------------------- /tests/t02: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-x/-X cmd buf size handling" 28 | label2="-x" 29 | 30 | touch $d/"abcd " 31 | 32 | test_cmdbufsize() 33 | { 34 | max="$1" 35 | cmd="$2" 36 | expected_stdout="$3" 37 | expected_stderr="$4" 38 | expected_rc="$5" 39 | desc="$6" 40 | 41 | test_rawhide "RAWHIDE_TEST_CMD_MAX=$max $cmd" "$expected_stdout" "$expected_stderr" "$expected_rc" "$label2 - $desc" 42 | } 43 | 44 | # Where buf size checks are: 45 | # - not interpolating (char is not %) 46 | # - interpolating %s 47 | # - interpolating %S 48 | # - interpolating %% 49 | 50 | # These require a buffer size of at least 19 51 | # echo 6789012345678 52 | test_cmdbufsize 20 "$rh -x 'echo 6789012345678' $d" "6789012345678\n6789012345678\n" "" 0 "not interpolating: small" 53 | test_cmdbufsize 19 "$rh -x 'echo 6789012345678' $d" "6789012345678\n6789012345678\n" "" 0 "not interpolating: max" 54 | test_cmdbufsize 18 "$rh -x 'echo 6789012345678' $d" "" "./rh: command is too big: echo 6789012345678 (tests/.$t)\n./rh: command is too big: echo 6789012345678 (tests/.$t/abcd )\n" 1 "not interpolating: too big" 55 | 56 | # These require a buffer size of at least 10 57 | # echo "$1" 58 | test_cmdbufsize 11 "$rh -x 'echo %s' $d" "tests/.$t\ntests/.$t/abcd \n" "" 0 "interpolating %s: small" 59 | test_cmdbufsize 10 "$rh -x 'echo %s' $d" "tests/.$t\ntests/.$t/abcd \n" "" 0 "interpolating %s: max" 60 | test_cmdbufsize 9 "$rh -x 'echo %s' $d" "" "./rh: command is too big: echo %%s (tests/.$t)\n./rh: command is too big: echo %%s (tests/.$t/abcd )\n" 1 "interpolating %s: too big" 61 | 62 | 63 | # These require a buffer size of at least 10 64 | # echo "$2" 65 | test_cmdbufsize 11 "$rh -x 'echo %S' $d" ".$t\nabcd \n" "" 0 "interpolating %S: small" 66 | test_cmdbufsize 10 "$rh -x 'echo %S' $d" ".$t\nabcd \n" "" 0 "interpolating %S: max" 67 | test_cmdbufsize 09 "$rh -x 'echo %S' $d" "" "./rh: command is too big: echo %%S (tests/.$t)\n./rh: command is too big: echo %%S (tests/.$t/abcd )\n" 1 "interpolating %S: too big" 68 | 69 | # These require a buffer size of at least 12 70 | # echo "$1" % 71 | test_cmdbufsize 13 "$rh -x 'echo %s %%' $d" "tests/.$t %%\ntests/.$t/abcd %%\n" "" 0 "interpolating %%: small" 72 | test_cmdbufsize 12 "$rh -x 'echo %s %%' $d" "tests/.$t %%\ntests/.$t/abcd %%\n" "" 0 "interpolating %%: max" 73 | test_cmdbufsize 11 "$rh -x 'echo %s %%' $d" "" "./rh: command is too big: echo %%s %%%% (tests/.$t)\n./rh: command is too big: echo %%s %%%% (tests/.$t/abcd )\n" 1 "interpolating %%: too big" 74 | 75 | label2="-X" 76 | 77 | # These require a buffer size of at least 19 78 | # echo 6789012345678 79 | test_cmdbufsize 20 "$rh -X 'echo 6789012345678' $d" "6789012345678\n6789012345678\n" "" 0 "not interpolating: small" 80 | test_cmdbufsize 19 "$rh -X 'echo 6789012345678' $d" "6789012345678\n6789012345678\n" "" 0 "not interpolating: max" 81 | test_cmdbufsize 18 "$rh -X 'echo 6789012345678' $d" "" "./rh: command is too big: echo 6789012345678 (tests/.$t)\n./rh: command is too big: echo 6789012345678 (tests/.$t/abcd )\n" 1 "not interpolating: too big" 82 | 83 | # These require a buffer size of at least 10 84 | # echo "$1" 85 | test_cmdbufsize 11 "$rh -X 'echo %s' $d" "tests/.$t\ntests/.$t/abcd \n" "" 0 "interpolating %s: small" 86 | test_cmdbufsize 10 "$rh -X 'echo %s' $d" "tests/.$t\ntests/.$t/abcd \n" "" 0 "interpolating %s: max" 87 | test_cmdbufsize 9 "$rh -X 'echo %s' $d" "" "./rh: command is too big: echo %%s (tests/.$t)\n./rh: command is too big: echo %%s (tests/.$t/abcd )\n" 1 "interpolating %s: too big" 88 | 89 | # These require a buffer size of at least 10 90 | # echo "$2" 91 | test_cmdbufsize 11 "$rh -X 'echo %S' $d" ".$t\nabcd \n" "" 0 "interpolating %S: small" 92 | test_cmdbufsize 10 "$rh -X 'echo %S' $d" ".$t\nabcd \n" "" 0 "interpolating %S: max" 93 | test_cmdbufsize 09 "$rh -X 'echo %S' $d" "" "./rh: command is too big: echo %%S (tests/.$t)\n./rh: command is too big: echo %%S (tests/.$t/abcd )\n" 1 "interpolating %S: too big" 94 | 95 | # These require a buffer size of at least 12 96 | # echo "$1" % 97 | test_cmdbufsize 13 "$rh -X 'echo %s %%' $d" "tests/.$t %%\ntests/.$t/abcd %%\n" "" 0 "interpolating %%: small" 98 | test_cmdbufsize 12 "$rh -X 'echo %s %%' $d" "tests/.$t %%\ntests/.$t/abcd %%\n" "" 0 "interpolating %%: max" 99 | test_cmdbufsize 11 "$rh -X 'echo %s %%' $d" "" "./rh: command is too big: echo %%s %%%% (tests/.$t)\n./rh: command is too big: echo %%s %%%% (tests/.$t/abcd )\n" 1 "interpolating %%: too big" 100 | 101 | finish 102 | 103 | exit $errors 104 | 105 | # vi:set ts=4 sw=4: 106 | -------------------------------------------------------------------------------- /tests/t03: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="path buf size handling" 28 | 29 | mkdir $d/0123456789 30 | mkdir $d/0123456789/0123456789 31 | touch $d/0123456789/0123456789/0123456789 32 | 33 | test_pathbufsize() 34 | { 35 | max="$1" 36 | cmd="$2" 37 | expected_stdout="$3" 38 | expected_stderr="$4" 39 | expected_rc="$5" 40 | desc="$6" 41 | 42 | max="`expr $max - 1`" # Convert buf size to max length 43 | test_rawhide "RAWHIDE_TEST_PATHLEN_MAX=$max $cmd" "$expected_stdout" "$expected_stderr" "$expected_rc" "$desc" 44 | } 45 | 46 | # Where buf size checks are: 47 | # 1 - rawhide_search - initial fpath 48 | # 2 - rawhide_search - appending trailing / 49 | # 3 - rawhide_traverse - appending d_name 50 | # 4 - rawhide_traverse - appending trailing / 51 | # 52 | # For 3 and 4, fpath grows as needed (in case we cross a filesystem boundary) 53 | 54 | # This requires a path buf size of at least 44 to succeed without forcing 55 | # the path buf to grow 56 | # tests/.t03/0123456789/0123456789/0123456789 57 | 58 | ln -s rawhide.conf rc # Avoid errors about rawhide.conf.d being too long 59 | rh="./rh -Nn -f rc" 60 | test_pathbufsize 10 "$rh $d" "" "./rh: path is too long: $d\n" 1 "too big - [10] initial path" 61 | test_pathbufsize 11 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [11] appending / to initial path - so buffer grows (4)" 62 | test_pathbufsize 12 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [12] appending d_name to initial path - so buffer grows (3)" 63 | test_pathbufsize 21 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [21] appending d_name to initial path - so buffer grows (3)" 64 | test_pathbufsize 22 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [22] appending / to subpath - so buffer grows (4)" 65 | test_pathbufsize 23 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [23] appending d_name to subpath - so buffer grows (3)" 66 | test_pathbufsize 32 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [32] appending d_name to subpath - so buffer grows (3)" 67 | test_pathbufsize 33 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [33] appending / to subsubpath - so buffer grows (4)" 68 | test_pathbufsize 34 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [34] appending d_name to subsubpath - so buffer grows (3)" 69 | test_pathbufsize 43 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "too big - [43] appending d_name to subsubpath - so buffer grows (3)" 70 | test_pathbufsize 44 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "[44] max" 71 | test_pathbufsize 99 "$rh $d" "$d\n$d/0123456789\n$d/0123456789/0123456789\n$d/0123456789/0123456789/0123456789\n" "" 0 "[99] small" 72 | rm rc 73 | 74 | finish 75 | 76 | exit $errors 77 | 78 | # vi:set ts=4 sw=4: 79 | -------------------------------------------------------------------------------- /tests/t04: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="rc is failure when -x cmd fails" 28 | 29 | touch $d/abc 30 | 31 | test_rawhide "$rh -x 'echo out' $d" "out\nout\n" "" 0 "-x rc=0" 32 | test_rawhide "$rh -x 'echo err >&2' $d" "" "err\nerr\n" 0 "-x stderr but rc=0" 33 | test_rawhide "$rh -x 'echo err >&2; false' $d" "" "err\nerr\n" 1 "-x stderr and rc=1" 34 | 35 | label="rc is failure when -X cmd fails" 36 | 37 | test_rawhide "$rh -X 'echo out' $d" "out\nout\n" "" 0 "-X rc=0" 38 | test_rawhide "$rh -X 'echo err >&2' $d" "" "err\nerr\n" 0 "-X stderr but rc=0" 39 | test_rawhide "$rh -X 'echo err >&2; false' $d" "" "err\nerr\n" 1 "-X stderr and rc=1" 40 | 41 | finish 42 | 43 | exit $errors 44 | 45 | # vi:set ts=4 sw=4: 46 | -------------------------------------------------------------------------------- /tests/t05: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-0 option" 28 | 29 | touch $d/abc 30 | 31 | test_rawhide_pre_hook() { test_rh_find_pre_hook; } 32 | 33 | test_rawhide_find "$rh $d" "find $d -print" "without -0 gives newline chars" 34 | test_rawhide_find "$rh -0 $d" "find $d -print0" "with -0 gives nul chars" 35 | 36 | finish 37 | 38 | exit $errors 39 | 40 | # vi:set ts=4 sw=4: 41 | -------------------------------------------------------------------------------- /tests/t06: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="trivial options (-h --help -V --version invalid)" 28 | 29 | touch $d/abc 30 | 31 | test_rawhide_post_hook() { test_rh_first_line_post_hook; } 32 | 33 | test_rawhide "./rh -h" "usage: rh [options] [path...]\n" "" 0 "-h option" 34 | test_rawhide "./rh --help" "usage: rh [options] [path...]\n" "" 0 "--help option" 35 | test_rawhide_grep "./rh -V" "^rh-[0-9.]+[a-z]?$" "" 0 "-V option" 36 | test_rawhide_grep "./rh --version" "^rh-[0-9.]+[a-z]?$" "" 0 "--version option" 37 | 38 | test_rawhide "./rh -!" "" "./rh: invalid option: -! (see ./rh -h for help)\n" 1 "invalid option" 39 | 40 | finish 41 | 42 | exit $errors 43 | 44 | # vi:set ts=4 sw=4: 45 | -------------------------------------------------------------------------------- /tests/t07: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-e and -f option variations" 28 | 29 | touch $d/abc 30 | 31 | test_rawhide "$rh $d" "$d\n$d/abc\n" "" 0 "default -e 1" 32 | test_rawhide "$rh -e '' $d" "$d\n$d/abc\n" "" 0 "explicit -e '' (default to implicit -e 1)" 33 | test_rawhide "$rh -e 1 $d" "$d\n$d/abc\n" "" 0 "explicit -e 1" 34 | test_rawhide "$rh 1 $d" "$d\n$d/abc\n" "" 0 "implicit -e 1 before dir" 35 | test_rawhide "$rh $d 1" "$d\n$d/abc\n" "" 0 "implicit -e 1 after dir" 36 | test_rawhide "$rh $d 1 $d" "$d\n$d/abc\n$d\n$d/abc\n" "" 0 "implicit -e 1 between two dirs" 37 | test_rawhide "$rh -e file $d" "$d/abc\n" "" 0 "explicit -e file" 38 | test_rawhide "$rh file $d" "$d/abc\n" "" 0 "implicit -e file before dir" 39 | test_rawhide "$rh $d file" "$d/abc\n" "" 0 "implicit -e file after dir" 40 | test_rawhide "$rh $d file $d" "$d/abc\n$d/abc\n" "" 0 "implicit -e file between two dirs" 41 | test_rawhide "$rh -e dir $d" "$d\n" "" 0 "explicit -e dir" 42 | test_rawhide "$rh dir $d" "$d\n" "" 0 "implicit -e dir before dir" 43 | test_rawhide "$rh $d dir" "$d\n" "" 0 "implicit -e dir after dir" 44 | test_rawhide "$rh $d dir $d" "$d\n$d\n" "" 0 "implicit -e dir between two dirs" 45 | 46 | test_rawhide "$rh -e 'jnk(){1}' 1 $d" "$d\n$d/abc\n" "" 0 "explicit -e with no expr with no expr and implicit -e 1 before dir" 47 | test_rawhide "$rh -e 'jnk(){1}' $d 1" "$d\n$d/abc\n" "" 0 "explicit -e with no expr and implicit -e 1 after dir" 48 | test_rawhide "$rh -e 'jnk(){1}' $d 1 $d" "$d\n$d/abc\n$d\n$d/abc\n" "" 0 "explicit -e with no expr and implicit -e 1 between two dirs" 49 | test_rawhide "$rh -e 'jnk(){1}' file $d" "$d/abc\n" "" 0 "explicit -e with no expr and implicit -e file before dir" 50 | test_rawhide "$rh -e 'jnk(){1}' $d file" "$d/abc\n" "" 0 "explicit -e with no expr and implicit -e file after dir" 51 | test_rawhide "$rh -e 'jnk(){1}' $d file $d" "$d/abc\n$d/abc\n" "" 0 "explicit -e with no expr and implicit -e file between two dirs" 52 | test_rawhide "$rh -e 'jnk(){1}' dir $d" "$d\n" "" 0 "explicit -e with no expr and implicit -e dir before dir" 53 | test_rawhide "$rh -e 'jnk(){1}' $d dir" "$d\n" "" 0 "explicit -e with no expr and implicit -e dir after dir" 54 | test_rawhide "$rh -e 'jnk(){1}' $d dir $d" "$d\n$d\n" "" 0 "explicit -e with no expr and implicit -e dir between two dirs" 55 | 56 | test_rawhide "echo 0 | $builtin_rh -f- -e '' $d" "" "" 0 "-fzero explicit -e '' (empty -e default to -fzero trailing expr)" 57 | test_rawhide "echo 0 | $builtin_rh -f- -e '' 1 $d" "$d\n$d/abc\n" "" 0 "-fzero explicit -e '' 1 (empty -e and implicit cmdarg expr)" 58 | 59 | # These tests have to run from inside the test directory (so as to default to ".") 60 | 61 | rh="$explicit_rh" 62 | test_rawhide_pre_hook() { test_rh_cd_pre_hook; } 63 | test_rawhide_post_hook() { test_rh_cd_post_hook; } 64 | 65 | test_rawhide "$rh dir" ".\n" "" 0 "implicit -e dir without dir args (default .)" 66 | test_rawhide "$rh file" "./abc\n" "" 0 "implicit -e file without dir args (default .)" 67 | 68 | test_rawhide_pre_hook() { true; } 69 | test_rawhide_post_hook() { true; } 70 | 71 | # Test -f and -f- 72 | 73 | rh="$builtin_rh" 74 | test_rawhide "$rh -f tests/missing $d" "" "./rh: invalid -f option argument: tests/missing: No such file or directory\n" 1 "-f with missing file" 75 | 76 | echo "yes() { 1 }" > $d.conf 77 | echo "no() { 0 }" > $d.conf2 78 | test_rawhide "$rh -f $d.conf $d" "$d\n$d/abc\n" "" 0 "-f ok but unused" 79 | test_rawhide "$rh -f $d.conf -f $d.conf2 $d" "$d\n$d/abc\n" "" 0 "-f twice (allowed)" 80 | test_rawhide "$rh -f $d.conf -e yes $d" "$d\n$d/abc\n" "" 0 "-e using code from -f" 81 | test_rawhide "$rh -e 1 -e 1 $d" "" "./rh: too many -e options\n" 1 "-e twice (not allowed)" 82 | 83 | test_rawhide "cat $d.conf | $rh -f- $d" "$d\n$d/abc\n" "" 0 "-f- ok but unused " 84 | test_rawhide "cat $d.conf | $rh -f- -f $d.conf2 $d" "$d\n$d/abc\n" "" 0 "-f- and -f (-f twice) (allowed)" 85 | test_rawhide "cat $d.conf | $rh -f- -f- $d" "" "./rh: invalid -f option argument: - (stdin can only be read once)\n" 1 "-f- twice (not allowed)" 86 | test_rawhide "cat $d.conf | $rh -f- -e yes $d" "$d\n$d/abc\n" "" 0 "-e using code from -f-" 87 | 88 | # Add a file test expression to the -f file (i.e. a stored default test) 89 | echo "(mode & IFMT) == IFDIR" >> $d.conf 90 | 91 | test_rawhide "$rh -f $d.conf $d" "$d\n" "" 0 "-f with stored default file test expression" 92 | test_rawhide "$rh -f $d.conf -e '(mode & IFMT) == IFREG' $d" "$d/abc\n" "" 0 "-f with stored default file test expression overridden by explicit -e" 93 | test_rawhide "$rh -f $d.conf '(mode & IFMT) == IFREG' $d" "$d/abc\n" "" 0 "-f with stored default file test expression overridden by implicit -e" 94 | test_rawhide "cat $d.conf | $rh -f - $d" "$d\n" "" 0 "-f- with stored default file test expression" 95 | test_rawhide "cat $d.conf | $rh -f - -e '(mode & IFMT) == IFREG' $d" "$d/abc\n" "" 0 "-f- with stored default file test expression overridden by explicit -e" 96 | test_rawhide "cat $d.conf | $rh -f - '(mode & IFMT) == IFREG' $d" "$d/abc\n" "" 0 "-f- with stored default file test expression overridden by implicit -e" 97 | 98 | mkdir $d.conf.d $d.conf2.d 99 | echo "f1 { 1 }" > $d.conf.d/a 100 | echo "f2 { f1 }" > $d.conf.d/b 101 | echo "f3 { f2 }" > $d.conf.d/c 102 | echo "f4 { f3 }" > $d.conf2.d/a 103 | echo "f5 { f4 }" > $d.conf2.d/b 104 | echo "f6 { f5 }" > $d.conf2.d/c 105 | test_rawhide "$rh -f $d.conf -f $d.conf2 f6 $d" "$d\n$d/abc\n" "" 0 "multiple -f with corresponding directories" 106 | test_rawhide "$rh -f $d.conf.d -f $d.conf2.d f6 $d" "$d\n$d/abc\n" "" 0 "multiple -f that are directories" 107 | rm $d.conf $d.conf2 108 | rm -rf $d.conf.d $d.conf2.d 109 | 110 | test_rawhide "$rh -e" "" "./rh: missing -e option argument (see ./rh -h for help)\n" 1 "-e with no argument" 111 | test_rawhide "$rh -f ''" "" "./rh: missing -f option argument (see ./rh -h for help)\n" 1 "-f with empty argument" 112 | test_rawhide "$rh -f" "" "./rh: missing -f option argument (see ./rh -h for help)\n" 1 "-f with no argument" 113 | 114 | if [ "`whoami`" != root ] 115 | then 116 | touch $d.conf 117 | chmod 000 $d.conf 118 | test_rawhide "$rh -f $d.conf" "" "./rh: $d.conf: Permission denied\n" 1 "-f with unreadable file" 119 | chmod 644 $d.conf 120 | rm $d.conf 121 | fi 122 | 123 | if [ -n "`command -v mkfifo`" ] && mkfifo $d.fifo >/dev/null 2>/dev/null 124 | then 125 | test_rawhide "$rh -f $d.fifo $d" "" "./rh: invalid -f option argument: $d.fifo (not a file or directory)\n" 1 "-f with non-file-or-directory" 126 | rm $d.fifo 127 | fi 128 | 129 | finish 130 | 131 | exit $errors 132 | 133 | # vi:set ts=4 sw=4: 134 | -------------------------------------------------------------------------------- /tests/t08: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="prune/trim" 28 | 29 | touch $d/good 30 | mkdir $d/.snapshot 31 | mkdir $d/.snapshot/bb 32 | touch $d/.snapshot/bb/111 33 | touch $d/.snapshot/bb/222 34 | mkdir $d/.snapshot/aaa 35 | touch $d/.snapshot/aaa/111 36 | touch $d/.snapshot/aaa/222 37 | touch $d/xxx 38 | touch $d/bad 39 | mkdir $d/thing 40 | touch $d/thing/other 41 | touch $d/blah~ 42 | touch $d/blah 43 | touch $d/grr 44 | touch $d/aaa 45 | mkdir $d/thing~ 46 | touch $d/thing~/ggg 47 | touch $d/thing~/fff 48 | 49 | test_rawhide_pre_hook() { test_rh_find_pre_hook; } 50 | 51 | test_rawhide_find "$rh -e '\".snapshot\" ? prune : !\"*~\"' $d" "find $d -name .snapshot -prune -o \( \! -name '*~' -print \)" "prune target but not siblings (?:)" 52 | test_rawhide_find "$rh -e '\".snapshot\" && prune || !\"*~\"' $d" "find $d -name .snapshot -prune -o \( \! -name '*~' -print \)" "prune target but not siblings (&& and ||)" 53 | 54 | test_rawhide_find "$rh -e '\".snapshot\" ? trim : !\"*~\"' $d" "find $d -name .snapshot -print -prune -o \( \! -name '*~' -print \)" "trim target but not siblings (?:)" 55 | test_rawhide_find "$rh -e '\".snapshot\" && trim || !\"*~\"' $d" "find $d -name .snapshot -print -prune -o \( \! -name '*~' -print \)" "trim target but not siblings (&& and ||)" 56 | 57 | finish 58 | 59 | exit $errors 60 | 61 | # vi:set ts=4 sw=4: 62 | -------------------------------------------------------------------------------- /tests/t09: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="exit" 28 | 29 | mkdir $d/aaa 30 | touch $d/aaa/111 31 | touch $d/aaa/222 32 | mkdir $d/bbb 33 | touch $d/bbb/111 34 | touch $d/bbb/222 35 | 36 | test_rawhide_pre_hook() { test_rh_find_pre_hook; } 37 | 38 | test_rawhide_find "$rh -e '\"111\"' $d" "find $d -name 111 -print" "without exit" 39 | 40 | case "`uname`" in 41 | OpenBSD|NetBSD|SunOS) # Find doesn't have -quit 42 | test_rawhide_pre_hook() { true; } 43 | first="`$rh -e '\"111\"' $d | head -1`" 44 | test_rawhide "$rh -e '\"111\" ? exit : 0' $d" "$first\n" "" 0 "with ? exit : 0" 45 | test_rawhide "$rh -e '\"111\" ? quit : 0' $d" "$first\n" "" 0 "with ? quit : 0" 46 | test_rawhide "$rh -e '\"111\" && exit' $d" "$first\n" "" 0 "with && exit" 47 | test_rawhide "$rh -e '\"111\" && quit' $d" "$first\n" "" 0 "with && quit" 48 | ;; 49 | *) 50 | test_rawhide_find "$rh -e '\"111\" ? exit : 0' $d" "find $d -name 111 -print -quit" "with ? exit : 0" 51 | test_rawhide_find "$rh -e '\"111\" && exit' $d" "find $d -name 111 -print -quit" "with && exit" 52 | test_rawhide_find "$rh -e '\"111\" && quit' $d" "find $d -name 111 -print -quit" "with && quit" 53 | ;; 54 | esac 55 | 56 | finish 57 | 58 | exit $errors 59 | 60 | # vi:set ts=4 sw=4: 61 | -------------------------------------------------------------------------------- /tests/t10: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="glob" 28 | 29 | touch $d/a.a 30 | touch $d/a.b 31 | touch $d/a.c 32 | touch $d/b.a 33 | touch $d/b.b 34 | touch $d/b.c 35 | touch $d/c.a 36 | touch $d/c.b 37 | touch $d/c.c 38 | touch $d/ba 39 | touch $d/bana 40 | touch $d/banana 41 | touch $d/bananana 42 | touch $d/ale 43 | touch $d/aple 44 | touch $d/apple 45 | touch $d/appple 46 | touch $d/pear 47 | 48 | test_rawhide_pre_hook() { test_rh_find_pre_hook; } 49 | 50 | case "`uname`" in 51 | SunOS) 52 | # Note: Solaris find incorrectly excludes .* for * 53 | test_rawhide_find "$rh -e '\"*\" && !\".*\"' $d" "find $d -name '*' -print" "*" 54 | test_rawhide_find "$rh -e '{*} && !{.*}' $d" "find $d -name '*' -print" "*" 55 | ;; 56 | *) 57 | test_rawhide_find "$rh -e '\"*\"' $d" "find $d -name '*' -print" "*" 58 | test_rawhide_find "$rh -e '{*}' $d" "find $d -name '*' -print" "*" 59 | esac 60 | 61 | test_rawhide_find "$rh -e '\"*.c\"' $d" "find $d -name '*.c' -print" "*.c" 62 | test_rawhide_find "$rh -e '\"*.*\"' $d" "find $d -name '*.*' -print" "*.*" 63 | test_rawhide_find "$rh -e '\"?.*\"' $d" "find $d -name '?.*' -print" "?.*" 64 | test_rawhide_find "$rh -e '\"*.?\"' $d" "find $d -name '*.?' -print" "*.?" 65 | test_rawhide_find "$rh -e '\"*.[ab]\"' $d" "find $d -name '*.[ab]' -print" "*.[ab]" 66 | test_rawhide_find "$rh -e '\"*.[!ab]\"' $d" "find $d -name '*.[!ab]' -print" "*.[!ab]" 67 | test_rawhide_find "$rh -e '\"*.[a-c]\"' $d" "find $d -name '*.[a-c]' -print" "*.[a-c]" 68 | test_rawhide_find "$rh -e '\".*\"' $d" "find $d -name '.*' -print" ".*" 69 | 70 | test_rawhide_find "$rh -e '{*.c}' $d" "find $d -name '*.c' -print" "*.c" 71 | test_rawhide_find "$rh -e '{*.*}' $d" "find $d -name '*.*' -print" "*.*" 72 | test_rawhide_find "$rh -e '{?.*}' $d" "find $d -name '?.*' -print" "?.*" 73 | test_rawhide_find "$rh -e '{*.?}' $d" "find $d -name '*.?' -print" "*.?" 74 | test_rawhide_find "$rh -e '{*.[ab]}' $d" "find $d -name '*.[ab]' -print" "*.[ab]" 75 | test_rawhide_find "$rh -e '{*.[!ab]}' $d" "find $d -name '*.[!ab]' -print" "*.[!ab]" 76 | test_rawhide_find "$rh -e '{*.[a-c]}' $d" "find $d -name '*.[a-c]' -print" "*.[a-c]" 77 | test_rawhide_find "$rh -e '{.*}' $d" "find $d -name '.*' -print" ".*" 78 | 79 | # Test ksh extglob (GNU extension to fnmatch) 80 | # GNU find doesn't do this so we can't compare against it so we have to sort stdout 81 | 82 | # '?(pattern-list)' zero or one occurrences of any of the patterns matches 83 | # '*(pattern-list)' zero or more occurrences of any of the patterns match 84 | # '+(pattern-list)' one of more occurrences of any of the patterns match 85 | # '@(pattern-list)' exactly one occurrence of any of the patterns match 86 | # '!(pattern-list)' input string cannot be matched with any of the patterns 87 | 88 | if [ x"`uname`" = xLinux ] && $rh -h | grep -q 'Ksh extended glob patterns' # Not musl 89 | then 90 | rh="$explicit_rh" 91 | test_rawhide_pre_hook() { test_rh_cd_pre_hook; } 92 | test_rawhide_post_hook() { test_rh_cd_post_hook; test_rh_sort_post_hook; } 93 | 94 | test_rawhide "$rh -e '\"?(*.a|*.c)\"' ." "./a.a\n./a.c\n./b.a\n./b.c\n./c.a\n./c.c\n" "" 0 "?(*.a|*.c)" 95 | test_rawhide "$rh -e '\"?(a.c|def)\"' ." "./a.c\n" "" 0 "?(a.c|def)" 96 | test_rawhide "$rh -e '\"!(*.a|*.c)\"' ." ".\n./a.b\n./ale\n./aple\n./apple\n./appple\n./b.b\n./ba\n./bana\n./banana\n./bananana\n./c.b\n./pear\n" "" 0 "!(*.a|*.c)" 97 | test_rawhide "$rh -e '\"@(ba*(na)|a+(p)le)\"' ." "./aple\n./apple\n./appple\n./ba\n./bana\n./banana\n./bananana\n" "" 0 "@(ba*(na)|a+(p)le)" 98 | 99 | test_rawhide "$rh -e '{?(*.a|*.c)}' ." "./a.a\n./a.c\n./b.a\n./b.c\n./c.a\n./c.c\n" "" 0 "?(*.a|*.c)" 100 | test_rawhide "$rh -e '{?(a.c|def)}' ." "./a.c\n" "" 0 "?(a.c|def)" 101 | test_rawhide "$rh -e '{!(*.a|*.c)}' ." ".\n./a.b\n./ale\n./aple\n./apple\n./appple\n./b.b\n./ba\n./bana\n./banana\n./bananana\n./c.b\n./pear\n" "" 0 "!(*.a|*.c)" 102 | test_rawhide "$rh -e '{@(ba*(na)|a+(p)le)}' ." "./aple\n./apple\n./appple\n./ba\n./bana\n./banana\n./bananana\n" "" 0 "@(ba*(na)|a+(p)le)" 103 | fi 104 | 105 | finish 106 | 107 | exit $errors 108 | 109 | # vi:set ts=4 sw=4: 110 | -------------------------------------------------------------------------------- /tests/t11: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="config file path buf size handling" 28 | 29 | RAWHIDE_TEST_TTY=1; export RAWHIDE_TEST_TTY # Exercise ok() and ok2() 30 | 31 | test_configpathbufsize() 32 | { 33 | max="$1" 34 | cmd="$2" 35 | expected_stdout="$3" 36 | expected_stderr="$4" 37 | expected_rc="$5" 38 | desc="$6" 39 | 40 | max="`expr $max - 1`" # Convert buf size to max length 41 | test_rawhide "RAWHIDE_TEST_PATHLEN_MAX=$max $cmd" "$expected_stdout" "$expected_stderr" "$expected_rc" "$desc" 42 | } 43 | 44 | # Where config buf size checks are: 45 | # 46 | # (#1) /etc/rawhide.conf [no longer, just used as is] 47 | # (#2) /etc/rawhide.conf.d 48 | # (#3)/etc/rawhide.conf.d/* 49 | # (#4) /etc/rawhide.conf.d/d_name [no longer, because they're real] 50 | # (#5) ~ 51 | # (#6) ~/.rhrc and $RAWHIDE_RC (separate checks) 52 | # (#7) ~/.rhrc.d 53 | # (#8) ~/.rhrc.d/* 54 | # (#9) ~/.rhrc.d/d_name [no longer, because they're real] 55 | 56 | mkdir tests/etc 57 | touch tests/etc/rawhide.conf # 23 58 | mkdir tests/etc/rawhide.conf.d # 25 59 | touch tests/etc/rawhide.conf.d/a # 27 60 | touch tests/etc/rawhide.conf.d/aa # 28 61 | touch tests/etc/rawhide.conf.d/aaa # 29 62 | touch tests/etc/rawhide.conf.d/aaaa # 30 63 | mkdir tests/home # 11 64 | touch tests/home/.rhrc # 17 65 | mkdir tests/home/.rhrc.d # 19 66 | touch tests/home/.rhrc.d/a # 21 67 | touch tests/home/.rhrc.d/aa # 22 68 | touch tests/home/.rhrc.d/aaa # 23 69 | touch tests/home/.rhrc.d/aaaa # 24 70 | 71 | # Note: root can't use $RAWHIDE_CONFIG or $RAWHIDE_RC so some tests aren't possible 72 | 73 | [ "`whoami`" = root ] && root=1 || root=0 74 | 75 | test_rawhide_grep "RAWHIDE_TEST_PATHLEN_MAX=2 ./rh $d 2>&1" "^\./rh: path is too long: (/.*/rawhide\.conf\.d|/.*/\.rhrc|$d)$" "" 1 "[2] too big - /etc/rawhide.conf (#2 was #1) - ~ (#5 and #6) without RAWHIDE_CONFIG or RAWHIDE_RC" 76 | 77 | if [ $root = 0 ] 78 | then 79 | rh="RAWHIDE_CONFIG=tests/etc/rawhide.conf RAWHIDE_RC=tests/home/.rhrc ./rh" 80 | test_configpathbufsize 10 "$rh $d" "" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc\n./rh: path is too long: $d\n" 1 "[10] too big - /etc/rawhide.conf (#2 was #1) - ~ (#5)" 81 | test_configpathbufsize 11 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc\n" 0 "[11] too big - /etc/rawhide.conf (#2 was #1) - ~/.rhrc (#6) - but search path buffer grows" 82 | test_configpathbufsize 16 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc\n" 0 "[16] too big - /etc/rawhide.conf (#2 was #1) - ~/.rhrc (#6)" 83 | test_configpathbufsize 17 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc.d\n" 0 "[17] too big - /etc/rawhide.conf (#2 was #1) - ~/.rhrc.d (#7)" 84 | test_configpathbufsize 18 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc.d\n" 0 "[18] too big - /etc/rawhide.conf (#2 was #1) - ~/.rhrc.d (#7)" 85 | test_configpathbufsize 19 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc.d/*\n" 0 "[19] too big - /etc/rawhide.conf (#2 was #1) - ~/.rhrc.d/* (#8)" 86 | test_configpathbufsize 20 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n./rh: path is too long: tests/home/.rhrc.d/*\n" 0 "[20] too big - /etc/rawhide.conf (#2 was #1) - ~/.rhrc.d/* (#8)" 87 | test_configpathbufsize 21 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n" 0 "[21] too big - /etc/rawhide.conf (#2 was #1) - but ~/.rhrc.d/aa aaa aaaa are real so ok (was #9)" 88 | test_configpathbufsize 22 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n" 0 "[22] too big - /etc/rawhide.conf (#2 was #1) - but ~/.rhrc.d/aaa aaaa are real so ok (was #9)" 89 | test_configpathbufsize 23 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n" 0 "[23] too big - /etc/rawhide.conf.d (#2) - but ~/.rhrc.d/aaaa are real so ok (was #9)" 90 | test_configpathbufsize 24 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d\n" 0 "[24] too big - /etc/rawhide.conf.d (#2)" 91 | test_configpathbufsize 26 "$rh $d" "$d\n" "./rh: path is too long: tests/etc/rawhide.conf.d/*\n" 0 "[26] too big - /etc/rawhide.conf.d/* (#3)" 92 | test_configpathbufsize 27 "$rh $d" "$d\n" "" 0 "[27] too big - but /etc/rawhide.conf.d/aa aaa aaaa are real so ok (was #4)" 93 | test_configpathbufsize 28 "$rh $d" "$d\n" "" 0 "[28] too big - but /etc/rawhide.conf.d/aaa aaaa are real so ok (was #4)" 94 | test_configpathbufsize 29 "$rh $d" "$d\n" "" 0 "[29] too big - but /etc/rawhide.conf.d/aaaa are real so ok (was #4)" 95 | test_configpathbufsize 30 "$rh $d" "$d\n" "" 0 "[30] max" 96 | test_configpathbufsize 31 "$rh $d" "$d\n" "" 0 "[31] small" 97 | fi 98 | 99 | rm -r tests/etc/rawhide.conf.d 100 | touch tests/etc/rawhide.conf.d 101 | rm -r tests/home/.rhrc.d 102 | touch tests/home/.rhrc.d 103 | 104 | [ $root = 0 ] && 105 | test_rawhide "$rh $d" "$d\n" "./rh: tests/etc/rawhide.conf.d is not a directory\n./rh: tests/home/.rhrc.d is not a directory\n" 0 "/etc/rawhide.conf.d and ~/.rhrc.d are not directories" 106 | 107 | rm tests/etc/rawhide.conf.d 108 | mkdir tests/etc/rawhide.conf.d 109 | mkdir tests/etc/rawhide.conf.d/dir 110 | rm tests/home/.rhrc.d 111 | mkdir tests/home/.rhrc.d 112 | mkdir tests/home/.rhrc.d/dir 113 | 114 | [ $root = 0 ] && 115 | test_rawhide "$rh $d" "$d\n" "./rh: tests/etc/rawhide.conf.d/dir is not a file\n./rh: tests/home/.rhrc.d/dir is not a file\n" 0 "/etc/rawhide.conf.d/dir and ~/.rhrc.d/dir are not files" 116 | 117 | rm -rf tests/etc tests/home 118 | 119 | # Above tests were for $RAWHIDE_RC. Need to test actual ~ and ~/.rhrc (but leave root's home directory alone) 120 | 121 | if [ $root = 0 -a ! -e ~/.rhrc -a ! -d ~/.rhrc.d ] 122 | then 123 | rh="./rh -N" 124 | touch ~/.rhrc 125 | home_size="`echo ~ | wc -c`" 126 | home_under_size="`expr $home_size - 1`" 127 | home_rhrc_size="`expr $home_size + 6`" 128 | home_rhrc_under_size="`expr $home_rhrc_size - 1`" 129 | if [ $home_under_size -le 10 ] 130 | then 131 | test_configpathbufsize $home_under_size "$rh $d" "" "./rh: path is too long: $HOME/.rhrc\n./rh: path is too long: $d\n" 1 "[$home_under_size] too big - real ~ (#6) - searchpath" 132 | else 133 | test_configpathbufsize $home_under_size "$rh $d" "$d\n" "./rh: path is too long: $HOME/.rhrc\n" 0 "[$home_under_size] too big - real ~ (#6)" 134 | fi 135 | test_configpathbufsize $home_rhrc_under_size "$rh $d" "$d\n" "./rh: path is too long: $HOME/.rhrc\n" 0 "[$home_under_size] too big - real ~/.rhrc (#6)" 136 | rm -rf ~/.rhrc 137 | fi 138 | 139 | finish 140 | 141 | exit $errors 142 | 143 | # vi:set ts=4 sw=4: 144 | -------------------------------------------------------------------------------- /tests/t14: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="config files" 28 | 29 | RAWHIDE_TEST_ETCDIR=tests/$t.etc 30 | RAWHIDE_CONFIG=$RAWHIDE_TEST_ETCDIR/rawhide.conf 31 | export RAWHIDE_CONFIG 32 | RAWHIDE_HOME=tests/$t.home 33 | export RAWHIDE_HOME 34 | RAWHIDE_RC=$RAWHIDE_HOME/.rhrc 35 | export RAWHIDE_RC 36 | 37 | # Note: root can't use $RAWHIDE_CONFIG or $RAWHIDE_RC so many of these tests aren't possible 38 | 39 | [ "`whoami`" = root ] && root=1 || root=0 40 | 41 | # Test with no config files or .d directories 42 | 43 | test_rawhide "./rh -e 1 $d" "$d\n" "" 0 "no config needed" 44 | test_rawhide "./rh -e home $d" "" "./rh: command line: -e 'home': line 1 byte 5: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "no config - func from ~/.rhrc undefined" 45 | test_rawhide "./rh -e homed $d" "" "./rh: command line: -e 'homed': line 1 byte 6: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "no config - func from ~/.rhrc.d/ undefined" 46 | test_rawhide "./rh -e etc $d" "" "./rh: command line: -e 'etc': line 1 byte 4: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "no config - func from /etc/rawhide.conf undefined" 47 | test_rawhide "./rh -e etcd $d" "" "./rh: command line: -e 'etcd': line 1 byte 5: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "no config - func from /etc/rawhide.conf.d/ undefined" 48 | 49 | # Test with config files but no .d directories 50 | 51 | mkdir $RAWHIDE_HOME 52 | mkdir $RAWHIDE_TEST_ETCDIR 53 | 54 | echo "home() { 1 }" > $RAWHIDE_RC 55 | echo "etc() { 1 }" > $RAWHIDE_CONFIG 56 | 57 | test_rawhide "./rh -e 1 $d" "$d\n" "" 0 "no config needed" 58 | [ $root = 0 ] && 59 | test_rawhide "./rh -e home $d" "$d\n" "" 0 "func from \$RAWHIDE_RC defined" 60 | [ $root = 1 ] && 61 | test_rawhide "./rh -e home $d" "" "./rh: command line: -e 'home': line 1 byte 5: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from \$RAWHIDE_RC undefined because root" 62 | test_rawhide "./rh -e homed $d" "" "./rh: command line: -e 'homed': line 1 byte 6: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from \$RAWHIDE_RC .d undefined" 63 | [ $root = 0 ] && 64 | test_rawhide "./rh -e etc $d" "$d\n" "" 0 "func from \$RAWHIDE_CONFIG defined" 65 | [ $root = 1 ] && 66 | test_rawhide "./rh -e etc $d" "" "./rh: command line: -e 'etc': line 1 byte 4: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from \$RAWHIDE_CONFIG undefined because root" 67 | test_rawhide "./rh -e etcd $d" "" "./rh: command line: -e 'etcd': line 1 byte 5: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from \$RAWHIDE_CONFIG .d undefined" 68 | 69 | # Test with config files and empty .d directories 70 | 71 | mkdir ${RAWHIDE_RC}.d 72 | mkdir ${RAWHIDE_CONFIG}.d 73 | 74 | test_rawhide "./rh -e 1 $d" "$d\n" "" 0 "no config needed" 75 | [ $root = 0 ] && 76 | test_rawhide "./rh -e home $d" "$d\n" "" 0 "func from ~/.rhrc defined" 77 | test_rawhide "./rh -e homed $d" "" "./rh: command line: -e 'homed': line 1 byte 6: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from ~/.rhrc.d/ undefined" 78 | [ $root = 0 ] && 79 | test_rawhide "./rh -e etc $d" "$d\n" "" 0 "func from /etc/rawhide.conf defined" 80 | test_rawhide "./rh -e etcd $d" "" "./rh: command line: -e 'etcd': line 1 byte 5: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from /etc/rawhide.conf.d/ undefined" 81 | 82 | # Test with config files and non-empty .d directories 83 | 84 | echo "homed1() { home }" > "${RAWHIDE_RC}.d/d1" 85 | echo "homed2() { homed1 }" > "${RAWHIDE_RC}.d/d2" 86 | echo "homed3() { homed2 }" > "${RAWHIDE_RC}.d/d3" 87 | echo "etcd1() { etc }" > "${RAWHIDE_CONFIG}.d/d1" 88 | echo "etcd2() { etcd1 }" > "${RAWHIDE_CONFIG}.d/d2" 89 | echo "etcd3() { etcd2 }" > "${RAWHIDE_CONFIG}.d/d3" 90 | 91 | test_rawhide "./rh -e 1 $d" "$d\n" "" 0 "no config needed" 92 | [ $root = 0 ] && 93 | test_rawhide "./rh -e home $d" "$d\n" "" 0 "func from ~/.rhrc defined" 94 | [ $root = 0 ] && 95 | test_rawhide "./rh -e homed1 $d" "$d\n" "" 0 "func from ~/.rhrc.d/d1 defined" 96 | [ $root = 0 ] && 97 | test_rawhide "./rh -e homed2 $d" "$d\n" "" 0 "func from ~/.rhrc.d/d2 defined" 98 | [ $root = 0 ] && 99 | test_rawhide "./rh -e homed3 $d" "$d\n" "" 0 "func from ~/.rhrc.d/d3 defined" 100 | [ $root = 0 ] && 101 | test_rawhide "./rh -e etc $d" "$d\n" "" 0 "func from /etc/rawhide.conf defined" 102 | [ $root = 0 ] && 103 | test_rawhide "./rh -e etcd1 $d" "$d\n" "" 0 "func from /etc/rawhide.conf.d/d1 defined" 104 | [ $root = 0 ] && 105 | test_rawhide "./rh -e etcd2 $d" "$d\n" "" 0 "func from /etc/rawhide.conf.d/d2 defined" 106 | [ $root = 0 ] && 107 | test_rawhide "./rh -e etcd3 $d" "$d\n" "" 0 "func from /etc/rawhide.conf.d/d3 defined" 108 | 109 | # Test with no config files but with non-empty .d directories but broken deps 110 | 111 | rm $RAWHIDE_RC 112 | rm $RAWHIDE_CONFIG 113 | 114 | [ $root = 0 ] && 115 | test_rawhide "./rh -e 1 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "no config needed (broken deps in config)" 116 | [ $root = 0 ] && 117 | test_rawhide "./rh -e home $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from ~/.rhrc undefined (broken deps in config)" 118 | [ $root = 0 ] && 119 | test_rawhide "./rh -e homed1 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from ~/.rhrc.d/d1 defined (broken deps in config)" 120 | [ $root = 0 ] && 121 | test_rawhide "./rh -e homed2 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from ~/.rhrc.d/d2 defined (broken deps in config)" 122 | [ $root = 0 ] && 123 | test_rawhide "./rh -e homed3 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from ~/.rhrc.d/d3 defined (broken deps in config)" 124 | [ $root = 0 ] && 125 | test_rawhide "./rh -e etc $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from /etc/rawhide.conf undefined (broken deps in config)" 126 | [ $root = 0 ] && 127 | test_rawhide "./rh -e etcd1 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from /etc/rawhide.conf.d/d1 defined (broken deps in config)" 128 | [ $root = 0 ] && 129 | test_rawhide "./rh -e etcd2 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from /etc/rawhide.conf.d/d2 defined (broken deps in config)" 130 | [ $root = 0 ] && 131 | test_rawhide "./rh -e etcd3 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "func from /etc/rawhide.conf.d/d3 defined (broken deps in config)" 132 | 133 | # Test -N and -n separately and together 134 | 135 | [ $root = 0 ] && 136 | test_rawhide "./rh -N -e 1 $d" "" "./rh: tests/t14.home/.rhrc.d/d1: line 1 byte 15: undefined identifier: identifier home\n" 1 "no config needed - broken deps - exclude etc - still broken" 137 | [ $root = 0 ] && 138 | test_rawhide "./rh -n -e 1 $d" "" "./rh: tests/t14.etc/rawhide.conf.d/d1: line 1 byte 13: undefined identifier: identifier etc\n" 1 "no config needed - broken deps - exclude home - still broken" 139 | test_rawhide "./rh -Nn -e 1 $d" "$d\n" "" 0 "no config needed - broken deps - exclude home and etc - ok" 140 | 141 | # Test with no config files but with non-empty .d directories but no broken deps 142 | 143 | echo "homed1() { 1 }" > "${RAWHIDE_RC}.d/d1" 144 | echo "homed2() { homed1 }" > "${RAWHIDE_RC}.d/d2" 145 | echo "homed3() { homed2 }" > "${RAWHIDE_RC}.d/d3" 146 | echo "etcd1() { 1 }" > "${RAWHIDE_CONFIG}.d/d1" 147 | echo "etcd2() { etcd1 }" > "${RAWHIDE_CONFIG}.d/d2" 148 | echo "etcd3() { etcd2 }" > "${RAWHIDE_CONFIG}.d/d3" 149 | 150 | test_rawhide "./rh -e 1 $d" "$d\n" "" 0 "no config needed" 151 | test_rawhide "./rh -e home $d" "" "./rh: command line: -e 'home': line 1 byte 5: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from ~/.rhrc undefined" 152 | [ $root = 0 ] && 153 | test_rawhide "./rh -e homed1 $d" "$d\n" "" 0 "func from ~/.rhrc.d/d1 defined and no broken deps" 154 | [ $root = 0 ] && 155 | test_rawhide "./rh -e homed2 $d" "$d\n" "" 0 "func from ~/.rhrc.d/d2 defined and no broken deps" 156 | [ $root = 0 ] && 157 | test_rawhide "./rh -e homed3 $d" "$d\n" "" 0 "func from ~/.rhrc.d/d3 defined and no broken deps" 158 | test_rawhide "./rh -e etc $d" "" "./rh: command line: -e 'etc': line 1 byte 4: expected '(' or '{', found eof (possible attempt to call an undefined function)\n" 1 "func from /etc/rawhide.conf undefined" 159 | [ $root = 0 ] && 160 | test_rawhide "./rh -e etcd1 $d" "$d\n" "" 0 "func from /etc/rawhide.conf.d/d1 defined and no broken deps" 161 | [ $root = 0 ] && 162 | test_rawhide "./rh -e etcd2 $d" "$d\n" "" 0 "func from /etc/rawhide.conf.d/d2 defined and no broken deps" 163 | [ $root = 0 ] && 164 | test_rawhide "./rh -e etcd3 $d" "$d\n" "" 0 "func from /etc/rawhide.conf.d/d3 defined and no broken deps" 165 | 166 | rm -rf $RAWHIDE_TEST_ETCDIR 167 | rm -rf $RAWHIDE_HOME 168 | finish 169 | 170 | exit $errors 171 | 172 | # vi:set ts=4 sw=4: 173 | -------------------------------------------------------------------------------- /tests/t16: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-r, -m and -M options" 28 | 29 | mkdir $d/d1-a 30 | mkdir $d/d1-a/d2-a.a 31 | mkdir $d/d1-a/d2-a.a/d3-a.a.a 32 | mkdir $d/d1-a/d2-a.a/d3-a.a.b 33 | mkdir $d/d1-a/d2-a.a/d3-a.a.c 34 | mkdir $d/d1-a/d2-a.b 35 | mkdir $d/d1-a/d2-a.b/d3-a.b.a 36 | mkdir $d/d1-a/d2-a.b/d3-a.b.b 37 | mkdir $d/d1-a/d2-a.b/d3-a.b.c 38 | mkdir $d/d1-a/d2-a.c 39 | mkdir $d/d1-a/d2-a.c/d3-a.c.a 40 | mkdir $d/d1-a/d2-a.c/d3-a.c.b 41 | mkdir $d/d1-a/d2-a.c/d3-a.c.c 42 | 43 | mkdir $d/d1-b 44 | mkdir $d/d1-b/d2-b.a 45 | mkdir $d/d1-b/d2-b.a/d3-b.a.a 46 | mkdir $d/d1-b/d2-b.a/d3-b.a.b 47 | mkdir $d/d1-b/d2-b.a/d3-b.a.c 48 | mkdir $d/d1-b/d2-b.b 49 | mkdir $d/d1-b/d2-b.b/d3-b.b.a 50 | mkdir $d/d1-b/d2-b.b/d3-b.b.b 51 | mkdir $d/d1-b/d2-b.b/d3-b.b.c 52 | mkdir $d/d1-b/d2-b.c 53 | mkdir $d/d1-b/d2-b.c/d3-b.c.a 54 | mkdir $d/d1-b/d2-b.c/d3-b.c.b 55 | mkdir $d/d1-b/d2-b.c/d3-b.c.c 56 | 57 | mkdir $d/d1-c 58 | mkdir $d/d1-c/d2-c.a 59 | mkdir $d/d1-c/d2-c.a/d3-c.a.a 60 | mkdir $d/d1-c/d2-c.a/d3-c.a.b 61 | mkdir $d/d1-c/d2-c.a/d3-c.a.c 62 | mkdir $d/d1-c/d2-c.b 63 | mkdir $d/d1-c/d2-c.b/d3-c.b.a 64 | mkdir $d/d1-c/d2-c.b/d3-c.b.b 65 | mkdir $d/d1-c/d2-c.b/d3-c.b.c 66 | mkdir $d/d1-c/d2-c.c 67 | mkdir $d/d1-c/d2-c.c/d3-c.c.a 68 | mkdir $d/d1-c/d2-c.c/d3-c.c.b 69 | mkdir $d/d1-c/d2-c.c/d3-c.c.c 70 | 71 | # Where possible (not Solaris), compare depth numbers with find's -mindepth -maxdepth 72 | if find_has_mindepth 73 | then 74 | test_rawhide_pre_hook() { test_rh_find_pre_hook; } 75 | 76 | test_rawhide_find "$rh $d" "find $d" "no depth restriction" 77 | test_rawhide_find "$rh -r $d" "find $d -mindepth 1 -maxdepth 1" "-r" 78 | 79 | test_rawhide_find "$rh -m0 $d" "find $d -mindepth 0" "-m0" 80 | test_rawhide_find "$rh -m1 $d" "find $d -mindepth 1" "-m1" 81 | test_rawhide_find "$rh -m2 $d" "find $d -mindepth 2" "-m2" 82 | test_rawhide_find "$rh -m3 $d" "find $d -mindepth 3" "-m3" 83 | test_rawhide_find "$rh -m4 $d" "find $d -mindepth 4" "-m4" 84 | 85 | test_rawhide_find "$rh -M0 $d" "find $d -maxdepth 0" "-M0" 86 | test_rawhide_find "$rh -M1 $d" "find $d -maxdepth 1" "-M1" 87 | test_rawhide_find "$rh -M2 $d" "find $d -maxdepth 2" "-M2" 88 | test_rawhide_find "$rh -M3 $d" "find $d -maxdepth 3" "-M3" 89 | test_rawhide_find "$rh -M4 $d" "find $d -maxdepth 4" "-M4" 90 | 91 | test_rawhide_find "$rh -m0 -M0 $d" "find $d -mindepth 0 -maxdepth 0" "-m0 -M0" 92 | test_rawhide_find "$rh -m1 -M1 $d" "find $d -mindepth 1 -maxdepth 1" "-m1 -M1" 93 | test_rawhide_find "$rh -m2 -M2 $d" "find $d -mindepth 2 -maxdepth 2" "-m2 -M2" 94 | test_rawhide_find "$rh -m3 -M3 $d" "find $d -mindepth 3 -maxdepth 3" "-m3 -M3" 95 | test_rawhide_find "$rh -m4 -M4 $d" "find $d -mindepth 4 -maxdepth 4" "-m4 -M4" 96 | 97 | test_rawhide_find "$rh -m0 -M1 $d" "find $d -mindepth 0 -maxdepth 1" "-m0 -M1" 98 | test_rawhide_find "$rh -m1 -M2 $d" "find $d -mindepth 1 -maxdepth 2" "-m1 -M2" 99 | test_rawhide_find "$rh -m2 -M3 $d" "find $d -mindepth 2 -maxdepth 3" "-m2 -M3" 100 | test_rawhide_find "$rh -m3 -M4 $d" "find $d -mindepth 3 -maxdepth 4" "-m3 -M4" 101 | test_rawhide_find "$rh -m4 -M5 $d" "find $d -mindepth 4 -maxdepth 5" "-m4 -M5" 102 | 103 | test_rawhide_find "$rh -m0 -M2 $d" "find $d -mindepth 0 -maxdepth 2" "-m0 -M2" 104 | test_rawhide_find "$rh -m1 -M3 $d" "find $d -mindepth 1 -maxdepth 3" "-m1 -M3" 105 | test_rawhide_find "$rh -m2 -M4 $d" "find $d -mindepth 2 -maxdepth 4" "-m2 -M4" 106 | test_rawhide_find "$rh -m3 -M5 $d" "find $d -mindepth 3 -maxdepth 5" "-m3 -M5" 107 | test_rawhide_find "$rh -m4 -M6 $d" "find $d -mindepth 4 -maxdepth 6" "-m4 -M6" 108 | 109 | test_rawhide_pre_hook() { true; } 110 | fi 111 | 112 | # Solaris find can't do -mindepth -maxdepth and order isn't fixed, so can't test when any siblings 113 | rm -rf $d/d1-* 114 | mkdir $d/d1 115 | mkdir $d/d1/d2 116 | mkdir $d/d1/d2/d3 117 | 118 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "no depth restriction" 119 | test_rawhide "$rh -r $d" "$d/d1\n" "" 0 "-r" 120 | 121 | test_rawhide "$rh -m0 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-m0" 122 | test_rawhide "$rh -m1 $d" "$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-m1" 123 | test_rawhide "$rh -m2 $d" "$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-m2" 124 | test_rawhide "$rh -m3 $d" "$d/d1/d2/d3\n" "" 0 "-m3" 125 | test_rawhide "$rh -m4 $d" "" "" 0 "-m4" 126 | 127 | test_rawhide "$rh -M0 $d" "$d\n" "" 0 "-M0" 128 | test_rawhide "$rh -M1 $d" "$d\n$d/d1\n" "" 0 "-M1" 129 | test_rawhide "$rh -M2 $d" "$d\n$d/d1\n$d/d1/d2\n" "" 0 "-M2" 130 | test_rawhide "$rh -M3 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-M3" 131 | test_rawhide "$rh -M4 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-M4" 132 | 133 | test_rawhide "$rh -m0 -M0 $d" "$d\n" "" 0 "-m0 -M0" 134 | test_rawhide "$rh -m1 -M1 $d" "$d/d1\n" "" 0 "-m1 -M1" 135 | test_rawhide "$rh -m2 -M2 $d" "$d/d1/d2\n" "" 0 "-m2 -M2" 136 | test_rawhide "$rh -m3 -M3 $d" "$d/d1/d2/d3\n" "" 0 "-m3 -M3" 137 | test_rawhide "$rh -m4 -M4 $d" "" "" 0 "-m4 -M4" 138 | 139 | test_rawhide "$rh -m0 -M1 $d" "$d\n$d/d1\n" "" 0 "-m0 -M1" 140 | test_rawhide "$rh -m1 -M2 $d" "$d/d1\n$d/d1/d2\n" "" 0 "-m1 -M2" 141 | test_rawhide "$rh -m2 -M3 $d" "$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-m2 -M3" 142 | test_rawhide "$rh -m3 -M4 $d" "$d/d1/d2/d3\n" "" 0 "-m3 -M4" 143 | test_rawhide "$rh -m4 -M5 $d" "" "" 0 "-m4 -M5" 144 | 145 | test_rawhide "$rh -m0 -M2 $d" "$d\n$d/d1\n$d/d1/d2\n" "" 0 "-m0 -M2" 146 | test_rawhide "$rh -m1 -M3 $d" "$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-m1 -M3" 147 | test_rawhide "$rh -m2 -M4 $d" "$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-m2 -M4" 148 | test_rawhide "$rh -m3 -M5 $d" "$d/d1/d2/d3\n" "" 0 "-m3 -M5" 149 | test_rawhide "$rh -m4 -M6 $d" "" "" 0 "-m4 -M6" 150 | 151 | test_rawhide "$rh -m1 -r $d" "" "./rh: -r and -m options are mutually exclusive\n" 1 "-m1 -r (-m and -r invalid)" 152 | test_rawhide "$rh -M1 -r $d" "" "./rh: -r and -M options are mutually exclusive\n" 1 "-M1 -r (-M and -r invalid)" 153 | 154 | test_rawhide "$rh -m -3 $d" "" "./rh: invalid -m option argument: -3 (must be a non-negative integer)\n" 1 "invalid -m (negative)" 155 | test_rawhide "$rh -M -3 $d" "" "./rh: invalid -M option argument: -3 (must be a non-negative integer)\n" 1 "invalid -M (negative)" 156 | test_rawhide "$rh -m garble $d" "" "./rh: invalid -m option argument: garble (must be a non-negative integer)\n" 1 "invalid -m (not a number)" 157 | test_rawhide "$rh -M garble $d" "" "./rh: invalid -M option argument: garble (must be a non-negative integer)\n" 1 "invalid -M (not a number)" 158 | test_rawhide "$rh -m '' $d" "" "./rh: missing -m option argument (see ./rh -h for help)\n" 1 "invalid -m (empty arg)" 159 | test_rawhide "$rh -M '' $d" "" "./rh: missing -M option argument (see ./rh -h for help)\n" 1 "invalid -M (empty arg)" 160 | test_rawhide "$rh -m" "" "./rh: missing -m option argument (see ./rh -h for help)\n" 1 "invalid -m (no arg)" 161 | test_rawhide "$rh -M" "" "./rh: missing -M option argument (see ./rh -h for help)\n" 1 "invalid -M (no arg)" 162 | 163 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=3 $rh -m 5 $d" "" "./rh: invalid -m option argument: 5 (must be no more than 4)\n" 1 "invalid -m (more than depth limit)" 164 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=3 $rh -M 5 $d" "" "./rh: invalid -M option argument: 5 (must be no more than 4)\n" 1 "invalid -M (more than depth limit)" 165 | 166 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=3 $rh -m 4 $d" "" "./rh: too many directory levels: $d/d1/d2/d3\n" 1 "valid -m (depth limit + 1 - ok - to show runtime error)" 167 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=3 $rh -M 4 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "./rh: too many directory levels: $d/d1/d2/d3\n" 1 "valid -M (depth limit + 1 - ok - to show runtime error)" 168 | 169 | finish 170 | 171 | exit $errors 172 | 173 | # vi:set ts=4 sw=4: 174 | -------------------------------------------------------------------------------- /tests/t17: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="traversal error reporting (stderr and exit status)" 28 | 29 | mkdir $d/d1 30 | mkdir $d/d1/d2 31 | mkdir $d/d1/d2/d3 32 | mkdir $d/d1/d2/d3/d4 33 | 34 | # Test "too many directory levels" 35 | 36 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=1 $rh $d" "$d\n$d/d1\n" "./rh: too many directory levels: $d/d1\n" 1 "reached system depth limit 1" 37 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=2 $rh $d" "$d\n$d/d1\n$d/d1/d2\n" "./rh: too many directory levels: $d/d1/d2\n" 1 "reached system depth limit 2" 38 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=3 $rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "./rh: too many directory levels: $d/d1/d2/d3\n" 1 "reached system depth limit 3" 39 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=4 $rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "./rh: too many directory levels: $d/d1/d2/d3/d4\n" 1 "reached system depth limit 4" 40 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=5 $rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "" 0 "not reached system depth limit 5" 41 | 42 | # Test just enough 43 | 44 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=1 $rh -M1 $d" "$d\n$d/d1\n" "" 0 "not reached system depth limit 1" 45 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=2 $rh -M2 $d" "$d\n$d/d1\n$d/d1/d2\n" "" 0 "not reached system depth limit 2" 46 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=3 $rh -M3 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "not reached system depth limit 3" 47 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=4 $rh -M4 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "" 0 "not reached system depth limit 4" 48 | test_rawhide "RAWHIDE_TEST_DEPTH_LIMIT=5 $rh -M5 $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "" 0 "not reached system depth limit 5" 49 | 50 | # Test fstatat messages 51 | 52 | test_rawhide_post_hook() { test_rh_errno_post_hook; } 53 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=$d $rh $d" "" "./rh: fstatat $d: Operation not permitted\n" 1 "fstatat failure $d/" 54 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=$d/d1 $rh $d" "$d\n" "./rh: fstatat $d/d1: Operation not permitted\n" 1 "fstatat failure $d/d1" 55 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=$d/d1/d2 $rh $d" "$d\n$d/d1\n" "./rh: fstatat $d/d1/d2: Operation not permitted\n" 1 "fstatat failure $d/d1/d2" 56 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=$d/d1/d2/d3 $rh $d" "$d\n$d/d1\n$d/d1/d2\n" "./rh: fstatat $d/d1/d2/d3: Operation not permitted\n" 1 "fstatat failure $d/d1/d2/d3" 57 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=$d/d1/d2/d3/d4 $rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "./rh: fstatat $d/d1/d2/d3/d4: Operation not permitted\n" 1 "fstatat failure $d/d1/d2/d3/d4" 58 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=. $rh" "" "./rh: fstatat .: Operation not permitted\n" 1 "fstatat . (default) failure (just for coverage)" 59 | test_rawhide_post_hook() { true; } 60 | 61 | # For "stack overflow", see tests/t12 (parser error messages) 62 | # For "path is too long" see tests/t03 (path buf size handling) 63 | 64 | # Test opendir 65 | 66 | if [ "`whoami`" != root ] 67 | then 68 | chmod 000 $d/d1/d2/d3/d4 69 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "./rh: $d/d1/d2/d3/d4: Permission denied\n" 1 "openat permission error 1" 70 | chmod 755 $d/d1/d2/d3/d4 71 | 72 | chmod 000 $d/d1/d2/d3 73 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "./rh: $d/d1/d2/d3: Permission denied\n" 1 "openat permission error 2" 74 | chmod 755 $d/d1/d2/d3 75 | fi 76 | 77 | finish 78 | 79 | exit $errors 80 | 81 | # vi:set ts=4 sw=4: 82 | -------------------------------------------------------------------------------- /tests/t18: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="fstatat/openat/fdopendir/fchdir/chdir/readlinkat syscall errors" 28 | 29 | mkdir $d/d1 30 | mkdir $d/d1/d2 31 | 32 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n" "" 0 "no syscall failure" 33 | test_rawhide_post_hook() { test_rh_errno_post_hook; } 34 | test_rawhide "RAWHIDE_TEST_FSTATAT_FAILURE=$d $rh $d" "" "./rh: fstatat $d: Operation not permitted\n" 1 "simulate fstatat failure" 35 | test_rawhide "RAWHIDE_TEST_OPENAT_FAILURE=1 $rh $d" "$d\n" "./rh: $d: Operation not permitted\n" 1 "simulate openat failure" 36 | test_rawhide "RAWHIDE_TEST_FDOPENDIR_FAILURE=1 $rh $d" "$d\n" "./rh: fdopendir $d: Operation not permitted\n" 1 "simulate fdopendir failure" 37 | test_rawhide "RAWHIDE_TEST_CHDIR_FAILURE=1 $rh -X 'echo %s' $d" "" "./rh: chdir tests: Operation not permitted\n" 1 "simulate chdir failure" 38 | test_rawhide "RAWHIDE_TEST_FCHDIR_FAILURE=1 $rh -X 'echo %s' $d" "$d\n" "./rh: fchdir $d: Operation not permitted\n" 1 "simulate fchdir failure" 39 | ln -s d1 $d/link 40 | test_rawhide_grep "RAWHIDE_TEST_READLINKAT_FAILURE=1 $rh -l $d/link" "^.*$" "./rh: readlinkat $d/link: Operation not permitted\n" 1 "simulate readlinkat failure (just for coverage)" 41 | test_rawhide_grep "RAWHIDE_TEST_READLINKAT_TOO_LONG_FAILURE=1 $rh -l $d/link" "^.*$" "./rh: readlinkat $d/link: target is too long\n" 1 "simulate readlinkat too long (just for coverage)" 42 | test_rawhide_grep "RAWHIDE_TEST_READLINKAT_FAILURE=1 $rh -l '\"*\".link' $d/link" "^.*$" "./rh: readlinkat $d/link: Operation not permitted\n" 1 "simulate readlinkat failure (just for coverage)" 43 | test_rawhide_grep "RAWHIDE_TEST_READLINKAT_TOO_LONG_FAILURE=1 $rh -l '\"*\".link' $d/link" "^.*$" "./rh: readlinkat $d/link: target is too long\n" 1 "simulate readlinkat too long (just for coverage)" 44 | rm $d/link 45 | test_rawhide_post_hook() { true; } 46 | 47 | finish 48 | 49 | exit $errors 50 | 51 | # vi:set ts=4 sw=4: 52 | -------------------------------------------------------------------------------- /tests/t20: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="cmdline option errors" 28 | 29 | # For -m -M see tests/t16 30 | # For -e -f see tests/t07 31 | 32 | test_rawhide "$rh -x 'echo 1' -x 'echo 2' $d" "" "./rh: too many -x options\n" 1 "too many -x options" 33 | test_rawhide "$rh -X 'echo 1' -X 'echo 2' $d" "" "./rh: too many -X options\n" 1 "too many -X options" 34 | test_rawhide "$rh -x 'echo 1' -X 'echo 2' $d" "" "./rh: -x and -X options are mutually exclusive\n" 1 "-x and -X options are mutually exclusive" 35 | test_rawhide "$rh -X 'echo 1' -x 'echo 2' $d" "" "./rh: -x and -X options are mutually exclusive\n" 1 "-x and -X options are mutually exclusive" 36 | test_rawhide "$rh -L '%f\n' -L '%p\n' $d" "" "./rh: too many -L or -j options\n" 1 "too many -L or -j options" 37 | test_rawhide "$rh -L '%f\n' -j $d" "" "./rh: too many -L or -j options\n" 1 "too many -L or -j options" 38 | test_rawhide "$rh -j -L '%p\n' $d" "" "./rh: too many -L or -j options\n" 1 "too many -L or -j options" 39 | test_rawhide "$rh -j -j $d" "" "./rh: too many -L or -j options\n" 1 "too many -L or -j options" 40 | test_rawhide "$rh -? '' $d" "" "./rh: missing -? option argument (see ./rh -h for help)\n" 1 "missing -? option argument" 41 | test_rawhide "$rh -? 'wrong' $d" "" "./rh: invalid -? option argument: wrong (needs: cmdline parser traversal exec all extra)\n" 1 "-? wrong [OK to fail when NDEBUG]" 42 | test_rawhide "$rh -x 'echo 1' -l $d" "" "./rh: -x and -l options are mutually exclusive\n" 1 "-x and -l options are mutually exclusive" 43 | test_rawhide "$rh -l -x 'echo 1' $d" "" "./rh: -x and -l options are mutually exclusive\n" 1 "-x and -l options are mutually exclusive" 44 | test_rawhide "$rh -X 'echo 1' -l $d" "" "./rh: -X and -l options are mutually exclusive\n" 1 "-X and -l options are mutually exclusive" 45 | test_rawhide "$rh -l -X 'echo 1' $d" "" "./rh: -X and -l options are mutually exclusive\n" 1 "-X and -l options are mutually exclusive" 46 | test_rawhide "$rh -x 'echo 1' -0 $d" "" "./rh: -x and -0 options are mutually exclusive\n" 1 "-x and -0 options are mutually exclusive" 47 | test_rawhide "$rh -0 -x 'echo 1' $d" "" "./rh: -x and -0 options are mutually exclusive\n" 1 "-x and -0 options are mutually exclusive" 48 | test_rawhide "$rh -X 'echo 1' -0 $d" "" "./rh: -X and -0 options are mutually exclusive\n" 1 "-X and -0 options are mutually exclusive" 49 | test_rawhide "$rh -0 -X 'echo 1' $d" "" "./rh: -X and -0 options are mutually exclusive\n" 1 "-X and -0 options are mutually exclusive" 50 | test_rawhide "$rh -l -0 $d" "" "./rh: -l and -0 options are mutually exclusive\n" 1 "-l and -0 options are mutually exclusive" 51 | test_rawhide "$rh -0 -l $d" "" "./rh: -l and -0 options are mutually exclusive\n" 1 "-l and -0 options are mutually exclusive" 52 | 53 | test_rawhide "$rh -U $d" "" "./rh: -U option only works if supplied three times\n" 1 "-U only once" 54 | test_rawhide "$rh -UU $d" "" "./rh: -U option only works if supplied three times\n" 1 "-U only twice" 55 | test_rawhide "$rh -UUU -x echo $d" "" "./rh: -x and -U options are mutually exclusive\n" 1 "-U and -x" 56 | test_rawhide "$rh -UUU -X echo $d" "" "./rh: -X and -U options are mutually exclusive\n" 1 "-U and -X" 57 | test_rawhide "$rh -UUU -l $d" "" "./rh: -l and -U options are mutually exclusive\n" 1 "-U and -l" 58 | test_rawhide "$rh -UUU -0 $d" "" "./rh: -0 and -U options are mutually exclusive\n" 1 "-U and -0" 59 | 60 | test_rawhide "$rh -E -q $d" "" "./rh: -E/-b and -q options are mutually exclusive\n" 1 "-E and -q" 61 | test_rawhide "$rh -H -I $d" "" "./rh: -H and -I options are mutually exclusive\n" 1 "-E and -q" 62 | 63 | test_rawhide "$rh -L" "" "./rh: missing -L option argument (see ./rh -h for help)\n" 1 "missing -L option argument" 64 | test_rawhide "$rh -L '' $d" "" "" 0 "empty -L option argument" 65 | test_rawhide "$rh -x 'echo 1' -L '%b' $d" "" "./rh: -x and -L/-j options are mutually exclusive\n" 1 "-x and -L/j options are mutually exclusive" 66 | test_rawhide "$rh -L '%b' -x 'echo 1' $d" "" "./rh: -x and -L/-j options are mutually exclusive\n" 1 "-x and -L/j options are mutually exclusive" 67 | test_rawhide "$rh -X 'echo 1' -L '%b' $d" "" "./rh: -X and -L/-j options are mutually exclusive\n" 1 "-X and -L/j options are mutually exclusive" 68 | test_rawhide "$rh -L '%b' -X 'echo 1' $d" "" "./rh: -X and -L/-j options are mutually exclusive\n" 1 "-X and -L/j options are mutually exclusive" 69 | test_rawhide "$rh -x 'echo 1' -j $d" "" "./rh: -x and -L/-j options are mutually exclusive\n" 1 "-x and -L/j options are mutually exclusive" 70 | test_rawhide "$rh -j -x 'echo 1' $d" "" "./rh: -x and -L/-j options are mutually exclusive\n" 1 "-x and -L/j options are mutually exclusive" 71 | test_rawhide "$rh -X 'echo 1' -j $d" "" "./rh: -X and -L/-j options are mutually exclusive\n" 1 "-X and -L/j options are mutually exclusive" 72 | test_rawhide "$rh -j -X 'echo 1' $d" "" "./rh: -X and -L/-j options are mutually exclusive\n" 1 "-X and -L/j options are mutually exclusive" 73 | test_rawhide "$rh -L '%b' -0 $d" "" "./rh: -0 and -L/-j options are mutually exclusive\n" 1 "-L and -0 options are mutually exclusive" 74 | test_rawhide "$rh -0 -L '%b' $d" "" "./rh: -0 and -L/-j options are mutually exclusive\n" 1 "-L and -0 options are mutually exclusive" 75 | test_rawhide "$rh -L '%b' -UUU $d" "" "./rh: -U and -L/-j options are mutually exclusive\n" 1 "-U and -L" 76 | test_rawhide "$rh -UUU -L '%b' $d" "" "./rh: -U and -L/-j options are mutually exclusive\n" 1 "-U and -L" 77 | test_rawhide "$rh -L '%b' -l $d" "" "./rh: -l and -L/-j options are mutually exclusive\n" 1 "-l and -L" 78 | test_rawhide "$rh -l -L '%b' $d" "" "./rh: -l and -L/-j options are mutually exclusive\n" 1 "-l and -L" 79 | 80 | test_rawhide "$rh -r -M 0 $d" "" "./rh: -r and -M options are mutually exclusive\n" 1 "-r and -M" 81 | 82 | if [ "`whoami`" != root -a -e /etc/shadow ] 83 | then 84 | test_rawhide "RAWHIDE_CONFIG=/etc/shadow ./rh -n $d" "$d\n" "./rh: /etc/shadow: Permission denied\n" 0 "unreadable RAWHIDE_CONF" 85 | test_rawhide "RAWHIDE_RC=/etc/shadow ./rh -N $d" "$d\n" "./rh: /etc/shadow: Permission denied\n" 0 "unreadable RAWHIDE_RC" 86 | fi 87 | 88 | finish 89 | 90 | exit $errors 91 | 92 | # vi:set ts=4 sw=4: 93 | -------------------------------------------------------------------------------- /tests/t21: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-D and -U options" 28 | 29 | mkdir $d/d1 30 | mkdir $d/d1/d2 31 | mkdir $d/d1/d2/d3 32 | touch $d/d1/d2/d3/d4 33 | 34 | # Solaris find can't do -mindepth -maxdepth, so test explicitly 35 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "" 0 "without -D option" 36 | test_rawhide "$rh -D $d" "$d/d1/d2/d3/d4\n$d/d1/d2/d3\n$d/d1/d2\n$d/d1\n$d\n" "" 0 "with -D option" 37 | test_rawhide "$rh -D -M0 $d" "$d\n" "" 0 "-D and -M0" 38 | test_rawhide "$rh -D -M1 $d" "$d/d1\n$d\n" "" 0 "-D and -M1" 39 | test_rawhide "$rh -D -m0 -M1 $d" "$d/d1\n$d\n" "" 0 "-D and -m0 -M1" 40 | test_rawhide "$rh -D -m0 -M2 $d" "$d/d1/d2\n$d/d1\n$d\n" "" 0 "-D and -m0 -M2" 41 | test_rawhide "$rh -D -m1 -M2 $d" "$d/d1/d2\n$d/d1\n" "" 0 "-D and -m1 -M2" 42 | test_rawhide "$rh -D -m1 -M3 $d" "$d/d1/d2/d3\n$d/d1/d2\n$d/d1\n" "" 0 "-D and -m1 -M3" 43 | test_rawhide "$rh -D -m2 -M3 $d" "$d/d1/d2/d3\n$d/d1/d2\n" "" 0 "-D and -m2 -M3" 44 | test_rawhide "$rh -D -m3 -M4 $d" "$d/d1/d2/d3/d4\n$d/d1/d2/d3\n" "" 0 "-D and -m3 -M4" 45 | test_rawhide "$rh -D -m4 -M4 $d" "$d/d1/d2/d3/d4\n" "" 0 "-D and -m4 -M4" 46 | test_rawhide "$rh -D -m5 -M5 $d" "" "" 0 "-D and -m5 -M5" 47 | 48 | # But where possible, compare depth numbers with find's -mindepth -maxdepth 49 | if find_has_mindepth 50 | then 51 | test_rawhide_pre_hook() { test_rh_find_pre_hook; } 52 | test_rawhide_find "$rh $d" "find $d" "without -D option" 53 | test_rawhide_find "$rh -D $d" "find $d -depth" "with -D option" 54 | test_rawhide_find "$rh -D -M0 $d" "find $d -depth -maxdepth 0" "-D and -M0" 55 | test_rawhide_find "$rh -D -M1 $d" "find $d -depth -maxdepth 1" "-D and -M1" 56 | test_rawhide_find "$rh -D -m0 -M1 $d" "find $d -depth -mindepth 0 -maxdepth 1" "-D and -m0 -M1" 57 | test_rawhide_find "$rh -D -m0 -M2 $d" "find $d -depth -mindepth 0 -maxdepth 2" "-D and -m0 -M2" 58 | test_rawhide_find "$rh -D -m1 -M2 $d" "find $d -depth -mindepth 1 -maxdepth 2" "-D and -m1 -M2" 59 | test_rawhide_find "$rh -D -m1 -M3 $d" "find $d -depth -mindepth 1 -maxdepth 3" "-D and -m1 -M3" 60 | test_rawhide_find "$rh -D -m2 -M3 $d" "find $d -depth -mindepth 2 -maxdepth 3" "-D and -m2 -M3" 61 | test_rawhide_find "$rh -D -m3 -M4 $d" "find $d -depth -mindepth 3 -maxdepth 4" "-D and -m3 -M4" 62 | test_rawhide_find "$rh -D -m4 -M4 $d" "find $d -depth -mindepth 4 -maxdepth 4" "-D and -m4 -M4" 63 | test_rawhide_find "$rh -D -m5 -M5 $d" "find $d -depth -mindepth 5 -maxdepth 5" "-D and -m5 -M5" 64 | test_rawhide_pre_hook() { true; } 65 | fi 66 | 67 | test_rawhide "$rh -D -e exit $d" "$d/d1/d2/d3/d4\n" "" 0 "-D with exit" 68 | 69 | test_rawhide "$rh -D $d" "$d/d1/d2/d3/d4\n$d/d1/d2/d3\n$d/d1/d2\n$d/d1\n$d\n" "" 0 "-D explicit check without find" 70 | test_rawhide "$rh -UUU $d" "" "" 0 "-UUU action (check next)" 71 | test_rawhide "$rh $d" "" "./rh: fstatat $d: No such file or directory\n" 1 "-UUU check (without -e1, deleted $d cleverly seen as an attempt at a path)" 72 | test_rawhide "$rh -e1 $d" "" "./rh: fstatat $d: No such file or directory\n" 1 "-UUU check (with -e1)" 73 | 74 | mkdir $d 75 | mkdir $d/d1 76 | mkdir $d/d1/d2 77 | mkdir $d/d1/d2/d3 78 | touch $d/d1/d2/d3/d4 79 | 80 | test_rawhide "$rh -UUU -e 'file' $d" "" "" 0 "-UUU file only action" 81 | test_rawhide "$rh -D $d" "$d/d1/d2/d3\n$d/d1/d2\n$d/d1\n$d\n" "" 0 "-UUU file only check (with -D)" 82 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-UUU file only check (without -D)" 83 | 84 | touch $d/d1/d2/d3/d4 85 | 86 | test_rawhide_post_hook() { test_rh_errno_post_hook; } 87 | test_rawhide "$rh -UUU -e 'dir' $d" "" "./rh: unlinkat $d/d1/d2/d3: Directory not empty\n./rh: unlinkat $d/d1/d2: Directory not empty\n./rh: unlinkat $d/d1: Directory not empty\n./rh: rmdir $d: Directory not empty\n" 1 "-UUU dir only action (fails because a file exists)" 0 "-UUU preparation" 88 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n$d/d1/d2/d3/d4\n" "" 0 "-UUU failed dir only check (no change)" 89 | test_rawhide_post_hook() { true; } 90 | 91 | test_rawhide "RAWHIDE_TEST_TTY=1 $rh -UUU -v $d/d1" "$d/d1/d2/d3/d4\n$d/d1/d2/d3\n$d/d1/d2\n$d/d1\n" "" 0 "-UUU with -v action (tty)" 92 | test_rawhide " $rh $d" "$d\n" "" 0 "-UUU with -v check" 93 | 94 | mkdir $d/d1 95 | mkdir $d/d1/d2 96 | mkdir $d/d1/d2/d3 97 | touch $d/d1/d2/d3/d4 98 | 99 | test_rawhide "$rh -UUU -v -e file $d" "$d/d1/d2/d3/d4\n" "" 0 "-UUU with -v (file only) action" 100 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/d2\n$d/d1/d2/d3\n" "" 0 "-UUU with -v (file only) check" 101 | 102 | test_rawhide "$rh -UUU -v -e dir $d/d1" "$d/d1/d2/d3\n$d/d1/d2\n$d/d1\n" "" 0 "-UUU with -v (the rest) action" 103 | test_rawhide "$rh $d" "$d\n" "" 0 "-UUU with -v (the rest) check" 104 | 105 | case "`uname`" in 106 | CYGWIN*) # The delete succeeds on Cygwin 107 | ;; 108 | *) 109 | if [ "`whoami`" != root ] 110 | then 111 | mkdir $d/d1 112 | touch $d/d1/f 113 | chmod -w $d/d1 114 | test_rawhide "$rh -UUU -e file $d/d1/f" "" "./rh: unlink $d/d1/f: Permission denied\n" 1 "-UUU file only (fail because parent directory not writable)" 115 | test_rawhide "$rh $d" "$d\n$d/d1\n$d/d1/f\n" "" 0 "-UUU with -v (the rest) check" 116 | chmod +w $d/d1 117 | rm -rf $d/d1 118 | fi 119 | ;; 120 | esac 121 | 122 | # Test -U with -y/-Y and symlinks 123 | 124 | mkdir $d/t1 $d/tt1 $d/t2 $d/tt2 $d/t3 $d/tt3 $d/t4 $d/tt4 125 | touch $d/ff1 $d/ff2 $d/ff3 $d/ff4 126 | mkdir $d/tt1/d $d/tt2/d $d/tt3/d $d/tt4/d 127 | touch $d/tt1/d/f $d/tt2/d/f $d/tt3/d/f $d/tt4/d/f 128 | ln -s ../tt1 $d/t1/ld 129 | ln -s ../tt2 $d/t2/ld 130 | ln -s ../tt3 $d/t3/ld 131 | ln -s ../tt4 $d/t4/ld 132 | ln -s ../ff1 $d/t1/lf 133 | ln -s ../ff2 $d/t2/lf 134 | ln -s ../ff3 $d/t3/lf 135 | ln -s ../ff4 $d/t4/lf 136 | 137 | test_rawhide_post_hook() { test_rh_sort_post_hook; } 138 | test_rawhide "$rh -UUU -v $d/t1" "$d/t1\n$d/t1/ld\n$d/t1/lf\n" "" 0 "-UUU -v with symlinks" 139 | test_rawhide "$rh $d/t1 $d/tt1 $d/ff1" "$d/ff1\n$d/tt1\n$d/tt1/d\n$d/tt1/d/f\n" "./rh: fstatat $d/t1: No such file or directory\n" 1 "-UUU -v with symlinks (aftermath)" 140 | test_rawhide "$rh -UUU -v -y $d/t2" "$d/t2\n$d/t2/ld\n$d/t2/lf\n" "" 0 "-UUU -v -y with unfollowed symlinks" 141 | test_rawhide "$rh $d/t2 $d/tt2 $d/ff2" "$d/ff2\n$d/tt2\n$d/tt2/d\n$d/tt2/d/f\n" "./rh: fstatat $d/t2: No such file or directory\n" 1 "-UUU -v -y with unfollowed symlinks (aftermath)" 142 | test_rawhide "$rh -UUU -v -y $d/t3/lf" "$d/t3/lf\n" "" 0 "-UUU -v -y with followed symlinks (to file)" 143 | test_rawhide "$rh $d/t3 $d/tt3 $d/ff3" "$d/ff3\n$d/t3\n$d/t3/ld\n$d/tt3\n$d/tt3/d\n$d/tt3/d/f\n" "" 0 "-UUU -v -y with followed symlinks (to file) (aftermath)" 144 | test_rawhide "$rh -UUU -v -y $d/t3/ld" "$d/t3/ld\n$d/t3/ld/d\n$d/t3/ld/d/f\n" "" 0 "-UUU -v -y with followed symlinks (to dir)" 145 | test_rawhide "$rh $d/t3 $d/tt3 $d/ff3" "$d/ff3\n$d/t3\n$d/tt3\n" "" 0 "-UUU -v -y with followed symlinks (to dir) (aftermath)" 146 | test_rawhide "$rh -UUU -v -Y $d/t4" "$d/t4\n$d/t4/ld\n$d/t4/ld/d\n$d/t4/ld/d/f\n$d/t4/lf\n" "" 0 "-UUU -v -Y with followed symlinks (to dir and file)" 147 | test_rawhide "$rh $d/t4 $d/tt4 $d/ff4" "$d/ff4\n$d/tt4\n" "./rh: fstatat $d/t4: No such file or directory\n" 1 "-UUU -v -Y with followed symlinks (to dir and file) (aftermath)" 148 | 149 | finish 150 | 151 | exit $errors 152 | 153 | # vi:set ts=4 sw=4: 154 | -------------------------------------------------------------------------------- /tests/t22: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="implicit -e expression heuristic" 28 | 29 | test_rawhide "$rh $d" "$d\n" "" 0 "an existing path" 30 | test_rawhide "$rh $d/abc" "" "./rh: fstatat $d/abc: No such file or directory\n" 1 "parent is a path" 31 | test_rawhide "$rh $d/abc/def" "" "./rh: fstatat $d/abc/def: No such file or directory\n" 1 "grand parent is a path" 32 | test_rawhide "$rh $d/abc/def/ghi" "" "./rh: fstatat $d/abc/def/ghi: No such file or directory\n" 1 "great grand parent is a path" 33 | test_rawhide "$rh $d/abc/def/ghi/jkl" "" "./rh: command line: -e '$d/abc/def/ghi/jkl': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "great great grand parent is a path - too far up - assuming expression" 34 | test_rawhide "$rh '$d/?'" "" "./rh: command line: -e '$d/?': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '?'" 35 | test_rawhide "$rh '$d/:'" "" "./rh: command line: -e '$d/:': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char ':'" 36 | test_rawhide "$rh '$d/|'" "" "./rh: command line: -e '$d/|': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '|'" 37 | test_rawhide "$rh '$d/&'" "" "./rh: command line: -e '$d/&': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '&'" 38 | test_rawhide "$rh '$d/^'" "" "./rh: command line: -e '$d/^': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '^'" 39 | test_rawhide "$rh '$d/='" "" "./rh: command line: -e '$d/=': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '='" 40 | test_rawhide "$rh '$d/!'" "" "./rh: command line: -e '$d/!': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '!'" 41 | test_rawhide "$rh '$d/<'" "" "./rh: command line: -e '$d/<': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '<'" 42 | test_rawhide "$rh '$d/>'" "" "./rh: command line: -e '$d/>': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '>'" 43 | test_rawhide "$rh '$d/*'" "" "./rh: command line: -e '$d/*': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '*'" 44 | test_rawhide "$rh '$d/%'" "" "./rh: command line: -e '$d/%%': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '%'" 45 | test_rawhide "$rh '$d/\$'" "" "./rh: command line: -e '$d/\$': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '\$'" 46 | test_rawhide "$rh '$d/\"'" "" "./rh: command line: -e '$d/\"': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '\"'" 47 | test_rawhide "$rh '$d/\"'" "" "./rh: command line: -e '$d/\"': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '\\'" 48 | test_rawhide "$rh '$d/['" "" "./rh: command line: -e '$d/[': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '['" 49 | test_rawhide "$rh '$d/]'" "" "./rh: command line: -e '$d/]': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char ']'" 50 | test_rawhide "$rh '$d/{'" "" "./rh: command line: -e '$d/{': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '{'" 51 | test_rawhide "$rh '$d/}'" "" "./rh: command line: -e '$d/}': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '}'" 52 | test_rawhide "$rh '$d/;'" "" "./rh: command line: -e '$d/;': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char ';'" 53 | test_rawhide "$rh '$d/\n'" "" "./rh: command line: -e '$d/\\\\n': line 1 byte 6: expected '(' or '{', found '/' (possible attempt to call an undefined function)\n" 1 "parent is a path but has non-pathy char '\\\\n'" 54 | 55 | test_rawhide "$rh ' ' $d" "$d\n" "" 0 "has non-pathy chars ' ' - expr - ok" 56 | test_rawhide "$rh '?' $d" "" "./rh: command line: -e '?': line 1 byte 1: syntax error: '?'\n" 1 "has non-pathy chars '?' expr" 57 | test_rawhide "$rh ':' $d" "" "./rh: command line: -e ':': line 1 byte 1: syntax error: ':'\n" 1 "has non-pathy chars ':' expr" 58 | test_rawhide "$rh '|' $d" "" "./rh: command line: -e '|': line 1 byte 1: syntax error: '|'\n" 1 "has non-pathy chars '|' expr" 59 | test_rawhide "$rh '&' $d" "" "./rh: command line: -e '&': line 1 byte 1: syntax error: '&'\n" 1 "has non-pathy chars '&' expr" 60 | test_rawhide "$rh '<' $d" "" "./rh: command line: -e '<': line 1 byte 1: syntax error: '<'\n" 1 "has non-pathy chars '<' expr" 61 | test_rawhide "$rh '>' $d" "" "./rh: command line: -e '>': line 1 byte 1: syntax error: '>'\n" 1 "has non-pathy chars '>' expr" 62 | test_rawhide "$rh '^' $d" "" "./rh: command line: -e '^': line 1 byte 1: syntax error: '^'\n" 1 "has non-pathy chars '^' expr" 63 | test_rawhide "$rh '=' $d" "" "./rh: command line: -e '=': line 1 byte 1: syntax error: '='\n" 1 "has non-pathy chars '=' expr" 64 | test_rawhide "$rh '!' $d" "" "./rh: command line: -e '!': line 1 byte 2: syntax error: eof\n" 1 "has non-pathy chars '!' expr" 65 | test_rawhide "$rh '*' $d" "" "./rh: command line: -e '*': line 1 byte 1: syntax error: '*'\n" 1 "has non-pathy chars '*' expr" 66 | test_rawhide "$rh '%' $d" "" "./rh: command line: -e '%%': line 1 byte 1: syntax error: '%%'\n" 1 "has non-pathy chars '%' expr" 67 | test_rawhide "$rh '+' $d" "" "./rh: command line: -e '+': line 1 byte 1: syntax error: '+'\n" 1 "has non-pathy chars '+' expr" 68 | test_rawhide "$rh '\$' $d" "" "./rh: command line: -e '\$': line 1 byte 1: no such user: \n" 1 "has non-pathy chars '\$' expr" 69 | test_rawhide "$rh '@' $d" "" "./rh: command line: -e '@': line 1 byte 1: no such group: \n" 1 "has non-pathy chars '@' expr" 70 | test_rawhide "$rh '\"' $d" "" "./rh: command line: -e '\"': line 1 byte 2: invalid string literal (missing closing double quote)\n" 1 "has non-pathy chars '\"' expr" 71 | test_rawhide "$rh '[' $d" "" "./rh: command line: -e '[': line 1 byte 2: expected year number, found eof\n" 1 "has non-pathy chars '[' expr" 72 | test_rawhide "$rh ']' $d" "" "./rh: command line: -e ']': line 1 byte 1: syntax error: ']'\n" 1 "has non-pathy chars ']' expr" 73 | test_rawhide "$rh '{' $d" "" "./rh: command line: -e '{': line 1 byte 2: invalid string literal (missing closing curly brace)\n" 1 "has non-pathy chars '{' expr" 74 | test_rawhide "$rh '}' $d" "" "./rh: command line: -e '}': line 1 byte 1: syntax error: '}'\n" 1 "has non-pathy chars '}' expr" 75 | test_rawhide "$rh ';' $d" "" "./rh: command line: -e ';': line 1 byte 1: syntax error: ';'\n" 1 "has non-pathy chars ';' expr" 76 | 77 | test_rawhide "$rh file $d" "" "" 0 "file: no expr chars and no non-pathy chars and not path - assume expr" 78 | test_rawhide "$rh dir $d" "$d\n" "" 0 "dir: no expr chars and no non-pathy chars and not path - assume expr" 79 | 80 | finish 81 | 82 | exit $errors 83 | 84 | # vi:set ts=4 sw=4: 85 | -------------------------------------------------------------------------------- /tests/t30: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rawhide - find files using pretty C expressions 4 | # https://raf.org/rawhide 5 | # https://github.com/raforg/rawhide 6 | # https://codeberg.org/raforg/rawhide 7 | # 8 | # Copyright (C) 1990 Ken Stauffer, 2022-2023 raf 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, see . 22 | # 23 | # 20231013 raf 24 | 25 | . tests/.common 26 | 27 | label="-? option" 28 | 29 | test_rawhide "$rh -? all,extra $d 2>/dev/null" "$d\n" "" 0 "test coverage" 30 | 31 | finish 32 | 33 | exit $errors 34 | 35 | # vi:set ts=4 sw=4: 36 | --------------------------------------------------------------------------------