├── .github └── workflows │ ├── .gitignore │ ├── expected-stderr.txt │ ├── full-check.yml │ ├── man_page_in_sync.yml │ ├── release-tarball.yml │ └── test.txt ├── AUTHORS ├── CONTRIBUTING.md ├── COPYING ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── README.md ├── autogen.sh ├── bash-completion └── dcfldd ├── configure.ac ├── doc └── UPDATE-CHECK ├── man ├── create-man.sh ├── dcfldd.1 └── dcfldd.txt └── src ├── Makefile.am ├── argmatch.c ├── argmatch.h ├── copy.c ├── copy.h ├── dcfldd.c ├── dcfldd.h ├── dcfldd_error.c ├── dcfldd_error.h ├── full-write.c ├── full-write.h ├── getpagesize.h ├── hash.c ├── hash.h ├── hashformat.c ├── hashformat.h ├── human.c ├── human.h ├── log.c ├── log.h ├── long-options.c ├── long-options.h ├── md5.c ├── md5.h ├── output.c ├── output.h ├── pathmax.h ├── pattern.c ├── pattern.h ├── safe-read.c ├── safe-read.h ├── sha1.c ├── sha1.h ├── sha2.c ├── sha2.h ├── sizeprobe.c ├── sizeprobe.h ├── split.c ├── split.h ├── sys2.h ├── system.h ├── translate.c ├── translate.h ├── util.c ├── util.h ├── verify.c ├── verify.h ├── version-etc.c ├── version-etc.h ├── xalloc.h ├── xstrtol.c ├── xstrtol.h ├── xstrtoul.c └── xstrtoumax.c /.github/workflows/.gitignore: -------------------------------------------------------------------------------- 1 | /actual-stderr.txt 2 | -------------------------------------------------------------------------------- /.github/workflows/expected-stderr.txt: -------------------------------------------------------------------------------- 1 | 2 | Total (md5): 92994b0ce292a217e3e3bc31b639e565 3 | 4 | Total (sha1): bc0e4b74695142e0a0bdae87aea310d7078866cb 5 | 6 | Total (sha256): 02fd428a4671925e4ca61541b9fac648f4ccdccad65602bfd3256ba14e59489c 7 | 8 | Total (sha384): 53b8374607a8258de4173265bfbfa6120093fd42090a92fd589cf2c6c16b4e421b5135777714976713f7949715720a83 9 | 10 | Total (sha512): 969a39bf47b5f12d81121084f19cb5ae250e0c0ea5b7c6d82cf08131acde8e1955d137612c2f6b255e25b0e28f96f93586f90f06965cb8f719ed7fbdd95cc8d4 11 | 12 | 0+1 records in 13 | 0+1 records out 14 | -------------------------------------------------------------------------------- /.github/workflows/full-check.yml: -------------------------------------------------------------------------------- 1 | name: full-check 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | include: 11 | - cc: gcc-14 12 | clang_major_version: null 13 | runs-on: ubuntu-24.04 14 | - cc: gcc-15 15 | clang_major_version: null 16 | runs-on: ubuntu-24.04 17 | - cc: clang-19 18 | clang_major_version: 19 19 | runs-on: ubuntu-22.04 20 | - cc: musl-gcc 21 | clang_major_version: null 22 | runs-on: ubuntu-24.04 23 | 24 | runs-on: ${{ matrix.runs-on }} 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | - name: gcc_15_repo 29 | if: "${{ matrix.cc == 'gcc-15' }}" 30 | run: | 31 | set -x 32 | # NOTE: plucky is 25.04 (not 24.04 LTS) 33 | sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu/ plucky main universe' 34 | - name: gcc_15_install 35 | if: "${{ matrix.cc == 'gcc-15' }}" 36 | run: | 37 | set -x 38 | sudo apt-get install --yes --no-install-recommends -V \ 39 | binutils \ 40 | gcc-15 41 | apt-cache policy binutils 42 | - name: clang_repo 43 | if: "${{ contains(matrix.cc, 'clang') }}" 44 | run: | 45 | set -x 46 | source /etc/os-release 47 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 48 | sudo add-apt-repository "deb http://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-${{ matrix.clang_major_version }} main" 49 | - name: clang_install 50 | if: "${{ contains(matrix.cc, 'clang') }}" 51 | run: |- 52 | sudo apt-get update 53 | sudo apt-get install --yes --no-install-recommends -V \ 54 | clang-${{ matrix.clang_major_version }} \ 55 | libclang-rt-${{ matrix.clang_major_version }}-dev 56 | - name: musl_tools_install 57 | if: "${{ contains(matrix.cc, 'musl') }}" 58 | run: |- 59 | sudo apt-get update 60 | sudo apt-get install --yes --no-install-recommends -V \ 61 | musl-tools 62 | - name: first_build 63 | run: | 64 | ./autogen.sh 65 | ./configure CC=${{ matrix.cc }} CFLAGS='-std=c99 -Wall -Wextra -pedantic' \ 66 | || { cat config.log ; false ; } 67 | make 68 | sudo make install 69 | sudo make uninstall 70 | make distclean 71 | - name: second_build 72 | run: | 73 | configure_args=( 74 | CC=${{ matrix.cc }} 75 | ) 76 | 77 | if [[ "${{ matrix.cc }}" != musl-gcc ]]; then 78 | configure_args+=( 79 | CFLAGS='-g -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer' 80 | LDFLAGS='-g -fsanitize=address,undefined' 81 | ) 82 | fi 83 | 84 | ./autogen.sh 85 | ./configure "${configure_args[@]}" \ 86 | || { cat config.log ; false ; } 87 | make 88 | sudo make install 89 | - name: run_program 90 | run: | 91 | set -x 92 | dcfldd if=.github/workflows/test.txt of=/tmp/test2.txt hash=md5,sha1,sha256,sha384,sha512 2>.github/workflows/actual-stderr.txt 93 | diff -u .github/workflows/{actual,expected}-stderr.txt 94 | ls -lh /tmp/test2.txt 95 | head -n3 /tmp/test2.txt | grep -i autopkgtest 96 | - name: test_make_dist 97 | run: | 98 | make distclean 99 | ./autogen.sh 100 | ./configure CC=${{ matrix.cc }} 101 | make dist 102 | mkdir test_dist 103 | mv dcfldd-*.tar.gz test_dist 104 | cd test_dist 105 | pwd 106 | tar -xvf dcfldd-*.tar.gz 107 | rm -f dcfldd-*.tar.gz 108 | cd dcfldd-* 109 | ./autogen.sh 110 | ./configure CC=${{ matrix.cc }} --with-bash-completion 111 | make 112 | ls 113 | sudo make install 114 | sudo make uninstall 115 | make distclean 116 | -------------------------------------------------------------------------------- /.github/workflows/man_page_in_sync.yml: -------------------------------------------------------------------------------- 1 | name: Enforce that man/dcfldd.1 remains in sync 2 | 3 | on: 4 | pull_request: 5 | push: 6 | schedule: 7 | - cron: '0 16 * * 5' # Every Friday 4pm 8 | workflow_dispatch: 9 | 10 | # Drop permissions to minimum for security 11 | permissions: 12 | contents: read 13 | 14 | jobs: 15 | man_page_in_sync: 16 | runs-on: ubuntu-24.04 17 | steps: 18 | 19 | - uses: actions/checkout@v4 20 | 21 | - name: Install build dependencies 22 | run: | 23 | sudo apt-get update 24 | sudo apt-get install --no-install-recommends --yes -V \ 25 | txt2man 26 | 27 | - name: Check man/dcfldd.1 for being in sync 28 | run: | 29 | set -x 30 | cd man/ 31 | rm dcfldd.1 # so that create-man.sh has to close that very gap 32 | ./create-man.sh 33 | git diff --exit-code # i.e. fail CI in case of a diff (and show it) 34 | -------------------------------------------------------------------------------- /.github/workflows/release-tarball.yml: -------------------------------------------------------------------------------- 1 | name: Release tarball 2 | 3 | on: 4 | push: 5 | tags: 6 | - "**" 7 | 8 | jobs: 9 | release: 10 | name: "Release" 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: "Determine tag" 17 | id: "determine-tag" 18 | run: "echo \"::set-output name=tag::${GITHUB_REF#refs/tags/v}\"" 19 | 20 | - name: "Determine configure.ac version" 21 | id: "determine-ac" 22 | run: "echo \"::set-output name=version::`sed -n -E 's/AC_INIT\\(\\[dcfldd\\], \\[(.+?)\\],.*$/\\1/p' configure.ac`\"" 23 | 24 | - name: "Fail when tag version != configure.ac version" 25 | run: "exit 1" 26 | if: steps.determine-tag.outputs.tag != steps.determine-ac.outputs.version 27 | 28 | - name: Build and check distribution tarball 29 | run: | 30 | ./autogen.sh 31 | ./configure 32 | make distcheck 33 | 34 | - name: Create Release 35 | id: create_release 36 | uses: actions/create-release@v1 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | with: 40 | tag_name: v${{ steps.determine-tag.outputs.tag }} 41 | release_name: Release ${{ steps.determine-tag.outputs.tag }} 42 | draft: false 43 | prerelease: false 44 | 45 | - name: Upload Release Asset 46 | id: upload-release-asset 47 | uses: actions/upload-release-asset@v1 48 | env: 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | with: 51 | upload_url: ${{ steps.create_release.outputs.upload_url }} 52 | asset_path: ./dcfldd-${{ steps.determine-tag.outputs.tag }}.tar.gz 53 | asset_name: dcfldd-${{ steps.determine-tag.outputs.tag }}.tar.gz 54 | asset_content_type: application/gzip 55 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | GNU dd by Paul Rubin, David MacKenzie and Stuart Kemp 2 | dcfldd by Nicholas Harbour and some colaborators 3 | In 2019, the project was migrated to GitHub by Joao Eriberto Mota Filho 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## HOW TO CONTRIBUTE TO DCFLDD DEVELOPMENT 2 | 3 | dcfldd is available at 4 | https://github.com/resurrecting-open-source-projects/dcfldd 5 | 6 | If you are interested in contribute to dcfldd development, please, follow 7 | these steps: 8 | 9 | 1. Send a patch that fix an issue or that implement a new feature. 10 | Alternatively, you can do a 'pull request'[1] in GitHub. 11 | 12 | [1] https://help.github.com/articles/about-pull-requests 13 | 14 | 2. Ask for join to the dcfldd project in GitHub, if you want to work 15 | officially. Note that this second step is not compulsory. However, 16 | to accept you in project, is needed a minimum previous collaboration. 17 | 18 | 19 | To find issues and bugs to fix, you can check these addresses: 20 | 21 | - https://github.com/resurrecting-open-source-projects/dcfldd 22 | - https://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=dcfldd 23 | - https://bugs.launchpad.net/ubuntu/+source/dcfldd/+bugs 24 | 25 | If you want to join, please make a contact. 26 | 27 | -- Eriberto, Mon, 28 Oct 2019 23:29:53 -0300. 28 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2025-06-01 David da Silva Polverari 2 | Version 1.9.3 3 | 4 | [ David da Silva Polverari ] 5 | 6 | * configure.ac: removed obsolete AC_PROG_GCC_TRADITIONAL macro. 7 | 8 | [ Sebastian Pipping ] 9 | 10 | * Renamed bash completion file on install. 11 | * Fixed several function prototypes and related code to build with GCC 15. 12 | * .github/workflows/full-check.yml: 13 | - added GitHub CI test to ensure distibution tarball can install bash 14 | completion scripts. 15 | - updated to start covering GCC 15. 16 | * .github/workflows/man_page_in_sync.yml: created to make GitHub Actions 17 | enforce man page on release was generated properly. 18 | * configure.ac: migrated from using deprecated AC_HELP_STRING macro to 19 | AS_HELP_STRING. 20 | 21 | 2024-10-20 David da Silva Polverari 22 | Version 1.9.2 23 | 24 | [ David da Silva Polverari ] 25 | 26 | * Added configure switch to enable existing bash completion. 27 | * Added dcfldd_error module to avoid dependency on glibc's error(). 28 | * Replaced error() invocations with dcfldd_error(). 29 | * autogen.sh: added checks for pkg-config presence. 30 | * configure.ac: enabled assertions by default. 31 | 32 | [ Jonas Stein ] 33 | 34 | * Added repology badge with link to all known dcfldd packaged versions. 35 | 36 | [ Lucian Popescu ] 37 | 38 | * Fixed memory leaks and removed unused variables. 39 | 40 | [ Sam James ] 41 | 42 | * src/sha2.c: 43 | - Fixed aliasing violation on pointer access. 44 | - Fixed instances of --Wsizeof-pointer-memaccess 45 | 46 | [ Sebastian Pipping ] 47 | 48 | * .github/workflows/full-check.yml: 49 | - Added build agains musl libc. 50 | - Added config.log dump on configure failure for debugging. 51 | - Covered more hashing tests on the expected program output. 52 | - Disabled sanitizers when building with musl-gcc. 53 | - Enabled debugging symbols. 54 | - Enabled use of UndefinedBehaviorSanitizer. 55 | - Updated Github CI pipeline to use more modern compiler versions. 56 | * src/hash.c: fixed function pointer type mismatch. 57 | * src/ouput.c: initialized output_t.stream properly. 58 | * src/sha2.{c,h}: 59 | - Replaced SHA2_USE_INTTYPES_H by HAVE_INTTYPES_H to support musl libc. 60 | - Moved typedefs from implementation to header to allow reuse. 61 | 62 | 2023-04-17 Joao Eriberto Mota Filho 63 | Version 1.9.1 64 | 65 | [ David Polverari ] 66 | 67 | * Fixed memory leaks causing out of memory error when using diffwr option. 68 | 69 | 2023-02-08 Joao Eriberto Mota Filho 70 | Version 1.9 71 | 72 | [ Tibor Szolnoki ] 73 | 74 | * Added support for writing to output only if destination block content 75 | differs ('diffwr' option). 76 | 77 | [ David Polverari ] 78 | 79 | * Added bash completion for diffwr. 80 | * Minor fixes in manpage and help. 81 | * Minor optimizations in source code. 82 | 83 | 2022-10-17 Joao Eriberto Mota Filho 84 | Version 1.8 85 | 86 | [ Joao Eriberto Mota Filho ] 87 | 88 | * Improved CI test for GitHub (added test for make dist). 89 | 90 | [ David Polverari ] 91 | 92 | * Added support for runtime endianness check. 93 | * Fixed SHA1 output on big-endian architectures. 94 | 95 | 2021-08-17 Joao Eriberto Mota Filho 96 | Version 1.7.1 97 | 98 | [ Joao Eriberto Mota Filho ] 99 | 100 | * Changes to process manpage in main Makefile.am. 101 | * Created CI test in GitHub. 102 | * Updated install system, removed warnings and bumped required autoconf 103 | to 2.69. 104 | 105 | [ David Polverari ] 106 | 107 | * New internal feature: release make distcheck tarball on tag push (automated 108 | distcheck), via GitHub actions. 109 | 110 | 2020-02-02 Joao Eriberto Mota Filho 111 | Version 1.7 112 | 113 | [ David Polverari ] 114 | 115 | * src/sizeprobe.c: fixed destination size unit. (Debian bug #886647) 116 | * src/util.c: fixed non-Linux build error. 117 | 118 | 2020-01-13 Joao Eriberto Mota Filho 119 | Version 1.6 120 | 121 | [ Joao Eriberto Mota Filho ] 122 | 123 | * Updated bash completion script. 124 | 125 | [ David Polverari ] 126 | 127 | * Fixed a segfault when using 'errlog='. 128 | 129 | 2019-11-02 Joao Eriberto Mota Filho 130 | Version 1.5 131 | 132 | [ Joao Eriberto Mota Filho ] 133 | 134 | * Autotools files: 135 | - Added a distclean-local target in Makefile.am. 136 | - Added the autogen.sh file. 137 | - Improved the configure.ac and Makefile.am files. 138 | - Moved some build lines from Makefile.am to src/Makefile.am. 139 | - Removed all autogenerated files. 140 | * Added a bash completion script (from Debian). 141 | * Created CONTRIBUTING.md file. 142 | * Fixed some building warnings. 143 | * Fixed the message when using hashes (add a newline to generate a space 144 | between the summary message and hashes. 145 | * Manpage and help page: 146 | - Added all new features from David Loveall to manpage and help page. 147 | - Full reviewed and improved the manpage and help page. Added examples 148 | in manpage. 149 | - Using txt2man to produce an updated manpage. 150 | * Moved all source code to src/. 151 | * Reorganized AUTHORS and ChangeLog files. 152 | * Rewritten README file, now called README.md. 153 | * Set -fgnu89-inline in CFLAGS to avoid warning (fix: 'warning: inline 154 | function 'quit' declared but never defined'). 155 | * Updated all headers and rights. 156 | * Updated GPL-2 text in all headers and in COPYING files. 157 | 158 | [ Bernhard Übelacker ] 159 | 160 | * Fixed include order to avoid different definitions of off_t. Patch from 161 | Debian. 162 | 163 | [ David Loveall ] 164 | 165 | * Several changes and improvements. Patch from SF.net[1]. Changes from Dave. 166 | Additions: 167 | 168 | - Allows for partial write of block during conv=sync if at the end of 169 | input. 170 | - Allows limit=<# of bytes> to limit the count of input, rather than 171 | count=<# of blocks>. 172 | - Closes all popened processes. (Uses internal popen call, rather than 173 | original popen2.) 174 | - Allows sizeprobe=<# of bytes> to manually specify. 175 | - Allows for splitformat=MAC to use output file naming of foo.dmg, 176 | foo.002.dmgpart, ..., foo.999.dmgpart, foo.1000.dmgpart, .... 177 | - Allows for splitformat=WIN to use output file naming of foo.001, foo.002, 178 | ..., foo.999, foo.1000, .... 179 | - Fixes too many opened files bug. 180 | 181 | [ Martin Scharrer ] 182 | 183 | * Fix exception for statusinterval=0. Patch from SF.net. 184 | 185 | [ Miah Gregory ] 186 | 187 | * Fixed implicit declaration warnings. Patch from Debian. 188 | * Fixed a spelling error. Patch from Debian. 189 | 190 | [ Vangelis Koukis ] 191 | 192 | * Fixed size probing of large block devices. Patch from Debian. 193 | * Fixed the sizeprobe=of option. Patch from Debian. 194 | 195 | ---- OLD AND INCOMPLETE CHANGELOG ---- 196 | 197 | Changes from version 1.2.2: 198 | - Added ability to write to multiple output files. 199 | - Added split capability with the "split=" and "splitformat=" switches. 200 | - Converts "if=/dev/zero" to "pattern=00" to force efficiency. 201 | - Fixed a few bugs with verify. 202 | 203 | Changes from version 1.2.1: 204 | - Fixed large file support bug 205 | - added verify capability 206 | 207 | Changes from version 1.0: 208 | - Added SHA-1, SHA-256, SHA-384 and SHA-512 support 209 | - Fixed compile errors. 210 | - Fixed Megabyte constant. 211 | - Fixed problem with not displaying the final hash remainder. 212 | - Created an entirely new (and trim) build environment. 213 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # configure.ac, was previously configure.in (before 2019) 2 | # 3 | # Copyright ?-2002 Jim Meyering 4 | # Copyright 2002-2006 Nicholas Harbour 5 | # Copyright 2019-2021 Joao Eriberto Mota Filho 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License along 18 | # with this program; if not, write to the Free Software Foundation, Inc., 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | AUTOMAKE_OPTIONS = foreign no-dependencies 22 | 23 | if ENABLE_BASH_COMPLETION 24 | bashcompletiondir = $(BASH_COMPLETION_DIR) 25 | dist_bashcompletion_DATA = bash-completion/dcfldd 26 | endif 27 | 28 | SUBDIRS = src 29 | 30 | man_MANS = man/dcfldd.1 31 | 32 | EXTRA_DIST= autogen.sh CONTRIBUTING.md man/dcfldd.1 README.md 33 | 34 | distclean-local: 35 | rm -rf autom4te.cache 36 | rm -f aclocal.m4 compile config.* configure depcomp install-sh \ 37 | Makefile.in missing man/Makefile.in src/Makefile.in 38 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Version 1.9 2 | ----------- 3 | 4 | New option: diffwr. 5 | 6 | Version 1.5 7 | ----------- 8 | 9 | New options: 10 | - limit 11 | - using bytes in sizeprobe 12 | - MAC/WIN in split format 13 | 14 | Added several examples in manpage. 15 | 16 | See the manpage. 17 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Packaging status](https://repology.org/badge/tiny-repos/dcfldd.svg)](https://repology.org/project/dcfldd/versions) 2 | 3 | # dcfldd 4 | 5 | #### dcfldd - enhanced version of dd for forensics and security 6 | 7 | ## Help this project ## 8 | 9 | dcfldd needs your help. **If you are a programmer** and if you want to help a 10 | nice project, this is your opportunity. 11 | 12 | dcfldd was imported from some tarballs (the original homepage[1] and 13 | developers are inactive). After this, all patches found in Debian project and 14 | other places for this program were applied. All initial work was registered in 15 | ChangeLog file (version 1.5 and later releases). 16 | 17 | If you are interested to help dcfldd, read the [CONTRIBUTING.md](CONTRIBUTING.md) file. 18 | 19 | [1]: https://sourceforge.net/projects/dcfldd 20 | 21 | ## What is dcfldd? ## 22 | 23 | dcfldd is a modified version of GNU dd. The major features added are: 24 | 25 | - Hashing on-the-fly: dcfldd can hash the input data as it is being 26 | transferred, helping to ensure data integrity. 27 | - Status output: dcfldd can update the user of its progress in terms of the 28 | amount of data transferred and how much longer operation will take. 29 | - Flexible disk wipes: dcfldd can be used to wipe disks quickly and with a 30 | known pattern if desired. 31 | - Image/wipe verify: dcfldd can verify that a target drive is a bit-for-bit 32 | match of the specified input file or pattern. 33 | - Multiple outputs: dcfldd can output to multiple files or disks at the same 34 | time. 35 | - Split output: dcfldd can split output to multiple files with more 36 | configurability than the split command. 37 | - Piped output and logs: dcfldd can send all its log data and output to 38 | commands as well as files natively. 39 | 40 | dcfldd was originally created by Nicholas Harbour from the DoD Computer 41 | Forensics Laboratory (DCFL). Nick Harbour still maintaining the package, 42 | although he was no longer affiliated with the DCFL. 43 | 44 | Nowadays, dcfldd is maintained by volunteers. 45 | 46 | ## Build and Install ## 47 | 48 | To build and install, run the following commands: 49 | 50 | $ ./autogen.sh 51 | $ ./configure 52 | $ make 53 | # make install 54 | 55 | To return to original source code you can use '$ make distclean' command. 56 | 57 | On Debian systems you can use '# apt install dcfldd'. 58 | 59 | There is a bash completion file inside doc/ directory in source code. 60 | 61 | ## Author ## 62 | 63 | dcfldd was originally developed by Nicholas Harbour under GPL-2+ license. 64 | 65 | Currently, the source code and newer versions are available at 66 | https://github.com/resurrecting-open-source-projects/dcfldd 67 | 68 | See AUTHORS file for more information. 69 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # autogen.sh with clean option 4 | # Copyright 2016 Joao Eriberto Mota Filho 5 | # Copyright 2023 David da Silva Polverari 6 | # 7 | # This file is under BSD-3-Clause license. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions 11 | # are met: 12 | # 1. Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # 2. Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # 3. Neither the name of the authors nor the names of its contributors 18 | # may be used to endorse or promote products derived from this software 19 | # without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | # SUCH DAMAGE. 32 | 33 | 34 | # Use clean option 35 | if [ "$1" = "clean" -a ! -e Makefile ] 36 | then 37 | echo "Vanishing the code" 38 | rm -rf aclocal.m4 autom4te.cache compile config.guess config.h.in \ 39 | config.sub configure depcomp install-sh Makefile.in missing \ 40 | man/Makefile.in src/Makefile.in 41 | exit 0 42 | fi 43 | 44 | # Do not use clean option 45 | if [ "$1" = "clean" -a -e Makefile ] 46 | then 47 | echo "I can not clean. Use '$ make distclean'." 48 | exit 0 49 | fi 50 | 51 | env pkg-config --version > /dev/null 2>&1 52 | if [ $? -ne 0 ] 53 | then 54 | echo "pkg-config is missing. Please install it and run $0 again." 55 | exit 1 56 | fi 57 | 58 | # Do autoreconf 59 | autoreconf -i \ 60 | && { echo " "; \ 61 | echo "Done. You can use the 'clean' option to vanish the source code."; \ 62 | echo "Example of use: $ ./autogen clean"; \ 63 | } \ 64 | || { echo "We have a problem..."; exit 1; } 65 | -------------------------------------------------------------------------------- /bash-completion/dcfldd: -------------------------------------------------------------------------------- 1 | # bash completion for dcfldd -*- shell-script -*- 2 | # Copyright 2017-2020 Joao Eriberto Mota Filho 3 | # Copyright 2022 David Polverari 4 | # Version: 20200113 5 | # Based in dd completion script. 6 | 7 | _dcfldd() 8 | { 9 | local cur prev words cword 10 | _init_completion -n = || return 11 | 12 | case $cur in 13 | conv=*) 14 | cur=${cur#*=} 15 | COMPREPLY=( $( compgen -W 'ascii ebcdic ibm block unblock lcase 16 | notrunc ucase swab noerror sync' -- "$cur" ) ) 17 | return 0 18 | ;; 19 | errlog=*|if=*|of=*|md5log=*|sha1log=*|sha256log=*|sha384log=*|sha512log=*|verifylog=*|vf=*) 20 | cur=${cur#*=} 21 | _filedir 22 | return 0 23 | ;; 24 | hash=*) 25 | cur=${cur#*=} 26 | realcur=${cur##*,} 27 | COMPREPLY=( $( compgen -W 'md5 sha1 sha256 sha384 sha512' -- "$realcur" ) ) 28 | return 0 29 | ;; 30 | hashconv=*) 31 | cur=${cur#*=} 32 | COMPREPLY=( $( compgen -W 'before after' -- "$cur" ) ) 33 | return 0 34 | ;; 35 | status=*) 36 | cur=${cur#*=} 37 | COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) 38 | return 0 39 | ;; 40 | sizeprobe=*) 41 | cur=${cur#*=} 42 | COMPREPLY=( $( compgen -W 'if of' -- "$cur" ) ) 43 | return 0 44 | ;; 45 | diffwr=*) 46 | cur=${cur#*=} 47 | COMPREPLY=( $( compgen -W 'on off' -- "$cur") ) 48 | return 0 49 | ;; 50 | esac 51 | 52 | _expand || return 0 53 | 54 | COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) \ 55 | $( compgen -W 'bs cbs conv count limit ibs if obs of seek skip pattern 56 | textpattern errlog hash md5log sha1log sha256log sha384log 57 | sha512log hashwindow hashconv hashformat totalhashformat 58 | status statusinterval sizeprobe split splitformat vf 59 | verifylog diffwr' -S '=' -- "$cur" ) ) 60 | } && 61 | complete -F _dcfldd -o nospace dcfldd 62 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # configure.ac, was previously configure.in (before 2019) 2 | # 3 | # Copyright ?-2001 Jim Meyering 4 | # Copyright 2001-2006 Nicholas Harbour 5 | # Copyright 2019-2022 Joao Eriberto Mota Filho 6 | # Copyright 2022 David Polverari 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 2 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 along 19 | # with this program; if not, write to the Free Software Foundation, Inc., 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | 22 | AC_PREREQ([2.69]) 23 | 24 | AC_INIT([dcfldd],[1.9.3],[https://github.com/resurrecting-open-source-projects/dcfldd/issues]) 25 | AC_CONFIG_SRCDIR(src/dcfldd.c) 26 | AM_INIT_AUTOMAKE 27 | 28 | AC_HEADER_ASSERT 29 | AC_CONFIG_HEADERS([config.h]) 30 | AC_CANONICAL_HOST 31 | 32 | PKG_PROG_PKG_CONFIG 33 | 34 | AC_PROG_CC 35 | AC_PROG_CPP 36 | AC_PROG_INSTALL 37 | AC_PROG_LN_S 38 | AC_PROG_MAKE_SET 39 | AC_PROG_RANLIB 40 | AC_PROG_EGREP 41 | 42 | AC_USE_SYSTEM_EXTENSIONS 43 | 44 | AC_C_CONST 45 | AC_C_BIGENDIAN 46 | AC_TYPE_OFF_T 47 | AC_TYPE_SIZE_T 48 | 49 | AC_ARG_ENABLE([runtime-endian-check], 50 | AS_HELP_STRING([--disable-runtime-endian-check],[disable runtime checks for endianness]) 51 | ) 52 | 53 | AC_ARG_WITH([bash-completion], 54 | AS_HELP_STRING([--with-bash-completion[=PATH]], 55 | [Install the bash auto-completion script in this directory. @<:@default=no@:>@]), 56 | [], 57 | [with_bash_completion=no] 58 | ) 59 | 60 | AS_IF([test "x$enable_runtime_endian_check" != "xno"], [ 61 | dnl Do the stuff needed for enabling the feature 62 | AC_DEFINE([RUNTIME_ENDIAN], 1, [Define whether to check for endianness during runtime]) 63 | ]) 64 | 65 | if test "x$with_bash_completion" == "xyes"; then 66 | PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], 67 | [BASH_COMPLETION_DIR="`$PKG_CONFIG --variable=completionsdir bash-completion`"], 68 | [BASH_COMPLETION_DIR="$datadir/bash-completion/completions"]) 69 | else 70 | BASH_COMPLETION_DIR="$with_bash_completion" 71 | fi 72 | 73 | AC_CHECK_DECLS([strtol, strtoul, strtoumax, strndup]) 74 | 75 | AC_SUBST([BASH_COMPLETION_DIR]) 76 | AM_CONDITIONAL([ENABLE_BASH_COMPLETION],[test "x$with_bash_completion" != "xno"]) 77 | 78 | AC_CONFIG_FILES([Makefile src/Makefile]) 79 | AC_OUTPUT 80 | -------------------------------------------------------------------------------- /doc/UPDATE-CHECK: -------------------------------------------------------------------------------- 1 | When updating, change the following files (if needed): 2 | 3 | - Update rights. 4 | - Update ChangeLog. 5 | - man/create-man.sh (DATE, version) 6 | - Generate a new manpage. 7 | - Check for spelling errors in ChangeLog, manpage and README. 8 | - Check final manpage with man command. 9 | - Update README. 10 | - Update configure.ac (VERSION) 11 | - Test in Debian Sid. 12 | - Release extra files with make dist. 13 | -------------------------------------------------------------------------------- /man/create-man.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2015-2020 Joao Eriberto Mota Filho 4 | # Create a manpage using txt2man command. Version 2.0, 2020-06-19. 5 | # This file is part of txt2man package for Debian. 6 | # This script can be used under BSD-3-Clause license. 7 | 8 | #-------------------------------------------------------- 9 | # Don't change the following lines 10 | TEST=$(txt2man -h 2> /dev/null) 11 | [ "$TEST" ] || { echo -e "\nYou need to install txt2man, from https://github.com/mvertes/txt2man.\n"; exit 1; } 12 | 13 | function create-man { 14 | txt2man -d "$T2M_DATE" -t $T2M_NAME -r $T2M_NAME-$T2M_VERSION -s $T2M_LEVEL -v "$T2M_DESC" $T2M_NAME.txt > $T2M_NAME.$T2M_LEVEL 15 | } 16 | #-------------------------------------------------------- 17 | 18 | # Put here all data for your first manpage (in T2M lines) 19 | T2M_DATE="01 May 2025" 20 | T2M_NAME=dcfldd 21 | T2M_VERSION=1.9.3 22 | T2M_LEVEL=1 23 | T2M_DESC="enhanced version of dd for forensics and security" 24 | create-man 25 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # configure.ac, was previously configure.in (before 2019) 2 | # 3 | # Copyright ?-2002 Jim Meyering 4 | # Copyright 2002-2006 Nicholas Harbour 5 | # Copyright 2019 Joao Eriberto Mota Filho 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License along 18 | # with this program; if not, write to the Free Software Foundation, Inc., 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | bin_PROGRAMS = dcfldd 22 | 23 | AM_CFLAGS = -fgnu89-inline 24 | 25 | dcfldd_SOURCES = dcfldd.c \ 26 | md5.c md5.h \ 27 | sha1.c sha1.h \ 28 | sha2.c sha2.h \ 29 | human.c human.h \ 30 | getpagesize.h \ 31 | long-options.c long-options.h \ 32 | safe-read.c safe-read.h \ 33 | xstrtol.c xstrtol.h \ 34 | version-etc.c version-etc.h \ 35 | system.h sys2.h pathmax.h xalloc.h \ 36 | argmatch.c argmatch.h \ 37 | xstrtoul.c \ 38 | full-write.c \ 39 | xstrtoumax.c \ 40 | copy.c copy.h \ 41 | dcfldd.h \ 42 | hash.h hash.c \ 43 | verify.c verify.h \ 44 | translate.c translate.h \ 45 | sizeprobe.c sizeprobe.h \ 46 | pattern.c pattern.h \ 47 | util.c util.h \ 48 | log.c log.h \ 49 | full-write.h \ 50 | output.c output.h \ 51 | split.c split.h \ 52 | hashformat.c hashformat.h \ 53 | dcfldd_error.c dcfldd_error.h 54 | -------------------------------------------------------------------------------- /src/argmatch.c: -------------------------------------------------------------------------------- 1 | /* argmatch.c -- find a match for a string in an array 2 | Copyright 1990, 1998, 1999 Free Software Foundation, Inc. 3 | Copyright 2019 Joao Eriberto Mota Filho 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 | 19 | /* Written by David MacKenzie 20 | Modified by Akim Demaille */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | # include "config.h" 24 | #endif 25 | 26 | #include "dcfldd.h" 27 | #include "argmatch.h" 28 | #include "log.h" 29 | 30 | #include 31 | #ifdef STDC_HEADERS 32 | # include 33 | #endif 34 | 35 | #if HAVE_LOCALE_H 36 | # include 37 | #endif 38 | 39 | #if ENABLE_NLS 40 | # include 41 | # define _(Text) gettext (Text) 42 | #else 43 | # define _(Text) Text 44 | #endif 45 | 46 | /* When reporting an invalid argument, show nonprinting characters 47 | by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use 48 | literal_quoting_style. */ 49 | #ifndef ARGMATCH_QUOTING_STYLE 50 | # define ARGMATCH_QUOTING_STYLE locale_quoting_style 51 | #endif 52 | 53 | /* The following test is to work around the gross typo in 54 | systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE 55 | is defined to 0, not 1. */ 56 | #if !EXIT_FAILURE 57 | # undef EXIT_FAILURE 58 | # define EXIT_FAILURE 1 59 | #endif 60 | 61 | /* Non failing version of argmatch call this function after failing. */ 62 | #ifndef ARGMATCH_DIE 63 | # define ARGMATCH_DIE exit (EXIT_FAILURE) 64 | #endif 65 | 66 | #ifdef ARGMATCH_DIE_DECL 67 | ARGMATCH_DIE_DECL; 68 | #endif 69 | 70 | static void 71 | __argmatch_die (void) 72 | { 73 | ARGMATCH_DIE; 74 | } 75 | 76 | /* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h. 77 | Default to __argmatch_die, but allow caller to change this at run-time. */ 78 | argmatch_exit_fn argmatch_die = __argmatch_die; 79 | 80 | 81 | /* If ARG is an unambiguous match for an element of the 82 | null-terminated array ARGLIST, return the index in ARGLIST 83 | of the matched element, else -1 if it does not match any element 84 | or -2 if it is ambiguous (is a prefix of more than one element). 85 | If SENSITIVE, comparison is case sensitive. 86 | 87 | If VALLIST is none null, use it to resolve ambiguities limited to 88 | synonyms, i.e., for 89 | "yes", "yop" -> 0 90 | "no", "nope" -> 1 91 | "y" is a valid argument, for `0', and "n" for `1'. */ 92 | 93 | static int 94 | __argmatch_internal (const char *arg, const char *const *arglist, 95 | const char *vallist, size_t valsize, 96 | int case_sensitive) 97 | { 98 | int i; /* Temporary index in ARGLIST. */ 99 | size_t arglen; /* Length of ARG. */ 100 | int matchind = -1; /* Index of first nonexact match. */ 101 | int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */ 102 | 103 | arglen = strlen (arg); 104 | 105 | /* Test all elements for either exact match or abbreviated matches. */ 106 | for (i = 0; arglist[i]; i++) 107 | { 108 | if (case_sensitive 109 | ? !strncmp (arglist[i], arg, arglen) 110 | : !strncasecmp (arglist[i], arg, arglen)) 111 | { 112 | if (strlen (arglist[i]) == arglen) 113 | /* Exact match found. */ 114 | return i; 115 | else if (matchind == -1) 116 | /* First nonexact match found. */ 117 | matchind = i; 118 | else 119 | { 120 | /* Second nonexact match found. */ 121 | if (vallist == NULL 122 | || memcmp (vallist + valsize * matchind, 123 | vallist + valsize * i, valsize)) 124 | { 125 | /* There is a real ambiguity, or we could not 126 | disambiguate. */ 127 | ambiguous = 1; 128 | } 129 | } 130 | } 131 | } 132 | if (ambiguous) 133 | return -2; 134 | else 135 | return matchind; 136 | } 137 | 138 | /* argmatch - case sensitive version */ 139 | int 140 | argmatch (const char *arg, const char *const *arglist, 141 | const char *vallist, size_t valsize) 142 | { 143 | return __argmatch_internal (arg, arglist, vallist, valsize, 1); 144 | } 145 | 146 | /* argcasematch - case insensitive version */ 147 | int 148 | argcasematch (const char *arg, const char *const *arglist, 149 | const char *vallist, size_t valsize) 150 | { 151 | return __argmatch_internal (arg, arglist, vallist, valsize, 0); 152 | } 153 | 154 | /* Error reporting for argmatch. 155 | CONTEXT is a description of the type of entity that was being matched. 156 | VALUE is the invalid value that was given. 157 | PROBLEM is the return value from argmatch. */ 158 | 159 | void 160 | argmatch_invalid (const char *context, const char *value, int problem) 161 | { 162 | char *format = (problem == -1 163 | ? "invalid argument %s for `%s'" 164 | : "ambiguous argument %s for `%s'"); 165 | 166 | log_info(format, value, context); 167 | } 168 | 169 | /* List the valid arguments for argmatch. 170 | ARGLIST is the same as in argmatch. 171 | VALLIST is a pointer to an array of values. 172 | VALSIZE is the size of the elements of VALLIST */ 173 | void 174 | argmatch_valid (const char *const *arglist, 175 | const char *vallist, size_t valsize) 176 | { 177 | int i; 178 | const char *last_val = NULL; 179 | 180 | /* We try to put synonyms on the same line. The assumption is that 181 | synonyms follow each other */ 182 | fprintf (stderr, "Valid arguments are:"); 183 | for (i = 0; arglist[i]; i++) 184 | if ((i == 0) 185 | || memcmp (last_val, vallist + valsize * i, valsize)) 186 | { 187 | log_info("\n - `%s'", arglist[i]); 188 | last_val = vallist + valsize * i; 189 | } 190 | else 191 | { 192 | log_info(", `%s'", arglist[i]); 193 | } 194 | putc ('\n', stderr); 195 | } 196 | 197 | /* Never failing versions of the previous functions. 198 | 199 | CONTEXT is the context for which argmatch is called (e.g., 200 | "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, 201 | calls the (supposed never to return) function EXIT_FN. */ 202 | 203 | int 204 | __xargmatch_internal (const char *context, 205 | const char *arg, const char *const *arglist, 206 | const char *vallist, size_t valsize, 207 | int case_sensitive, 208 | argmatch_exit_fn exit_fn) 209 | { 210 | int res = __argmatch_internal (arg, arglist, 211 | vallist, valsize, 212 | case_sensitive); 213 | if (res >= 0) 214 | /* Success. */ 215 | return res; 216 | 217 | /* We failed. Explain why. */ 218 | argmatch_invalid (context, arg, res); 219 | argmatch_valid (arglist, vallist, valsize); 220 | (*exit_fn) (); 221 | 222 | return -1; /* To please the compilers. */ 223 | } 224 | 225 | /* Look for VALUE in VALLIST, an array of objects of size VALSIZE and 226 | return the first corresponding argument in ARGLIST */ 227 | const char * 228 | argmatch_to_argument (const char *value, 229 | const char *const *arglist, 230 | const char *vallist, size_t valsize) 231 | { 232 | int i; 233 | 234 | for (i = 0; arglist[i]; i++) 235 | if (!memcmp (value, vallist + valsize * i, valsize)) 236 | return arglist[i]; 237 | return NULL; 238 | } 239 | 240 | #ifdef TEST 241 | /* 242 | * Based on "getversion.c" by David MacKenzie 243 | */ 244 | char *program_name; 245 | extern const char *getenv (); 246 | 247 | /* When to make backup files. */ 248 | enum backup_type 249 | { 250 | /* Never make backups. */ 251 | none, 252 | 253 | /* Make simple backups of every file. */ 254 | simple, 255 | 256 | /* Make numbered backups of files that already have numbered backups, 257 | and simple backups of the others. */ 258 | numbered_existing, 259 | 260 | /* Make numbered backups of every file. */ 261 | numbered 262 | }; 263 | 264 | /* Two tables describing arguments (keys) and their corresponding 265 | values */ 266 | static const char *const backup_args[] = 267 | { 268 | "no", "none", "off", 269 | "simple", "never", 270 | "existing", "nil", 271 | "numbered", "t", 272 | 0 273 | }; 274 | 275 | static const enum backup_type backup_vals[] = 276 | { 277 | none, none, none, 278 | simple, simple, 279 | numbered_existing, numbered_existing, 280 | numbered, numbered 281 | }; 282 | 283 | int 284 | main (int argc, const char *const *argv) 285 | { 286 | const char *cp; 287 | enum backup_type backup_type = none; 288 | 289 | program_name = (char *) argv[0]; 290 | 291 | if (argc > 2) 292 | { 293 | fprintf(stderr, "Usage: %s [VERSION_CONTROL]\n", program_name); 294 | exit (1); 295 | } 296 | 297 | if ((cp = getenv ("VERSION_CONTROL"))) 298 | backup_type = XARGCASEMATCH ("$VERSION_CONTROL", cp, 299 | backup_args, backup_vals); 300 | 301 | if (argc == 2) 302 | backup_type = XARGCASEMATCH (program_name, argv[1], 303 | backup_args, backup_vals); 304 | 305 | printf ("The version control is `%s'\n", 306 | ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); 307 | 308 | return 0; 309 | } 310 | #endif 311 | -------------------------------------------------------------------------------- /src/argmatch.h: -------------------------------------------------------------------------------- 1 | /* argmatch.h -- definitions and prototypes for argmatch.c 2 | Copyright (C) 1990, 1998, 1999 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by David MacKenzie 19 | Modified by Akim Demaille */ 20 | 21 | #ifndef ARGMATCH_H_ 22 | # define ARGMATCH_H_ 1 23 | 24 | # if HAVE_CONFIG_H 25 | # include 26 | # endif 27 | 28 | # include 29 | 30 | # ifndef PARAMS 31 | # if defined PROTOTYPES || (defined (__STDC__) && __STDC__) 32 | # define PARAMS(args) args 33 | # else 34 | # define PARAMS(args) () 35 | # endif /* GCC. */ 36 | # endif /* Not PARAMS. */ 37 | 38 | /* Assert there are as many real arguments as there are values 39 | (argument list ends with a NULL guard). There is no execution 40 | cost, since it will be statically evalauted to `assert (0)' or 41 | `assert (1)'. Unfortunately there is no -Wassert-0. */ 42 | 43 | # undef ARRAY_CARDINALITY 44 | # define ARRAY_CARDINALITY(Array) (sizeof ((Array)) / sizeof (*(Array))) 45 | 46 | # define ARGMATCH_ASSERT(Arglist, Vallist) \ 47 | assert (ARRAY_CARDINALITY ((Arglist)) == ARRAY_CARDINALITY ((Vallist)) + 1) 48 | 49 | /* Return the index of the element of ARGLIST (NULL terminated) that 50 | matches with ARG. If VALLIST is not NULL, then use it to resolve 51 | false ambiguities (i.e., different matches of ARG but corresponding 52 | to the same values in VALLIST). */ 53 | 54 | int argmatch 55 | PARAMS ((const char *arg, const char *const *arglist, 56 | const char *vallist, size_t valsize)); 57 | int argcasematch 58 | PARAMS ((const char *arg, const char *const *arglist, 59 | const char *vallist, size_t valsize)); 60 | 61 | # define ARGMATCH(Arg, Arglist, Vallist) \ 62 | argmatch ((Arg), (Arglist), (const char *) (Vallist), sizeof (*(Vallist))) 63 | 64 | # define ARGCASEMATCH(Arg, Arglist, Vallist) \ 65 | argcasematch ((Arg), (Arglist), (const char *) (Vallist), sizeof (*(Vallist))) 66 | 67 | /* xargmatch calls this function when it fails. This function should not 68 | return. By default, this is a function that calls ARGMATCH_DIE which 69 | in turn defaults to `exit (EXIT_FAILURE)'. */ 70 | typedef void (*argmatch_exit_fn) PARAMS ((void)); 71 | extern argmatch_exit_fn argmatch_die; 72 | 73 | /* Report on stderr why argmatch failed. Report correct values. */ 74 | 75 | void argmatch_invalid 76 | PARAMS ((const char *context, const char *value, int problem)); 77 | 78 | /* Left for compatibility with the old name invalid_arg */ 79 | 80 | # define invalid_arg(Context, Value, Problem) \ 81 | argmatch_invalid ((Context), (Value), (Problem)) 82 | 83 | 84 | 85 | /* Report on stderr the list of possible arguments. */ 86 | 87 | void argmatch_valid 88 | PARAMS ((const char *const *arglist, 89 | const char *vallist, size_t valsize)); 90 | 91 | # define ARGMATCH_VALID(Arglist, Vallist) \ 92 | argmatch_valid (Arglist, (const char *) Vallist, sizeof (*(Vallist))) 93 | 94 | 95 | 96 | /* Same as argmatch, but upon failure, reports a explanation on the 97 | failure, and exits using the function EXIT_FN. */ 98 | 99 | int __xargmatch_internal 100 | PARAMS ((const char *context, 101 | const char *arg, const char *const *arglist, 102 | const char *vallist, size_t valsize, 103 | int case_sensitive, argmatch_exit_fn exit_fn)); 104 | 105 | /* Programmer friendly interface to __xargmatch_internal. */ 106 | 107 | # define XARGMATCH(Context, Arg, Arglist, Vallist) \ 108 | (Vallist [__xargmatch_internal ((Context), (Arg), (Arglist), \ 109 | (const char *) (Vallist), \ 110 | sizeof (*(Vallist)), \ 111 | 1, argmatch_die)]) 112 | 113 | # define XARGCASEMATCH(Context, Arg, Arglist, Vallist) \ 114 | (Vallist [__xargmatch_internal ((Context), (Arg), (Arglist), \ 115 | (const char *) (Vallist), \ 116 | sizeof (*(Vallist)), \ 117 | 0, argmatch_die)]) 118 | 119 | /* Convert a value into a corresponding argument. */ 120 | 121 | const char *argmatch_to_argument 122 | PARAMS ((char const *value, const char *const *arglist, 123 | const char *vallist, size_t valsize)); 124 | 125 | # define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \ 126 | argmatch_to_argument ((char const *) &(Value), (Arglist), \ 127 | (const char *) (Vallist), sizeof (*(Vallist))) 128 | 129 | #endif /* ARGMATCH_H_ */ 130 | -------------------------------------------------------------------------------- /src/copy.h: -------------------------------------------------------------------------------- 1 | /* $Id: copy.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef COPY_H 25 | #define COPY_H 26 | 27 | extern int dd_copy(void); 28 | 29 | #endif /* COPY_H */ 30 | -------------------------------------------------------------------------------- /src/dcfldd.h: -------------------------------------------------------------------------------- 1 | /* $Id: dcfldd.h,v 1.7 2005/05/19 21:00:07 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2008 David Loveall 8 | Copyright 2017-2019 Joao Eriberto Mota Filho 9 | Copyright 2022 Tibor Szolnoki 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2, or (at your option) 14 | any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software Foundation, 23 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 24 | 25 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 26 | 27 | #ifndef DCFLDD_H 28 | #define DCFLDD_H 29 | 30 | #define _FILE_OFFSET_BITS 64 31 | #define LARGEFILE_SOURCE 32 | 33 | #if HAVE_INTTYPES_H 34 | # include 35 | #endif 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include "config.h" 42 | #include "system.h" 43 | 44 | #include "hash.h" 45 | 46 | /* The official name of this program (e.g., no `g' prefix). */ 47 | #define PROGRAM_NAME "dcfldd" 48 | 49 | #define AUTHORS "dcfldd by Nicholas Harbour and others.\nGNU dd by Paul Rubin, David MacKenzie and Stuart Kemp.\nCurrently, the source code is at\nhttps://github.com/resurrecting-open-source-projects/dcfldd" 50 | 51 | #define SWAB_ALIGN_OFFSET 2 52 | 53 | #ifndef SIGINFO 54 | # define SIGINFO SIGUSR1 55 | #endif 56 | 57 | #ifndef S_TYPEISSHM 58 | # define S_TYPEISSHM(Stat_ptr) 0 59 | #endif 60 | 61 | #define ROUND_UP_OFFSET(X, M) ((M) - 1 - (((X) + (M) - 1) % (M))) 62 | #define PTR_ALIGN(Ptr, M) ((Ptr) \ 63 | + ROUND_UP_OFFSET ((char *)(Ptr) - (char *)0, (M))) 64 | 65 | #define max(a, b) ((a) > (b) ? (a) : (b)) 66 | #define min(a, b) ((a) < (b) ? (a) : (b)) 67 | #define output_char(c) \ 68 | do \ 69 | { \ 70 | obuf[oc++] = (c); \ 71 | if (oc >= output_blocksize) \ 72 | write_output (); \ 73 | } \ 74 | while (0) 75 | 76 | /* Default input and output blocksize. */ 77 | /* #define DEFAULT_BLOCKSIZE 512 */ 78 | #ifndef DEFAULT_BLOCKSIZE 79 | #define DEFAULT_BLOCKSIZE 32768 /* 32k blocksize is HUGELY more efficient 80 | * for large device IO than 512 */ 81 | #endif /* DEFAULT_BLOCKSIZE */ 82 | 83 | #ifndef DEFAULT_SPLIT_FORMAT 84 | #define DEFAULT_SPLIT_FORMAT "nnn" 85 | #endif /* DEFAULT_SPLIT_FORMAT */ 86 | 87 | #ifndef DEFAULT_HASHWINDOW_FORMAT 88 | #define DEFAULT_HASHWINDOW_FORMAT "#window_start# - #window_end#: #hash#" 89 | #endif /* DEFAULT_HASHWINDOW_FORMAT */ 90 | 91 | #ifndef DEFAULT_TOTALHASH_FORMAT 92 | #define DEFAULT_TOTALHASH_FORMAT "\nTotal (#algorithm#): #hash#" 93 | #endif /* DEFAULT_TOTALHASH_FORMAT */ 94 | 95 | #ifndef DEFAULT_HASHCONV 96 | #define DEFAULT_HASHCONV HASHCONV_BEFORE 97 | #endif /* DEFAULT_HASHCONV */ 98 | 99 | /* Conversions bit masks. */ 100 | #define C_ASCII 01 101 | #define C_EBCDIC 02 102 | #define C_IBM 04 103 | #define C_BLOCK 010 104 | #define C_UNBLOCK 020 105 | #define C_LCASE 040 106 | #define C_UCASE 0100 107 | #define C_SWAB 0200 108 | #define C_NOERROR 0400 109 | #define C_NOTRUNC 01000 110 | #define C_SYNC 02000 111 | /* Use separate input and output buffers, and combine partial input blocks. */ 112 | #define C_TWOBUFS 04000 113 | 114 | typedef enum { 115 | HASHCONV_BEFORE, 116 | HASHCONV_AFTER 117 | } hashconv_t; 118 | 119 | extern hashconv_t hashconv; 120 | 121 | extern char *program_name; 122 | 123 | extern char *input_file; 124 | extern char *output_file; 125 | 126 | extern size_t input_blocksize; 127 | extern size_t output_blocksize; 128 | extern size_t conversion_blocksize; 129 | 130 | extern uintmax_t skip_records; 131 | extern uintmax_t seek_records; 132 | extern uintmax_t max_records; 133 | extern uintmax_t max_records_extrabytes; 134 | 135 | extern int conversions_mask; 136 | extern int translation_needed; 137 | 138 | extern uintmax_t w_partial; 139 | extern uintmax_t w_full; 140 | extern uintmax_t r_partial; 141 | extern uintmax_t r_full; 142 | extern uintmax_t r_partial; 143 | extern uintmax_t r_truncate; 144 | 145 | extern int do_hash; 146 | extern int do_verify; 147 | extern int do_status; 148 | extern int do_diffwr; 149 | 150 | extern int char_is_saved; 151 | extern unsigned char saved_char; 152 | 153 | extern time_t start_time; 154 | 155 | extern ssize_t update_thresh; 156 | 157 | struct conversion 158 | { 159 | char *convname; 160 | int conversion; 161 | }; 162 | 163 | /* FIXME: Figure out where usage() is getting called from and delete this if needed */ 164 | extern void usage(int); 165 | extern void print_stats(void); 166 | extern void cleanup(void); 167 | extern inline void quit(int); 168 | 169 | extern void parse_conversion(char *); 170 | extern int hex2char(char *); 171 | 172 | #endif /* DCFLDD_H */ 173 | -------------------------------------------------------------------------------- /src/dcfldd_error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * dcfldd_error.c -- replacement for non-portable GNU libc's error() 3 | * Copyright (C) 2024 David da Silva Polverari 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "config.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | // dcfldd defines program_name and sets it to argv[0] 30 | extern char *program_name; 31 | 32 | /* 33 | * dcfldd_error(): a replacement for glibc's error() for usage within dcfldd 34 | * 35 | * WARNING: this function is not intended as a full drop-in replacement for 36 | * error(). One example difference is that glibc's error function reads the 37 | * program name from a global variable "program_invocation_name" (see "man 3 38 | * program_invocation_name") whereas the implementation here is using dcfldd's 39 | * own global variable "program_name", instead. 40 | */ 41 | 42 | void 43 | dcfldd_error(int status, int errnum, const char *format, ...) 44 | { 45 | assert(program_name != NULL); 46 | va_list args; 47 | va_start(args, format); 48 | 49 | fflush (stdout); 50 | fprintf(stderr, "%s: ", program_name); 51 | 52 | vfprintf(stderr, format, args); 53 | va_end(args); 54 | 55 | if (errnum) { 56 | fprintf(stderr, ": %s", strerror(errnum)); 57 | } 58 | 59 | fprintf(stderr, "\n"); 60 | 61 | if (status) { 62 | exit(status); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/dcfldd_error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dcfldd_error.h -- replacement for non-portable GNU libc's error() 3 | * Copyright (C) 2024 David da Silva Polverari 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef DCFLDD_ERROR_H 21 | #define DCFLDD_ERROR_H 22 | 23 | void dcfldd_error(int status, int errnum, const char *format, ...); 24 | 25 | #endif /* DCFLDD_ERROR_H */ 26 | -------------------------------------------------------------------------------- /src/full-write.c: -------------------------------------------------------------------------------- 1 | /* full-write.c -- an interface to write that retries after interrupts 2 | Copyright 1993, 1994, 1997, 1998, 2000 Free Software Foundation, Inc. 3 | Copyright 2022-2023 David Polverari 4 | Copyright 2022 Tibor Szolnoki 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2, or (at your option) 9 | any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software Foundation, 18 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | Copied largely from GNU C's cccp.c. 21 | */ 22 | 23 | #include "dcfldd.h" 24 | 25 | #if HAVE_CONFIG_H 26 | # include 27 | #endif 28 | 29 | #include 30 | #include "safe-read.h" 31 | 32 | #if HAVE_UNISTD_H 33 | # include 34 | #endif 35 | 36 | #include 37 | #ifndef errno 38 | extern int errno; 39 | #endif 40 | 41 | /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted. 42 | Return LEN upon success, write's (negative) error code otherwise. */ 43 | 44 | int 45 | full_write (int desc, const char *ptr, size_t len, int diffwr) 46 | { 47 | int total_written; 48 | 49 | total_written = 0; 50 | while (len > 0) 51 | { 52 | int written = 0; 53 | if (diffwr) { /* Check destination block content is same as the buffer */ 54 | char *rptr = NULL; 55 | off_t pos = lseek(desc, 0, SEEK_CUR); 56 | if ((pos >= 0) && (rptr = malloc(len))) { 57 | int rlen = safe_read(desc, rptr, len); 58 | if ((rlen <= 0) || (rlen != len) || (memcmp(rptr, ptr, len))) { 59 | lseek(desc, pos, SEEK_SET); 60 | } else { 61 | written = len; 62 | } 63 | free(rptr); 64 | } 65 | } 66 | if (written <= 0) { 67 | written = write (desc, ptr, len); 68 | } 69 | /* write on an old Slackware Linux 1.2.13 returns zero when 70 | I try to write more data than there is room on a floppy disk. 71 | This puts dd into an infinite loop. Reproduce with 72 | dd if=/dev/zero of=/dev/fd0. If you have this problem, 73 | consider upgrading to a newer kernel. */ 74 | if (written < 0) 75 | { 76 | #ifdef EINTR 77 | if (errno == EINTR) 78 | continue; 79 | #endif 80 | return written; 81 | } 82 | total_written += written; 83 | ptr += written; 84 | len -= written; 85 | } 86 | return total_written; 87 | } 88 | -------------------------------------------------------------------------------- /src/full-write.h: -------------------------------------------------------------------------------- 1 | /* $Id: full-write.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2022 Tibor Szolnoki 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 2, or (at your option) 12 | 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, write to the Free Software Foundation, 21 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 | 23 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 24 | 25 | #ifndef FULL_WRITE_H 26 | #define FULL_WRITE_H 27 | 28 | int full_write(int, const char *, size_t, int diffwr); 29 | 30 | #endif /* FULL_WRITE_H */ 31 | -------------------------------------------------------------------------------- /src/getpagesize.h: -------------------------------------------------------------------------------- 1 | /* Emulate getpagesize on systems that lack it. */ 2 | 3 | #ifndef HAVE_GETPAGESIZE 4 | 5 | #ifdef HAVE_UNISTD_H 6 | # include 7 | #endif 8 | 9 | #if !defined getpagesize && defined _SC_PAGESIZE 10 | # if !(defined VMS && __VMS_VER < 70000000) 11 | # define getpagesize() sysconf (_SC_PAGESIZE) 12 | # endif 13 | #endif 14 | 15 | #if !defined getpagesize && defined VMS 16 | # ifdef __ALPHA 17 | # define getpagesize() 8192 18 | # else 19 | # define getpagesize() 512 20 | # endif 21 | #endif 22 | 23 | /* This is for BeOS. */ 24 | #if !defined getpagesize && HAVE_OS_H 25 | # include 26 | # if defined B_PAGE_SIZE 27 | # define getpagesize() B_PAGE_SIZE 28 | # endif 29 | #endif 30 | 31 | #ifndef getpagesize 32 | # include 33 | # ifdef EXEC_PAGESIZE 34 | # define getpagesize() EXEC_PAGESIZE 35 | # else 36 | # ifdef NBPG 37 | # ifndef CLSIZE 38 | # define CLSIZE 1 39 | # endif 40 | # define getpagesize() (NBPG * CLSIZE) 41 | # else 42 | # ifdef NBPC 43 | # define getpagesize() NBPC 44 | # endif 45 | # endif 46 | # endif 47 | #endif 48 | 49 | #endif /* not HAVE_GETPAGESIZE */ 50 | -------------------------------------------------------------------------------- /src/hash.c: -------------------------------------------------------------------------------- 1 | /* $Id: hash.c,v 1.4 2005/05/14 23:20:30 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #include "dcfldd.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "md5.h" 31 | #include "sha1.h" 32 | #include "sha2.h" 33 | #include "hash.h" 34 | #include "log.h" 35 | 36 | hashflag_t hashflags = 0; 37 | 38 | /* Md5 global data */ 39 | MD5_CTX MD5_total_context; 40 | MD5_CTX MD5_window_context; 41 | MD5_CTX MD5_vtotal_context; 42 | MD5_CTX MD5_vwindow_context; 43 | char MD5_hashstr[MD5_DIGEST_STRING_LENGTH + 1] = {'\0'}; 44 | 45 | /* SHA1 global data */ 46 | SHA1Context SHA1_total_context; 47 | SHA1Context SHA1_window_context; 48 | SHA1Context SHA1_vtotal_context; 49 | SHA1Context SHA1_vwindow_context; 50 | char SHA1_hashstr[SHA1_DIGEST_STRING_LENGTH + 1] = {'\0'}; 51 | 52 | /* SHA256 global data */ 53 | SHA256_CTX SHA256_total_context; 54 | SHA256_CTX SHA256_window_context; 55 | SHA256_CTX SHA256_vtotal_context; 56 | SHA256_CTX SHA256_vwindow_context; 57 | char SHA256_hashstr[SHA256_DIGEST_STRING_LENGTH + 1] = {'\0'}; 58 | 59 | /* SHA384 global data */ 60 | SHA384_CTX SHA384_total_context; 61 | SHA384_CTX SHA384_window_context; 62 | SHA384_CTX SHA384_vtotal_context; 63 | SHA384_CTX SHA384_vwindow_context; 64 | char SHA384_hashstr[SHA384_DIGEST_STRING_LENGTH + 1] = {'\0'}; 65 | 66 | /* SHA512 global data */ 67 | SHA512_CTX SHA512_total_context; 68 | SHA512_CTX SHA512_window_context; 69 | SHA512_CTX SHA512_vtotal_context; 70 | SHA512_CTX SHA512_vwindow_context; 71 | char SHA512_hashstr[SHA512_DIGEST_STRING_LENGTH + 1] = {'\0'}; 72 | 73 | off_t hash_windowlen = 0; 74 | off_t window_beginning = 0; 75 | off_t bytes_in_window = 0; 76 | off_t bytes_in_total = 0; 77 | 78 | void (*hashinit)(void *); 79 | void (*hashupdate)(void *, const void *, size_t); 80 | void (*hashfinal)(void *, void *); 81 | 82 | void *hashstr_buf; 83 | size_t hashstr_buf_size; 84 | 85 | FILE *hash_log; 86 | 87 | /* Hash algorithms */ 88 | 89 | void MD5InitGeneric(void * mdContext) { 90 | MD5Init((MD5_CTX *)mdContext); 91 | } 92 | 93 | void MD5UpdateGeneric(void * mdContext, const void * inBuf, size_t inLen) { 94 | assert(inLen <= (size_t)UINT_MAX); 95 | MD5Update((MD5_CTX *)mdContext, (const unsigned char *)inBuf, (unsigned int)inLen); 96 | } 97 | 98 | void MD5FinalGeneric(void * mdContext, void * buf) { 99 | MD5Final((MD5_CTX *)mdContext, (char *)buf); 100 | } 101 | 102 | void SHA1InitGeneric(void * sc) { 103 | SHA1Init((SHA1Context *)sc); 104 | } 105 | 106 | void SHA1UpdateGeneric(void * sc, const void * vdata, size_t len) { 107 | assert(len <= (size_t)0xFFFFFFFFu); 108 | SHA1Update((SHA1Context *)sc, vdata, (uint32_t)len); 109 | } 110 | 111 | void SHA1EndGeneric(void * sc, void * hashstrbuf) { 112 | SHA1End((SHA1Context *)sc, (char *)hashstrbuf); 113 | } 114 | 115 | void SHA256_Init_Generic(void * context) { 116 | SHA256_Init((SHA256_CTX *)context); 117 | } 118 | 119 | void SHA256_Update_Generic(void * context, const void * data, size_t len) { 120 | SHA256_Update((SHA256_CTX *)context, (const sha2_byte *)data, len); 121 | } 122 | 123 | void SHA256_End_Generic(void * context, void * buffer) { 124 | SHA256_End((SHA256_CTX *)context, (char *)buffer); 125 | } 126 | 127 | void SHA384_Init_Generic(void * context) { 128 | SHA384_Init((SHA384_CTX *)context); 129 | } 130 | 131 | void SHA384_Update_Generic(void * context, const void * data, size_t len) { 132 | SHA384_Update((SHA384_CTX *)context, (const sha2_byte *)data, len); 133 | } 134 | 135 | void SHA384_End_Generic(void * context, void * buffer) { 136 | SHA384_End((SHA384_CTX *)context, (char *)buffer); 137 | } 138 | 139 | void SHA512_Init_Generic(void * context) { 140 | SHA512_Init((SHA512_CTX *)context); 141 | } 142 | 143 | void SHA512_Update_Generic(void * context, const void * data, size_t len) { 144 | SHA512_Update((SHA512_CTX *)context, (const sha2_byte *)data, len); 145 | } 146 | 147 | void SHA512_End_Generic(void * context, void * buffer) { 148 | SHA512_End((SHA512_CTX *)context, (char *)buffer); 149 | } 150 | 151 | hashlist_t *ihashlist; 152 | 153 | hashtype_t hashops[] = 154 | { 155 | {"md5", 156 | 1, 157 | &MD5_window_context, 158 | &MD5_total_context, 159 | &MD5_vwindow_context, 160 | &MD5_vtotal_context, 161 | MD5InitGeneric, 162 | MD5UpdateGeneric, 163 | MD5FinalGeneric, 164 | &MD5_hashstr[0], 165 | sizeof (MD5_hashstr), 166 | NULL}, 167 | 168 | {"sha1", 169 | 1<<1, 170 | &SHA1_window_context, 171 | &SHA1_total_context, 172 | &SHA1_vwindow_context, 173 | &SHA1_vtotal_context, 174 | SHA1InitGeneric, 175 | SHA1UpdateGeneric, 176 | SHA1EndGeneric, 177 | &SHA1_hashstr[0], 178 | sizeof (SHA1_hashstr), 179 | NULL}, 180 | 181 | {"sha256", 182 | 1<<2, 183 | &SHA256_window_context, 184 | &SHA256_total_context, 185 | &SHA256_vwindow_context, 186 | &SHA256_vtotal_context, 187 | SHA256_Init_Generic, 188 | SHA256_Update_Generic, 189 | SHA256_End_Generic, 190 | SHA256_hashstr, 191 | sizeof (SHA256_hashstr), 192 | NULL}, 193 | 194 | {"sha384", 195 | 1<<3, 196 | &SHA384_window_context, 197 | &SHA384_total_context, 198 | &SHA384_vwindow_context, 199 | &SHA384_vtotal_context, 200 | SHA384_Init_Generic, 201 | SHA384_Update_Generic, 202 | SHA384_End_Generic, 203 | &SHA384_hashstr[0], 204 | sizeof (SHA384_hashstr), 205 | NULL}, 206 | 207 | {"sha512", 208 | 1<<4, 209 | &SHA512_window_context, 210 | &SHA512_total_context, 211 | &SHA512_vwindow_context, 212 | &SHA512_vtotal_context, 213 | SHA512_Init_Generic, 214 | SHA512_Update_Generic, 215 | SHA512_End_Generic, 216 | &SHA512_hashstr[0], 217 | sizeof (SHA512_hashstr), 218 | NULL}, 219 | 220 | {NULL, 221 | 0, 222 | NULL, 223 | NULL, 224 | NULL, 225 | NULL, 226 | (void (*)(void *)) NULL, 227 | (void (*)(void *, const void *, size_t)) NULL, 228 | (void (*)(void *, void *)) NULL, 229 | NULL, 230 | 0, 231 | NULL} 232 | }; 233 | 234 | static void add_hash(hashlist_t **hashlist, int hash) 235 | { 236 | hashlist_t *hlptr = *hashlist; 237 | int i; 238 | 239 | if (hlptr == NULL) { 240 | hlptr = malloc(sizeof (hashlist_t)); 241 | *hashlist = hlptr; 242 | } else { 243 | for ( ; hlptr->next != NULL; hlptr = hlptr->next) 244 | ; 245 | hlptr->next = malloc(sizeof (hashlist_t)); 246 | hlptr = hlptr->next; 247 | } 248 | 249 | hlptr->next = NULL; 250 | hlptr->hash = &hashops[hash]; 251 | } 252 | 253 | /* add all the appropriate hashops according to the flags */ 254 | void init_hashlist(hashlist_t **hashlist, hashflag_t flags) 255 | { 256 | int i; 257 | 258 | for (i = 0; hashops[i].name != NULL; i++) 259 | if (hashops[i].flag & flags) 260 | add_hash(hashlist, i); 261 | } 262 | 263 | /* not to be confused with init_hashlist, this function calls 264 | * the hashtype specific init function for each hash type in 265 | * the list */ 266 | void hashl_init(hashlist_t *hashlist, int context) 267 | { 268 | hashlist_t *hptr; 269 | 270 | for (hptr = hashlist; hptr != NULL; hptr = hptr->next) { 271 | void *ctx; 272 | 273 | switch (context) { 274 | case WINDOW_CTX: 275 | ctx = hptr->hash->window_context; 276 | break; 277 | case TOTAL_CTX: 278 | ctx = hptr->hash->total_context; 279 | break; 280 | case VWINDOW_CTX: 281 | ctx = hptr->hash->vwindow_context; 282 | break; 283 | case VTOTAL_CTX: 284 | ctx = hptr->hash->vtotal_context; 285 | break; 286 | default: 287 | internal_error("unreachable branch encountered in hashl_init()"); 288 | break; 289 | } 290 | 291 | (hptr->hash->init)(ctx); 292 | } 293 | } 294 | 295 | void hashl_update(hashlist_t *hashlist, int context, const void *buf, size_t len) 296 | { 297 | hashlist_t *hptr; 298 | 299 | for (hptr = hashlist; hptr != NULL; hptr = hptr->next) { 300 | void *ctx; 301 | 302 | switch (context) { 303 | case WINDOW_CTX: 304 | ctx = hptr->hash->window_context; 305 | break; 306 | case TOTAL_CTX: 307 | ctx = hptr->hash->total_context; 308 | break; 309 | case VWINDOW_CTX: 310 | ctx = hptr->hash->vwindow_context; 311 | break; 312 | case VTOTAL_CTX: 313 | ctx = hptr->hash->vtotal_context; 314 | break; 315 | default: 316 | internal_error("unreachable branch encountered in hashl_update()"); 317 | break; 318 | } 319 | 320 | (hptr->hash->update)(ctx, buf, len); 321 | } 322 | } 323 | 324 | void hashl_final(hashlist_t *hashlist, int context) 325 | { 326 | hashlist_t *hptr; 327 | 328 | for (hptr = hashlist; hptr != NULL; hptr = hptr->next) { 329 | void *ctx; 330 | 331 | switch (context) { 332 | case WINDOW_CTX: 333 | ctx = hptr->hash->window_context; 334 | break; 335 | case TOTAL_CTX: 336 | ctx = hptr->hash->total_context; 337 | break; 338 | case VWINDOW_CTX: 339 | ctx = hptr->hash->vwindow_context; 340 | break; 341 | case VTOTAL_CTX: 342 | ctx = hptr->hash->vtotal_context; 343 | break; 344 | default: 345 | internal_error("unreachable branch encountered in hashl_final()"); 346 | break; 347 | } 348 | 349 | /* note that this writes the hash string to the global buffer 350 | * for the specific hashtype, when calling this multiple times 351 | * (i.e. like in verify) copy that buffer out before finalizing 352 | * another list */ 353 | (hptr->hash->final)(ctx, hptr->hash->hashstr_buf); 354 | } 355 | } 356 | 357 | void hash_update_buf(hashlist_t *hashlist, int winctx, int ttlctx, 358 | void *buf, size_t len) 359 | { 360 | if (hash_windowlen != 0) { 361 | hashl_update(hashlist, winctx, buf, len); 362 | if (winctx == WINDOW_CTX) /* don't do this for verify or you'll get double */ 363 | bytes_in_window += len; 364 | } 365 | hashl_update(hashlist, ttlctx, buf, len); 366 | 367 | if(ttlctx == TOTAL_CTX) 368 | bytes_in_total += len; 369 | } 370 | 371 | void hash_update(hashlist_t *hashlist, void *buf, size_t len) 372 | { 373 | size_t left_in_window = hash_windowlen - bytes_in_window; 374 | 375 | if (bytes_in_total == 0) 376 | hashl_init(hashlist, TOTAL_CTX); 377 | 378 | if (hash_windowlen == 0) 379 | hash_update_buf(hashlist, WINDOW_CTX, TOTAL_CTX, buf, len); 380 | else { 381 | if (bytes_in_window == 0) 382 | hashl_init(hashlist, WINDOW_CTX); 383 | 384 | if (len >= left_in_window) { 385 | hash_update_buf(hashlist, WINDOW_CTX, TOTAL_CTX, buf, left_in_window); 386 | hashl_final(hashlist, WINDOW_CTX); 387 | display_windowhash(hashlist, hash_windowlen); 388 | window_beginning += hash_windowlen; 389 | bytes_in_window = 0; 390 | hash_update(hashlist, buf + left_in_window, len - left_in_window); 391 | } else 392 | hash_update_buf(hashlist, WINDOW_CTX, TOTAL_CTX, buf, len); 393 | } 394 | } 395 | 396 | void display_windowhash(hashlist_t *hashlist, off_t windowlen) 397 | { 398 | hashlist_t *hptr; 399 | 400 | for (hptr = hashlist; hptr != NULL; hptr = hptr->next) 401 | log_hashwindow(hptr->hash, window_beginning, (window_beginning + windowlen), 402 | input_blocksize, hptr->hash->hashstr_buf); 403 | } 404 | 405 | void display_totalhash(hashlist_t *hashlist, int ttlctx) 406 | { 407 | hashlist_t *hptr; 408 | 409 | hashl_final(hashlist, ttlctx); 410 | 411 | for (hptr = hashlist; hptr != NULL; hptr = hptr->next) 412 | log_hashtotal(hptr->hash, 0, 0, 413 | input_blocksize, hptr->hash->hashstr_buf); 414 | } 415 | 416 | void hash_remainder(hashlist_t *hashlist, int winctx) 417 | { 418 | if (hash_windowlen > 0 && bytes_in_window > 0) { 419 | hashl_final(hashlist, winctx); 420 | display_windowhash(hashlist, bytes_in_window); 421 | } 422 | } 423 | -------------------------------------------------------------------------------- /src/hash.h: -------------------------------------------------------------------------------- 1 | /* $Id: hash.h,v 1.4 2005/05/14 23:20:30 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2012 Miah Gregory 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 2, or (at your option) 12 | 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, write to the Free Software Foundation, 21 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 | 23 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 24 | 25 | #ifndef HASH_H 26 | #define HASH_H 27 | 28 | #include "dcfldd.h" 29 | #include "md5.h" 30 | #include "sha1.h" 31 | #include "sha2.h" 32 | 33 | #include 34 | #include 35 | 36 | /* bytes_in_window and bytes_in_total are only used for dd_copy() */ 37 | extern off_t bytes_in_window; 38 | extern off_t bytes_in_total; 39 | 40 | extern void (*hashinit)(void *); 41 | extern void (*hashupdate)(void *, const void *, size_t); 42 | extern void (*hashfinal)(void *, void *); 43 | 44 | extern void *hashstr_buf; 45 | extern size_t hashstr_buf_size; 46 | 47 | typedef uint32_t hashflag_t; 48 | 49 | extern hashflag_t hashflags; 50 | 51 | typedef struct hashtype 52 | { 53 | char *name; 54 | hashflag_t flag; 55 | void *window_context; 56 | void *total_context; 57 | void *vwindow_context; 58 | void *vtotal_context; 59 | void (*init)(void *); 60 | void (*update)(void *, const void *, size_t); 61 | void (*final)(void *, void *); 62 | void *hashstr_buf; 63 | size_t hashstr_buf_size; 64 | FILE *log; 65 | } hashtype_t; 66 | 67 | typedef struct hashlist_s 68 | { 69 | struct hashlist_s *next; 70 | hashtype_t *hash; 71 | } hashlist_t; 72 | 73 | extern hashlist_t *ihashlist; 74 | 75 | extern struct hashtype hashops[]; 76 | 77 | extern FILE *hash_log; 78 | 79 | /* this enum order must correspond to their position in the hashops[] array */ 80 | enum {MD5 = 0, SHA1, SHA256, SHA384, SHA512}; 81 | 82 | enum {WINDOW_CTX, TOTAL_CTX, VWINDOW_CTX, VTOTAL_CTX}; 83 | 84 | #ifndef VERIFY_HASH 85 | #define VERIFY_HASH MD5 86 | #endif 87 | 88 | #ifndef DEFAULT_HASH 89 | #define DEFAULT_HASH MD5 90 | #endif 91 | 92 | extern off_t bytes_in_window; 93 | extern off_t bytes_in_total; 94 | extern off_t hash_windowlen; 95 | extern off_t window_beginning; 96 | 97 | extern void display_windowhash(hashlist_t *, off_t); 98 | extern void display_totalhash(hashlist_t *, int); 99 | extern void hash_update(hashlist_t *, void *, size_t); 100 | extern void hash_update_buf(hashlist_t *, int, int, void *, size_t); 101 | extern void hash_remainder(hashlist_t *, int); 102 | 103 | extern void init_hashlist(hashlist_t **hashlist, hashflag_t flags); 104 | 105 | /* inner hashl_* funcitons are for iterating over hashlists */ 106 | extern void hashl_init(hashlist_t *, int); 107 | extern void hashl_update(hashlist_t *, int, const void *, size_t); 108 | extern void hashl_final(hashlist_t *, int); 109 | 110 | #endif /* HASH_H */ 111 | -------------------------------------------------------------------------------- /src/hashformat.c: -------------------------------------------------------------------------------- 1 | /* $Id: hashformat.c,v 1.2 2005/05/15 13:18:27 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #include "dcfldd.h" 25 | #include "hashformat.h" 26 | #include "log.h" 27 | #include "util.h" 28 | #include "sys2.h" 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | format_t *hashformat = NULL; 36 | format_t *totalhashformat = NULL; 37 | 38 | static fmtatom_op_t fmt_string_op; 39 | static fmtatom_op_t fmt_window_start_op; 40 | static fmtatom_op_t fmt_window_end_op; 41 | static fmtatom_op_t fmt_winblk_start_op; 42 | static fmtatom_op_t fmt_winblk_end_op; 43 | static fmtatom_op_t fmt_algorithm_op; 44 | 45 | static fmtatom_op_t *fmtatom_op_table[] = 46 | { /* order must conform to fmtatom_t enum */ 47 | fmt_string_op, 48 | fmt_window_start_op, 49 | fmt_window_end_op, 50 | fmt_winblk_start_op, 51 | fmt_winblk_end_op, 52 | fmt_string_op, 53 | fmt_algorithm_op 54 | }; 55 | 56 | static void add_fmtatom(format_t **, fmtatom_t, void *); 57 | 58 | static void add_fmtatom(format_t **format, fmtatom_t atom, void *data) 59 | { 60 | format_t *fmt; 61 | 62 | if (*format == NULL) { 63 | *format = malloc(sizeof **format); 64 | fmt = *format; 65 | } else { 66 | /* cycle to the end of the list */ 67 | for (fmt = *format; fmt->next != NULL; fmt = fmt->next) 68 | ; 69 | fmt->next = malloc(sizeof *fmt); 70 | fmt = fmt->next; 71 | } 72 | 73 | fmt->next = NULL; 74 | fmt->type = atom; 75 | fmt->op = fmtatom_op_table[atom]; 76 | fmt->data = data; 77 | } 78 | 79 | format_t *parse_hashformat(char *str) 80 | { 81 | format_t *fmt = NULL; 82 | int i; 83 | 84 | if (str == NULL || strlen(str) == 0) 85 | return NULL; 86 | 87 | replace_escapes(str); 88 | 89 | if (*str == VARIABLE_HOOK) { 90 | for (i = 1; str[i] != '\0' && str[i] != VARIABLE_HOOK; i++) 91 | ; 92 | if (str[i] == '\0') 93 | user_error("invalid variable specifier \"%s\", variables should be terminated with another \'%c\'", str, VARIABLE_HOOK); 94 | else if (i == 1) { 95 | /* if there is two HOOKs with nothing between, remove the second and 96 | * push up all the following chars one position */ 97 | for (i = 0; str[i] != '\0'; i++) 98 | str[i] = str[i + 1]; 99 | } else { 100 | str[i] = '\0'; 101 | str++; 102 | if (STREQ(str, "window_start")) 103 | add_fmtatom(&fmt, FMT_WINDOW_START, NULL); 104 | else if (STREQ(str, "window_end")) 105 | add_fmtatom(&fmt, FMT_WINDOW_END, NULL); 106 | else if (STREQ(str, "block_start")) 107 | add_fmtatom(&fmt, FMT_WINBLK_START, NULL); 108 | else if (STREQ(str, "block_end")) 109 | add_fmtatom(&fmt, FMT_WINBLK_END, NULL); 110 | else if (STREQ(str, "hash")) 111 | add_fmtatom(&fmt, FMT_HASH, NULL); 112 | else if (STREQ(str, "algorithm")) 113 | add_fmtatom(&fmt, FMT_ALGORITHM, NULL); 114 | else 115 | user_error("invalid variable specifier \"%c%s%c\"", 116 | VARIABLE_HOOK, str, VARIABLE_HOOK); 117 | fmt->next = parse_hashformat(&str[i]); 118 | return fmt; 119 | } 120 | } 121 | 122 | /* this loop needs to start at 1 so that "$$" will display a '$' properly */ 123 | for (i = 1; str[i] != '\0' && str[i] != VARIABLE_HOOK; i++) 124 | ; 125 | 126 | add_fmtatom(&fmt, FMT_STRING, strndup(str, i)); 127 | fmt->next = parse_hashformat(&str[i]); 128 | 129 | return fmt; 130 | } 131 | 132 | void print_fmt(format_t *fmt, FMTATOMOP_ARGS) 133 | { 134 | for (; fmt != NULL; fmt = fmt->next) 135 | (fmt->op)(stream, wina, winb, blksize, alg, fmt->data == NULL ? data : fmt->data); 136 | fputc('\n', stream); 137 | } 138 | 139 | static void fmt_string_op(FMTATOMOP_ARGS) 140 | { 141 | char *str = (char *)data; 142 | fputs(str, stream); 143 | } 144 | 145 | static void fmt_window_start_op(FMTATOMOP_ARGS) 146 | { 147 | fprintf(stream, "%llu", (unsigned long long int) wina); 148 | } 149 | 150 | static void fmt_window_end_op(FMTATOMOP_ARGS) 151 | { 152 | fprintf(stream, "%llu", (unsigned long long int) winb); 153 | } 154 | 155 | static void fmt_winblk_start_op(FMTATOMOP_ARGS) 156 | { 157 | fprintf(stream, "%llu", (unsigned long long int) wina / blksize); 158 | } 159 | 160 | static void fmt_winblk_end_op(FMTATOMOP_ARGS) 161 | { 162 | fprintf(stream, "%llu", (unsigned long long int) winb / blksize); 163 | } 164 | 165 | static void fmt_algorithm_op(FMTATOMOP_ARGS) 166 | { 167 | fputs(alg, stream); 168 | } 169 | -------------------------------------------------------------------------------- /src/hashformat.h: -------------------------------------------------------------------------------- 1 | /* $Id: hashformat.h,v 1.1 2005/05/14 23:20:30 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef HASH_FORMAT_H 25 | #define HASH_FORMAT_H 26 | 27 | #include "dcfldd.h" 28 | #include "hash.h" 29 | #include 30 | #include 31 | 32 | typedef enum { 33 | FMT_STRING, 34 | FMT_WINDOW_START, 35 | FMT_WINDOW_END, 36 | FMT_WINBLK_START, /* window offsets / blocksize */ 37 | FMT_WINBLK_END, 38 | FMT_HASH, 39 | FMT_ALGORITHM 40 | } fmtatom_t; 41 | 42 | #define FMTATOMOP_ARGS FILE *stream, off_t wina, off_t winb, size_t blksize, char *alg, void *data 43 | 44 | typedef void (fmtatom_op_t)(FMTATOMOP_ARGS); 45 | 46 | #ifndef VARIABLE_HOOK 47 | #define VARIABLE_HOOK '#' 48 | #endif 49 | 50 | typedef struct format_s { 51 | struct format_s *next; 52 | fmtatom_t type; 53 | fmtatom_op_t *op; 54 | void *data; /* optional */ 55 | } format_t; 56 | 57 | extern format_t *hashformat; 58 | extern format_t *totalhashformat; 59 | 60 | extern void print_fmt(format_t *, FMTATOMOP_ARGS); 61 | extern format_t *parse_hashformat(char *); 62 | 63 | #endif /* HASH_FORMAT_H */ 64 | -------------------------------------------------------------------------------- /src/human.c: -------------------------------------------------------------------------------- 1 | /* human.c -- print human readable file size 2 | Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Originally contributed by lm@sgi.com; 19 | --si, output block size selection, and large file support 20 | added by eggert@twinsun.com. */ 21 | 22 | #if HAVE_CONFIG_H 23 | # include 24 | #endif 25 | 26 | #include 27 | #include 28 | 29 | #if HAVE_LIMITS_H 30 | # include 31 | #endif 32 | 33 | #if HAVE_STRING_H 34 | # include 35 | #else 36 | # include 37 | #endif 38 | 39 | #ifndef CHAR_BIT 40 | # define CHAR_BIT 8 41 | #endif 42 | #if HAVE_STDLIB_H 43 | # include 44 | #endif 45 | 46 | #if ENABLE_NLS 47 | # include 48 | # define _(Text) gettext (Text) 49 | #else 50 | # define _(Text) Text 51 | #endif 52 | 53 | #include 54 | #include 55 | 56 | #include "human.h" 57 | 58 | static const char suffixes[] = 59 | { 60 | 0, /* not used */ 61 | 'k', /* kilo */ 62 | 'M', /* Mega */ 63 | 'G', /* Giga */ 64 | 'T', /* Tera */ 65 | 'P', /* Peta */ 66 | 'E', /* Exa */ 67 | 'Z', /* Zetta */ 68 | 'Y' /* Yotta */ 69 | }; 70 | 71 | /* If INEXACT_STYLE is not human_round_to_even, and if easily 72 | possible, adjust VALUE according to the style. */ 73 | static double 74 | adjust_value (enum human_inexact_style inexact_style, double value) 75 | { 76 | /* Do not use the floor or ceil functions, as that would mean 77 | linking with the standard math library, which is a porting pain. 78 | So leave the value alone if it is too large to easily round. */ 79 | if (inexact_style != human_round_to_even && value < (uintmax_t) -1) 80 | { 81 | uintmax_t u = value; 82 | value = u + (inexact_style == human_ceiling && u != value); 83 | } 84 | 85 | return value; 86 | } 87 | 88 | /* Like human_readable_inexact, except always round to even. */ 89 | char * 90 | human_readable (uintmax_t n, char *buf, 91 | int from_block_size, int output_block_size) 92 | { 93 | return human_readable_inexact (n, buf, from_block_size, output_block_size, 94 | human_round_to_even); 95 | } 96 | 97 | /* Convert N to a human readable format in BUF. 98 | 99 | N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must 100 | be nonnegative. 101 | 102 | OUTPUT_BLOCK_SIZE must be nonzero. If it is positive, use units of 103 | OUTPUT_BLOCK_SIZE in the output number. 104 | 105 | Use INEXACT_STYLE to determine whether to take the ceiling or floor 106 | of any result that cannot be expressed exactly. 107 | 108 | If OUTPUT_BLOCK_SIZE is negative, use a format like "127k" if 109 | possible, using powers of -OUTPUT_BLOCK_SIZE; otherwise, use 110 | ordinary decimal format. Normally -OUTPUT_BLOCK_SIZE is either 111 | 1000 or 1024; it must be at least 2. Most people visually process 112 | strings of 3-4 digits effectively, but longer strings of digits are 113 | more prone to misinterpretation. Hence, converting to an 114 | abbreviated form usually improves readability. Use a suffix 115 | indicating which power is being used. For example, assuming 116 | -OUTPUT_BLOCK_SIZE is 1024, 8500 would be converted to 8.3k, 117 | 133456345 to 127M, 56990456345 to 53G, and so on. Numbers smaller 118 | than -OUTPUT_BLOCK_SIZE aren't modified. */ 119 | 120 | char * 121 | human_readable_inexact (uintmax_t n, char *buf, 122 | int from_block_size, int output_block_size, 123 | enum human_inexact_style inexact_style) 124 | { 125 | uintmax_t amt; 126 | int base; 127 | int to_block_size; 128 | int tenths = 0; 129 | int power; 130 | char *p; 131 | 132 | /* 0 means adjusted N == AMT.TENTHS; 133 | 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05; 134 | 2 means adjusted N == AMT.TENTHS + 0.05; 135 | 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */ 136 | int rounding = 0; 137 | 138 | if (output_block_size < 0) 139 | { 140 | base = -output_block_size; 141 | to_block_size = 1; 142 | } 143 | else 144 | { 145 | base = 0; 146 | to_block_size = output_block_size; 147 | } 148 | 149 | p = buf + LONGEST_HUMAN_READABLE; 150 | *p = '\0'; 151 | 152 | #ifdef lint 153 | /* Suppress `used before initialized' warning. */ 154 | power = 0; 155 | #endif 156 | 157 | /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE units. */ 158 | 159 | { 160 | int multiplier; 161 | int divisor; 162 | int r2; 163 | int r10; 164 | if (to_block_size <= from_block_size 165 | ? (from_block_size % to_block_size != 0 166 | || (multiplier = from_block_size / to_block_size, 167 | (amt = n * multiplier) / multiplier != n)) 168 | : (from_block_size == 0 169 | || to_block_size % from_block_size != 0 170 | || (divisor = to_block_size / from_block_size, 171 | r10 = (n % divisor) * 10, 172 | r2 = (r10 % divisor) * 2, 173 | amt = n / divisor, 174 | tenths = r10 / divisor, 175 | rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2), 176 | 0))) 177 | { 178 | /* Either the result cannot be computed easily using uintmax_t, 179 | or from_block_size is zero. Fall back on floating point. 180 | FIXME: This can yield answers that are slightly off. */ 181 | 182 | double damt = n * (from_block_size / (double) to_block_size); 183 | 184 | if (! base) 185 | sprintf (buf, "%.0f", adjust_value (inexact_style, damt)); 186 | else 187 | { 188 | double e = 1; 189 | power = 0; 190 | 191 | do 192 | { 193 | e *= base; 194 | power++; 195 | } 196 | while (e * base <= damt && power < sizeof suffixes - 1); 197 | 198 | damt /= e; 199 | 200 | sprintf (buf, "%.1f%c", adjust_value (inexact_style, damt), 201 | suffixes[power]); 202 | if (4 < strlen (buf)) 203 | sprintf (buf, "%.0f%c", 204 | adjust_value (inexact_style, damt * 10) / 10, 205 | suffixes[power]); 206 | } 207 | 208 | return buf; 209 | } 210 | } 211 | 212 | /* Use power of BASE notation if adjusted AMT is large enough. */ 213 | 214 | if (base && base <= amt) 215 | { 216 | power = 0; 217 | 218 | do 219 | { 220 | int r10 = (amt % base) * 10 + tenths; 221 | int r2 = (r10 % base) * 2 + (rounding >> 1); 222 | amt /= base; 223 | tenths = r10 / base; 224 | rounding = (r2 < base 225 | ? 0 < r2 + rounding 226 | : 2 + (base < r2 + rounding)); 227 | power++; 228 | } 229 | while (base <= amt && power < sizeof suffixes - 1); 230 | 231 | *--p = suffixes[power]; 232 | 233 | if (amt < 10) 234 | { 235 | if (2 * (1 - (int) inexact_style) 236 | < rounding + (tenths & (inexact_style == human_round_to_even))) 237 | { 238 | tenths++; 239 | rounding = 0; 240 | 241 | if (tenths == 10) 242 | { 243 | amt++; 244 | tenths = 0; 245 | } 246 | } 247 | 248 | if (amt < 10) 249 | { 250 | *--p = '0' + tenths; 251 | *--p = '.'; 252 | tenths = rounding = 0; 253 | } 254 | } 255 | } 256 | 257 | if (inexact_style == human_ceiling 258 | ? 0 < tenths + rounding 259 | : inexact_style == human_round_to_even 260 | ? 5 < tenths + (2 < rounding + (amt & 1)) 261 | : /* inexact_style == human_floor */ 0) 262 | { 263 | amt++; 264 | 265 | if (amt == base && power < sizeof suffixes - 1) 266 | { 267 | *p = suffixes[power + 1]; 268 | *--p = '0'; 269 | *--p = '.'; 270 | amt = 1; 271 | } 272 | } 273 | 274 | do 275 | *--p = '0' + (int) (amt % 10); 276 | while ((amt /= 10) != 0); 277 | 278 | return p; 279 | } 280 | 281 | 282 | /* The default block size used for output. This number may change in 283 | the future as disks get larger. */ 284 | #ifndef DEFAULT_BLOCK_SIZE 285 | # define DEFAULT_BLOCK_SIZE 1024 286 | #endif 287 | 288 | static char const *const block_size_args[] = { "human-readable", "si", 0 }; 289 | static int const block_size_types[] = { -1024, -1000 }; 290 | 291 | static int 292 | default_block_size (void) 293 | { 294 | return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE; 295 | } 296 | 297 | static strtol_error 298 | humblock (char const *spec, int *block_size) 299 | { 300 | int i; 301 | 302 | if (! spec && ! (spec = getenv ("BLOCK_SIZE"))) 303 | *block_size = default_block_size (); 304 | else if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_types))) 305 | *block_size = block_size_types[i]; 306 | else 307 | { 308 | char *ptr; 309 | unsigned long val; 310 | strtol_error e = xstrtoul (spec, &ptr, 0, &val, "eEgGkKmMpPtTyYzZ0"); 311 | if (e != LONGINT_OK) 312 | return e; 313 | if (*ptr) 314 | return LONGINT_INVALID_SUFFIX_CHAR; 315 | if ((int) val < 0 || val != (int) val) 316 | return LONGINT_OVERFLOW; 317 | *block_size = (int) val; 318 | } 319 | 320 | return LONGINT_OK; 321 | } 322 | 323 | void 324 | human_block_size (char const *spec, int report_errors, int *block_size) 325 | { 326 | strtol_error e = humblock (spec, block_size); 327 | if (*block_size == 0) 328 | { 329 | *block_size = default_block_size (); 330 | e = LONGINT_INVALID; 331 | } 332 | if (e != LONGINT_OK && report_errors) 333 | fprintf(stderr, "Invalid block size entered\n"); 334 | } 335 | -------------------------------------------------------------------------------- /src/human.h: -------------------------------------------------------------------------------- 1 | #ifndef HUMAN_H_ 2 | # define HUMAN_H_ 1 3 | 4 | # if HAVE_CONFIG_H 5 | # include 6 | # endif 7 | 8 | # if HAVE_INTTYPES_H 9 | # include 10 | # endif 11 | 12 | /* A conservative bound on the maximum length of a human-readable string. 13 | The output can be the product of the largest uintmax_t and the largest int, 14 | so add their sizes before converting to a bound on digits. */ 15 | # define LONGEST_HUMAN_READABLE ((sizeof (uintmax_t) + sizeof (int)) \ 16 | * CHAR_BIT / 3) 17 | 18 | # ifndef PARAMS 19 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 20 | # define PARAMS(Args) Args 21 | # else 22 | # define PARAMS(Args) () 23 | # endif 24 | # endif 25 | 26 | enum human_inexact_style 27 | { 28 | human_floor = -1, 29 | human_round_to_even = 0, 30 | human_ceiling = 1 31 | }; 32 | 33 | char *human_readable PARAMS ((uintmax_t, char *, int, int)); 34 | char *human_readable_inexact PARAMS ((uintmax_t, char *, int, int, 35 | enum human_inexact_style)); 36 | 37 | void human_block_size PARAMS ((char const *, int, int *)); 38 | 39 | #endif /* HUMAN_H_ */ 40 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | /* $Id: log.c,v 1.6 2005/05/15 20:15:28 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2020 David Polverari 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 2, or (at your option) 12 | 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, write to the Free Software Foundation, 21 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 | 23 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 24 | 25 | #include "dcfldd.h" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "log.h" 33 | #include "hash.h" 34 | #include "verify.h" 35 | #include 36 | #include "hashformat.h" 37 | 38 | FILE *errlog = NULL; 39 | 40 | void syscall_error(char *str) 41 | { 42 | syscall_error_noexit(str); 43 | exit(1); 44 | } 45 | 46 | void syscall_error_noexit(char *str) 47 | { 48 | char *errstr = strerror(errno); 49 | 50 | fprintf(stderr, "%s:%s: %s\n", program_name, str == NULL ? "" : str, errstr); 51 | if (errlog != NULL) 52 | fprintf(errlog, "%s:%s: %s\n", program_name, str == NULL ? "" : str, errstr); 53 | } 54 | 55 | void user_error(char *str, ...) 56 | { 57 | va_list ap; 58 | 59 | va_start(ap, str); 60 | fprintf(stderr, "%s: ", program_name); 61 | vfprintf(stderr, str, ap); 62 | fprintf(stderr, "\n"); 63 | if (errlog != NULL) { 64 | fprintf(errlog, "%s: ", program_name); 65 | vfprintf(errlog, str, ap); 66 | fprintf(errlog, "\n"); 67 | } 68 | va_end(ap); 69 | exit(1); 70 | } 71 | 72 | void log_info(char *str, ...) 73 | { 74 | va_list ap, ap2; 75 | 76 | va_start(ap, str); 77 | va_copy(ap2, ap); 78 | vfprintf(stderr, str, ap); 79 | if (errlog != NULL) { 80 | vfprintf(errlog, str, ap2); 81 | va_end(ap2); 82 | } 83 | va_end(ap); 84 | } 85 | 86 | void internal_error(char *str) 87 | { 88 | fprintf(stderr, "%s: internal error: %s\n", program_name, str); 89 | if (errlog != NULL) 90 | fprintf(errlog, "%s: internal error: %s\n", program_name, str); 91 | exit(1); 92 | } 93 | 94 | void log_hashwindow(hashtype_t *htype, off_t wina, off_t winb, size_t bs, char *hash) 95 | { 96 | print_fmt(hashformat, htype->log, wina, winb, bs, htype->name, hash); 97 | } 98 | 99 | void log_hashtotal(hashtype_t *htype, off_t wina, off_t winb, size_t bs, char *hash) 100 | { 101 | print_fmt(totalhashformat, htype->log, wina, winb, bs, htype->name, hash); 102 | } 103 | 104 | void log_verifywindow(hashtype_t *htype, off_t wina, off_t winb, int mismatch) 105 | { 106 | fprintf(htype->log, "%llu - %llu: %s\n", 107 | (unsigned long long int) wina, 108 | (unsigned long long int) winb, 109 | mismatch ? "Mismatch" : "Match"); 110 | } 111 | 112 | void log_verifytotal(hashtype_t *htype, int mismatch) 113 | { 114 | fprintf(htype->log, "Total: %s\n", mismatch ? "Mismatch" : "Match"); 115 | } 116 | -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | /* $Id: log.h,v 1.5 2005/05/15 20:15:28 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef LOG_H 25 | #define LOG_H 26 | 27 | #include "dcfldd.h" 28 | #include "hash.h" 29 | #include 30 | #include 31 | #include 32 | 33 | extern FILE *errlog; 34 | 35 | extern void syscall_error(char *); 36 | extern void syscall_error_noexit(char *); 37 | extern void user_error(char *, ...); 38 | extern void internal_error(char *); 39 | extern void log_info(char *, ...); 40 | 41 | extern void log_hashwindow(hashtype_t *, off_t, off_t, size_t, char *); 42 | extern void log_hashtotal(hashtype_t *, off_t, off_t, size_t, char *); 43 | 44 | extern void log_verifywindow(hashtype_t *, off_t, off_t, int); 45 | extern void log_verifytotal(hashtype_t *, int); 46 | 47 | #endif /* LOG_H */ 48 | -------------------------------------------------------------------------------- /src/long-options.c: -------------------------------------------------------------------------------- 1 | /* Utility to accept --help and --version options as unobtrusively as possible. 2 | Copyright (C) 1993, 1994, 1998, 1999, 2000 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by Jim Meyering. */ 19 | 20 | #if HAVE_CONFIG_H 21 | # include 22 | #endif 23 | 24 | #include 25 | #include 26 | #if HAVE_STDLIB_H 27 | # include 28 | #endif 29 | 30 | #include "long-options.h" 31 | #include "version-etc.h" 32 | 33 | #if ENABLE_NLS 34 | # include 35 | # define _(Text) gettext (Text) 36 | #else 37 | # define _(Text) Text 38 | #endif 39 | 40 | static struct option const long_options[] = 41 | { 42 | {"help", no_argument, 0, 'h'}, 43 | {"version", no_argument, 0, 'v'}, 44 | {0, 0, 0, 0} 45 | }; 46 | 47 | /* Process long options --help and --version, but only if argc == 2. 48 | Be careful not to gobble up `--'. */ 49 | 50 | void 51 | parse_long_options (int argc, 52 | char **argv, 53 | const char *command_name, 54 | const char *package, 55 | const char *version, 56 | const char *authors, 57 | void (*usage_func)(int)) 58 | { 59 | int c; 60 | int saved_opterr; 61 | 62 | saved_opterr = opterr; 63 | 64 | /* Don't print an error message for unrecognized options. */ 65 | opterr = 0; 66 | 67 | if (argc == 2 68 | && (c = getopt_long (argc, argv, "+", long_options, NULL)) != -1) 69 | { 70 | switch (c) 71 | { 72 | case 'h': 73 | (*usage_func) (0); 74 | 75 | case 'v': 76 | version_etc (stdout, command_name, package, version, authors); 77 | exit (0); 78 | 79 | default: 80 | /* Don't process any other long-named options. */ 81 | break; 82 | } 83 | } 84 | 85 | /* Restore previous value. */ 86 | opterr = saved_opterr; 87 | 88 | /* Reset this to zero so that getopt internals get initialized from 89 | the probably-new parameters when/if getopt is called later. */ 90 | optind = 0; 91 | } 92 | -------------------------------------------------------------------------------- /src/long-options.h: -------------------------------------------------------------------------------- 1 | /* long-options.h -- declaration for --help- and --version-handling function. 2 | Copyright (C) 1993, 1994, 1998, 1999 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by Jim Meyering. */ 19 | 20 | #ifndef PARAMS 21 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 22 | # define PARAMS(Args) Args 23 | # else 24 | # define PARAMS(Args) () 25 | # endif 26 | #endif 27 | 28 | void 29 | parse_long_options PARAMS ((int _argc, 30 | char **_argv, 31 | const char *_command_name, 32 | const char *_package, 33 | const char *_version, 34 | const char *_authors, 35 | void (*_usage) (int))); 36 | -------------------------------------------------------------------------------- /src/md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************** 3 | ** md5.c ** 4 | ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** 5 | ** Created: 2/17/90 RLR ** 6 | ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** 7 | ********************************************************************** 8 | */ 9 | 10 | /* 11 | ********************************************************************** 12 | ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** 13 | ** ** 14 | ** License to copy and use this software is granted provided that ** 15 | ** it is identified as the "RSA Data Security, Inc. MD5 Message ** 16 | ** Digest Algorithm" in all material mentioning or referencing this ** 17 | ** software or this function. ** 18 | ** ** 19 | ** License is also granted to make and use derivative works ** 20 | ** provided that such works are identified as "derived from the RSA ** 21 | ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** 22 | ** material mentioning or referencing the derived work. ** 23 | ** ** 24 | ** RSA Data Security, Inc. makes no representations concerning ** 25 | ** either the merchantability of this software or the suitability ** 26 | ** of this software for any particular purpose. It is provided "as ** 27 | ** is" without express or implied warranty of any kind. ** 28 | ** ** 29 | ** These notices must be retained in any copies of any part of this ** 30 | ** documentation and/or software. ** 31 | ********************************************************************** 32 | */ 33 | 34 | /* -- include the following line if the md5.h header file is separate -- */ 35 | #include "md5.h" 36 | 37 | /* forward declaration */ 38 | static void Transform (UINT4 *buf, UINT4 *in); 39 | 40 | static unsigned char PADDING[64] = { 41 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 49 | }; 50 | 51 | /* F, G and H are basic MD5 functions: selection, majority, parity */ 52 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 53 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 54 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 55 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 56 | 57 | /* ROTATE_LEFT rotates x left n bits */ 58 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 59 | 60 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ 61 | /* Rotation is separate from addition to prevent recomputation */ 62 | #define FF(a, b, c, d, x, s, ac) \ 63 | {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 64 | (a) = ROTATE_LEFT ((a), (s)); \ 65 | (a) += (b); \ 66 | } 67 | #define GG(a, b, c, d, x, s, ac) \ 68 | {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 69 | (a) = ROTATE_LEFT ((a), (s)); \ 70 | (a) += (b); \ 71 | } 72 | #define HH(a, b, c, d, x, s, ac) \ 73 | {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 74 | (a) = ROTATE_LEFT ((a), (s)); \ 75 | (a) += (b); \ 76 | } 77 | #define II(a, b, c, d, x, s, ac) \ 78 | {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 79 | (a) = ROTATE_LEFT ((a), (s)); \ 80 | (a) += (b); \ 81 | } 82 | 83 | void MD5Init (MD5_CTX *mdContext) 84 | { 85 | mdContext->i[0] = mdContext->i[1] = (UINT4)0; 86 | 87 | /* Load magic initialization constants. 88 | */ 89 | mdContext->buf[0] = (UINT4)0x67452301; 90 | mdContext->buf[1] = (UINT4)0xefcdab89; 91 | mdContext->buf[2] = (UINT4)0x98badcfe; 92 | mdContext->buf[3] = (UINT4)0x10325476; 93 | } 94 | 95 | void MD5Update (MD5_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen) 96 | { 97 | UINT4 in[16]; 98 | int mdi; 99 | unsigned int i, ii; 100 | 101 | /* compute number of bytes mod 64 */ 102 | mdi = (int)((mdContext->i[0] >> 3) & 0x3F); 103 | 104 | /* update number of bits */ 105 | if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) 106 | mdContext->i[1]++; 107 | mdContext->i[0] += ((UINT4)inLen << 3); 108 | mdContext->i[1] += ((UINT4)inLen >> 29); 109 | 110 | while (inLen--) { 111 | /* add new character to buffer, increment mdi */ 112 | mdContext->in[mdi++] = *inBuf++; 113 | 114 | /* transform if necessary */ 115 | if (mdi == 0x40) { 116 | for (i = 0, ii = 0; i < 16; i++, ii += 4) 117 | in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | 118 | (((UINT4)mdContext->in[ii+2]) << 16) | 119 | (((UINT4)mdContext->in[ii+1]) << 8) | 120 | ((UINT4)mdContext->in[ii]); 121 | Transform (mdContext->buf, in); 122 | mdi = 0; 123 | } 124 | } 125 | } 126 | 127 | void MD5Final (MD5_CTX *mdContext, char *buf) 128 | { 129 | UINT4 in[16]; 130 | int mdi; 131 | unsigned int i, ii; 132 | unsigned int padLen; 133 | 134 | /* save number of bits */ 135 | in[14] = mdContext->i[0]; 136 | in[15] = mdContext->i[1]; 137 | 138 | /* compute number of bytes mod 64 */ 139 | mdi = (int)((mdContext->i[0] >> 3) & 0x3F); 140 | 141 | /* pad out to 56 mod 64 */ 142 | padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); 143 | MD5Update (mdContext, PADDING, padLen); 144 | 145 | /* append length in bits and transform */ 146 | for (i = 0, ii = 0; i < 14; i++, ii += 4) 147 | in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | 148 | (((UINT4)mdContext->in[ii+2]) << 16) | 149 | (((UINT4)mdContext->in[ii+1]) << 8) | 150 | ((UINT4)mdContext->in[ii]); 151 | Transform (mdContext->buf, in); 152 | 153 | /* store buffer in digest */ 154 | for (i = 0, ii = 0; i < 4; i++, ii += 4) { 155 | mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); 156 | mdContext->digest[ii+1] = 157 | (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); 158 | mdContext->digest[ii+2] = 159 | (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); 160 | mdContext->digest[ii+3] = 161 | (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); 162 | } 163 | 164 | MD5Sprint(mdContext, buf); 165 | } 166 | 167 | /* Print the context to the given buffer (32 digits) 168 | */ 169 | void MD5Sprint (MD5_CTX *mdContext, char *buf) 170 | { 171 | int i; 172 | 173 | for (i = 0; i < 16; i++) 174 | sprintf (&buf[i*2], "%02x", mdContext->digest[i]); 175 | } 176 | 177 | /* Basic MD5 step. Transform buf based on in. 178 | */ 179 | static void Transform (UINT4 *buf, UINT4 *in) 180 | { 181 | UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; 182 | 183 | /* Round 1 */ 184 | #define S11 7 185 | #define S12 12 186 | #define S13 17 187 | #define S14 22 188 | FF ( a, b, c, d, in[ 0], S11, 3614090360u); /* 1 */ 189 | FF ( d, a, b, c, in[ 1], S12, 3905402710u); /* 2 */ 190 | FF ( c, d, a, b, in[ 2], S13, 606105819u); /* 3 */ 191 | FF ( b, c, d, a, in[ 3], S14, 3250441966u); /* 4 */ 192 | FF ( a, b, c, d, in[ 4], S11, 4118548399u); /* 5 */ 193 | FF ( d, a, b, c, in[ 5], S12, 1200080426u); /* 6 */ 194 | FF ( c, d, a, b, in[ 6], S13, 2821735955u); /* 7 */ 195 | FF ( b, c, d, a, in[ 7], S14, 4249261313u); /* 8 */ 196 | FF ( a, b, c, d, in[ 8], S11, 1770035416u); /* 9 */ 197 | FF ( d, a, b, c, in[ 9], S12, 2336552879u); /* 10 */ 198 | FF ( c, d, a, b, in[10], S13, 4294925233u); /* 11 */ 199 | FF ( b, c, d, a, in[11], S14, 2304563134u); /* 12 */ 200 | FF ( a, b, c, d, in[12], S11, 1804603682u); /* 13 */ 201 | FF ( d, a, b, c, in[13], S12, 4254626195u); /* 14 */ 202 | FF ( c, d, a, b, in[14], S13, 2792965006u); /* 15 */ 203 | FF ( b, c, d, a, in[15], S14, 1236535329u); /* 16 */ 204 | 205 | /* Round 2 */ 206 | #define S21 5 207 | #define S22 9 208 | #define S23 14 209 | #define S24 20 210 | GG ( a, b, c, d, in[ 1], S21, 4129170786u); /* 17 */ 211 | GG ( d, a, b, c, in[ 6], S22, 3225465664u); /* 18 */ 212 | GG ( c, d, a, b, in[11], S23, 643717713u); /* 19 */ 213 | GG ( b, c, d, a, in[ 0], S24, 3921069994u); /* 20 */ 214 | GG ( a, b, c, d, in[ 5], S21, 3593408605u); /* 21 */ 215 | GG ( d, a, b, c, in[10], S22, 38016083u); /* 22 */ 216 | GG ( c, d, a, b, in[15], S23, 3634488961u); /* 23 */ 217 | GG ( b, c, d, a, in[ 4], S24, 3889429448u); /* 24 */ 218 | GG ( a, b, c, d, in[ 9], S21, 568446438u); /* 25 */ 219 | GG ( d, a, b, c, in[14], S22, 3275163606u); /* 26 */ 220 | GG ( c, d, a, b, in[ 3], S23, 4107603335u); /* 27 */ 221 | GG ( b, c, d, a, in[ 8], S24, 1163531501u); /* 28 */ 222 | GG ( a, b, c, d, in[13], S21, 2850285829u); /* 29 */ 223 | GG ( d, a, b, c, in[ 2], S22, 4243563512u); /* 30 */ 224 | GG ( c, d, a, b, in[ 7], S23, 1735328473u); /* 31 */ 225 | GG ( b, c, d, a, in[12], S24, 2368359562u); /* 32 */ 226 | 227 | /* Round 3 */ 228 | #define S31 4 229 | #define S32 11 230 | #define S33 16 231 | #define S34 23 232 | HH ( a, b, c, d, in[ 5], S31, 4294588738u); /* 33 */ 233 | HH ( d, a, b, c, in[ 8], S32, 2272392833u); /* 34 */ 234 | HH ( c, d, a, b, in[11], S33, 1839030562u); /* 35 */ 235 | HH ( b, c, d, a, in[14], S34, 4259657740u); /* 36 */ 236 | HH ( a, b, c, d, in[ 1], S31, 2763975236u); /* 37 */ 237 | HH ( d, a, b, c, in[ 4], S32, 1272893353u); /* 38 */ 238 | HH ( c, d, a, b, in[ 7], S33, 4139469664u); /* 39 */ 239 | HH ( b, c, d, a, in[10], S34, 3200236656u); /* 40 */ 240 | HH ( a, b, c, d, in[13], S31, 681279174u); /* 41 */ 241 | HH ( d, a, b, c, in[ 0], S32, 3936430074u); /* 42 */ 242 | HH ( c, d, a, b, in[ 3], S33, 3572445317u); /* 43 */ 243 | HH ( b, c, d, a, in[ 6], S34, 76029189u); /* 44 */ 244 | HH ( a, b, c, d, in[ 9], S31, 3654602809u); /* 45 */ 245 | HH ( d, a, b, c, in[12], S32, 3873151461u); /* 46 */ 246 | HH ( c, d, a, b, in[15], S33, 530742520u); /* 47 */ 247 | HH ( b, c, d, a, in[ 2], S34, 3299628645u); /* 48 */ 248 | 249 | /* Round 4 */ 250 | #define S41 6 251 | #define S42 10 252 | #define S43 15 253 | #define S44 21 254 | II ( a, b, c, d, in[ 0], S41, 4096336452u); /* 49 */ 255 | II ( d, a, b, c, in[ 7], S42, 1126891415u); /* 50 */ 256 | II ( c, d, a, b, in[14], S43, 2878612391u); /* 51 */ 257 | II ( b, c, d, a, in[ 5], S44, 4237533241u); /* 52 */ 258 | II ( a, b, c, d, in[12], S41, 1700485571u); /* 53 */ 259 | II ( d, a, b, c, in[ 3], S42, 2399980690u); /* 54 */ 260 | II ( c, d, a, b, in[10], S43, 4293915773u); /* 55 */ 261 | II ( b, c, d, a, in[ 1], S44, 2240044497u); /* 56 */ 262 | II ( a, b, c, d, in[ 8], S41, 1873313359u); /* 57 */ 263 | II ( d, a, b, c, in[15], S42, 4264355552u); /* 58 */ 264 | II ( c, d, a, b, in[ 6], S43, 2734768916u); /* 59 */ 265 | II ( b, c, d, a, in[13], S44, 1309151649u); /* 60 */ 266 | II ( a, b, c, d, in[ 4], S41, 4149444226u); /* 61 */ 267 | II ( d, a, b, c, in[11], S42, 3174756917u); /* 62 */ 268 | II ( c, d, a, b, in[ 2], S43, 718787259u); /* 63 */ 269 | II ( b, c, d, a, in[ 9], S44, 3951481745u); /* 64 */ 270 | 271 | buf[0] += a; 272 | buf[1] += b; 273 | buf[2] += c; 274 | buf[3] += d; 275 | } 276 | -------------------------------------------------------------------------------- /src/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************** 3 | ** md5.h -- Header file for implementation of MD5 ** 4 | ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** 5 | ** Created: 2/17/90 RLR ** 6 | ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** 7 | ** Revised (for MD5): RLR 4/27/91 ** 8 | ** -- G modified to have y&~z instead of y&z ** 9 | ** -- FF, GG, HH modified to add in last register done ** 10 | ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** 11 | ** -- distinct additive constant for each step ** 12 | ** -- round 4 added, working mod 7 ** 13 | ********************************************************************** 14 | */ 15 | 16 | /* 17 | ********************************************************************** 18 | ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** 19 | ** ** 20 | ** License to copy and use this software is granted provided that ** 21 | ** it is identified as the "RSA Data Security, Inc. MD5 Message ** 22 | ** Digest Algorithm" in all material mentioning or referencing this ** 23 | ** software or this function. ** 24 | ** ** 25 | ** License is also granted to make and use derivative works ** 26 | ** provided that such works are identified as "derived from the RSA ** 27 | ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** 28 | ** material mentioning or referencing the derived work. ** 29 | ** ** 30 | ** RSA Data Security, Inc. makes no representations concerning ** 31 | ** either the merchantability of this software or the suitability ** 32 | ** of this software for any particular purpose. It is provided "as ** 33 | ** is" without express or implied warranty of any kind. ** 34 | ** ** 35 | ** These notices must be retained in any copies of any part of this ** 36 | ** documentation and/or software. ** 37 | ********************************************************************** 38 | */ 39 | #ifndef MD5_H 40 | #define MD5_H 41 | #if HAVE_INTTYPES_H 42 | # include 43 | #else 44 | # if HAVE_STDINT_H 45 | # include 46 | # endif 47 | #endif 48 | 49 | #include "hash.h" 50 | 51 | /* typedef a 32 bit type */ 52 | typedef uint32_t UINT4; 53 | 54 | #define MD5_DIGEST_STRING_LENGTH 32 55 | 56 | /* Data structure for MD5 (Message Digest) computation */ 57 | typedef struct { 58 | UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ 59 | UINT4 buf[4]; /* scratch buffer */ 60 | unsigned char in[64]; /* input buffer */ 61 | unsigned char digest[16]; /* actual digest after MD5Final call */ 62 | } MD5_CTX; 63 | 64 | void MD5Init (MD5_CTX *); 65 | void MD5Update (MD5_CTX *, const unsigned char *, unsigned int); 66 | void MD5Final (MD5_CTX *, char *); 67 | void MD5Sprint (MD5_CTX *, char *); 68 | #endif /* MD5_H */ 69 | -------------------------------------------------------------------------------- /src/output.c: -------------------------------------------------------------------------------- 1 | /* $Id: output.c,v 1.5 2005/06/15 14:33:04 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2008 David Loveall 8 | Copyright 2022 Tibor Szolnoki 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 2, or (at your option) 13 | 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, write to the Free Software Foundation, 22 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 | 24 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 25 | 26 | #ifdef HAVE_CONFIG_H 27 | # include "config.h" 28 | #endif 29 | 30 | #include "dcfldd.h" 31 | #include "output.h" 32 | #include "full-write.h" 33 | #include "config.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "split.h" 42 | #include "log.h" 43 | #include "util.h" 44 | 45 | outputlist_t *outputlist = NULL; 46 | 47 | void open_output(char *filename) 48 | { 49 | mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 50 | int fd; 51 | int opts 52 | = (O_CREAT 53 | | ((seek_records || do_diffwr || (conversions_mask & C_NOTRUNC)) ? 0 : O_TRUNC)); 54 | 55 | /* Open the output file with *read* access only if we might 56 | need to read to satisfy a `seek=' or "diffwr=on" request. If we can't read 57 | the file, go ahead with write-only access; it might work. */ 58 | if ((! (seek_records || do_diffwr) 59 | || (fd = open(filename, O_RDWR | opts, perms)) < 0) 60 | && (fd = open(filename, O_WRONLY | opts, perms)) < 0) 61 | { 62 | syscall_error(filename); 63 | } 64 | #if HAVE_FTRUNCATE 65 | if (seek_records != 0 && !(conversions_mask & C_NOTRUNC)) { 66 | struct stat statbuf; 67 | off_t o = seek_records * output_blocksize; 68 | if (o / output_blocksize != seek_records) 69 | syscall_error(filename); 70 | 71 | if (fstat(fd, &statbuf) != 0) 72 | syscall_error(filename); 73 | 74 | /* Complain only when ftruncate fails on a regular file, a 75 | directory, or a shared memory object, as the 2000-08 76 | POSIX draft specifies ftruncate's behavior only for these 77 | file types. For example, do not complain when Linux 2.4 78 | ftruncate fails on /dev/fd0. */ 79 | if (ftruncate(fd, o) != 0 80 | && (S_ISREG(statbuf.st_mode) 81 | || S_ISDIR(statbuf.st_mode) 82 | || S_TYPEISSHM(&statbuf))) 83 | { 84 | char buf[LONGEST_HUMAN_READABLE + 1]; 85 | log_info("%s: %s: advancing past %s bytes in output file %s", 86 | program_name, 87 | strerror(errno), 88 | human_readable(o, buf, 1, 1), 89 | filename); 90 | } 91 | } 92 | #endif /* HAVE_FTRUNCATE */ 93 | 94 | outputlist_add(SINGLE_FILE, fd); 95 | } 96 | 97 | void open_output_pipe(char *command) 98 | { 99 | FILE *stream; 100 | 101 | stream = popen(command, "w"); 102 | if (stream == NULL) 103 | syscall_error(command); 104 | 105 | outputlist_add(STREAM, stream); 106 | } 107 | 108 | void outputlist_add(outputtype_t type, ...) 109 | { 110 | va_list ap; 111 | outputlist_t *ptr; 112 | split_t *split; 113 | 114 | va_start(ap, type); 115 | 116 | /* forward to the last struct in outputlist */ 117 | for (ptr = outputlist; ptr != NULL && ptr->next != NULL; ptr = ptr->next) 118 | ; 119 | 120 | if (ptr == NULL) 121 | outputlist = ptr = malloc(sizeof (*ptr)); 122 | else { 123 | ptr->next = malloc(sizeof (*ptr)); 124 | ptr = ptr->next; 125 | } 126 | 127 | ptr->next = NULL; 128 | ptr->type = type; 129 | ptr->stream = NULL; 130 | ptr->diffwr = do_diffwr; 131 | 132 | switch (type) { 133 | case SINGLE_FILE: 134 | ptr->data.fd = va_arg(ap, int); 135 | break; 136 | case STREAM: 137 | ptr->type = SINGLE_FILE; 138 | ptr->stream = va_arg(ap, FILE *); 139 | ptr->data.fd = fileno(ptr->stream); 140 | ptr->diffwr = 0; 141 | break; 142 | case SPLIT_FILE: 143 | split = malloc(sizeof *split); 144 | split->name = strdup(va_arg(ap, char *)); 145 | split->format = strdup(va_arg(ap, char *)); 146 | split->max_bytes = va_arg(ap, off_t); 147 | split->total_bytes = 0; 148 | split->curr_bytes = 0; 149 | split->currfd = -1; 150 | ptr->data.split = split; 151 | break; 152 | } 153 | 154 | va_end(ap); 155 | } 156 | 157 | int outputlist_write(const char *buf, size_t len) 158 | { 159 | outputlist_t *ptr; 160 | int nwritten = 0; 161 | 162 | for (ptr = outputlist; ptr != NULL; ptr = ptr->next) { 163 | nwritten = 0; 164 | switch (ptr->type) { 165 | case SINGLE_FILE: 166 | nwritten = full_write(ptr->data.fd, buf, len, ptr->diffwr); 167 | break; 168 | case SPLIT_FILE: 169 | nwritten = split_write(ptr->data.split, buf, len, ptr->diffwr); 170 | break; 171 | } 172 | if (nwritten < len) 173 | break; 174 | } 175 | 176 | return nwritten; 177 | } 178 | -------------------------------------------------------------------------------- /src/output.h: -------------------------------------------------------------------------------- 1 | /* $Id: output.h,v 1.4 2005/05/15 20:15:28 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2008 David Loveall 8 | Copyright 2022 Tibor Szolnoki 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 2, or (at your option) 13 | 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, write to the Free Software Foundation, 22 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 | 24 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 25 | 26 | #ifndef OUTPUT_H 27 | #define OUTPUT_H 28 | 29 | #include "dcfldd.h" 30 | #include 31 | #include "split.h" 32 | 33 | typedef enum 34 | { 35 | NONE, 36 | SINGLE_FILE, 37 | SPLIT_FILE, 38 | STREAM 39 | } outputtype_t; 40 | 41 | typedef struct outputlist_s 42 | { 43 | struct outputlist_s *next; 44 | outputtype_t type; 45 | FILE *stream; 46 | union { 47 | int fd; 48 | split_t *split; 49 | } data; 50 | int diffwr; 51 | } outputlist_t; 52 | 53 | extern outputlist_t *outputlist; 54 | 55 | extern void open_output(char *); 56 | extern void open_output_pipe(char *); 57 | extern void outputlist_add(outputtype_t, ...); 58 | extern int outputlist_write(const char *, size_t); 59 | 60 | #endif /* OUTPUT_H */ 61 | -------------------------------------------------------------------------------- /src/pathmax.h: -------------------------------------------------------------------------------- 1 | /* Define PATH_MAX somehow. Requires sys/types.h. 2 | Copyright (C) 1992, 1999 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | #ifndef _PATHMAX_H 19 | # define _PATHMAX_H 20 | 21 | # ifdef HAVE_UNISTD_H 22 | # include 23 | # endif 24 | 25 | /* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define 26 | PATH_MAX but might cause redefinition warnings when sys/param.h is 27 | later included (as on MORE/BSD 4.3). */ 28 | # if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__)) 29 | # include 30 | # endif 31 | 32 | # ifndef _POSIX_PATH_MAX 33 | # define _POSIX_PATH_MAX 255 34 | # endif 35 | 36 | # if !defined(PATH_MAX) && defined(_PC_PATH_MAX) 37 | # define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \ 38 | : pathconf ("/", _PC_PATH_MAX)) 39 | # endif 40 | 41 | /* Don't include sys/param.h if it already has been. */ 42 | # if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN) 43 | # include 44 | # endif 45 | 46 | # if !defined(PATH_MAX) && defined(MAXPATHLEN) 47 | # define PATH_MAX MAXPATHLEN 48 | # endif 49 | 50 | # ifndef PATH_MAX 51 | # define PATH_MAX _POSIX_PATH_MAX 52 | # endif 53 | 54 | #endif /* _PATHMAX_H */ 55 | -------------------------------------------------------------------------------- /src/pattern.c: -------------------------------------------------------------------------------- 1 | /* $Id: pattern.c,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #include "dcfldd.h" 25 | #include 26 | 27 | /* Pattern to be written out */ 28 | char *pattern; 29 | size_t pattern_len; 30 | int input_from_pattern; 31 | 32 | 33 | char *make_pattern(char *pattern) 34 | { 35 | size_t plen, numbytes, i; 36 | char *buffer; 37 | 38 | plen = strlen(pattern); 39 | 40 | if (plen == 0 || plen % 2 != 0) 41 | return NULL; 42 | 43 | numbytes = plen / 2; 44 | buffer = malloc(numbytes); 45 | 46 | for (i = 0; i < numbytes; i++) { 47 | char tmpstring[3]; 48 | int byteval; 49 | strncpy(tmpstring, &pattern[i*2], 2); 50 | tmpstring[2] = '\0'; 51 | byteval = hex2char(tmpstring); 52 | 53 | if (byteval == -1) { 54 | free(buffer); 55 | return NULL; 56 | } 57 | buffer[i] = (char)byteval; 58 | } 59 | pattern_len = numbytes; 60 | 61 | return buffer; 62 | } 63 | 64 | void replicate_pattern(char *pattern, char *buffer, size_t size) 65 | { 66 | size_t i; 67 | 68 | for (i = 0; i < size; i++) 69 | buffer[i] = pattern[i % pattern_len]; 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/pattern.h: -------------------------------------------------------------------------------- 1 | /* $Id: pattern.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef PATTERN_H 25 | #define PATTERN_H 26 | 27 | #include "dcfldd.h" 28 | #include 29 | 30 | extern char *pattern; 31 | extern size_t pattern_len; 32 | extern int input_from_pattern; 33 | 34 | extern char *make_pattern(char *); 35 | extern void replicate_pattern(char *, char *, size_t); 36 | 37 | #endif /* PATTERN_H */ 38 | -------------------------------------------------------------------------------- /src/safe-read.c: -------------------------------------------------------------------------------- 1 | /* safe-read.c -- an interface to read that retries after interrupts 2 | Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #if HAVE_CONFIG_H 20 | # include 21 | #endif 22 | 23 | #include 24 | 25 | #if HAVE_UNISTD_H 26 | # include 27 | #endif 28 | 29 | #include 30 | #ifndef errno 31 | extern int errno; 32 | #endif 33 | 34 | #include "safe-read.h" 35 | 36 | /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted. 37 | Return the actual number of bytes read, zero for EOF, or negative 38 | for an error. */ 39 | 40 | ssize_t 41 | safe_read (int desc, void *ptr, size_t len) 42 | { 43 | ssize_t n_chars; 44 | 45 | if (len <= 0) 46 | return len; 47 | 48 | #ifdef EINTR 49 | do 50 | { 51 | n_chars = read (desc, ptr, len); 52 | } 53 | while (n_chars < 0 && errno == EINTR); 54 | #else 55 | n_chars = read (desc, ptr, len); 56 | #endif 57 | 58 | return n_chars; 59 | } 60 | -------------------------------------------------------------------------------- /src/safe-read.h: -------------------------------------------------------------------------------- 1 | #ifndef PARAMS 2 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 3 | # define PARAMS(Args) Args 4 | # else 5 | # define PARAMS(Args) () 6 | # endif 7 | #endif 8 | 9 | ssize_t 10 | safe_read PARAMS ((int desc, void *ptr, size_t len)); 11 | -------------------------------------------------------------------------------- /src/sha1.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2001-2003 Allan Saddi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS'' 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | * 26 | * $Id: sha1.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 27 | */ 28 | 29 | #ifndef _SHA1_H 30 | #define _SHA1_H 31 | 32 | #if HAVE_INTTYPES_H 33 | # include 34 | #else 35 | # if HAVE_STDINT_H 36 | # include 37 | # endif 38 | #endif 39 | 40 | #define SHA1_HASH_SIZE 20 41 | #define SHA1_DIGEST_STRING_LENGTH 40 42 | 43 | /* Hash size in 32-bit words */ 44 | #define SHA1_HASH_WORDS 5 45 | 46 | struct _SHA1Context { 47 | uint64_t totalLength; 48 | uint32_t hash[SHA1_HASH_WORDS]; 49 | uint32_t bufferLength; 50 | union { 51 | uint32_t words[16]; 52 | uint8_t bytes[64]; 53 | } buffer; 54 | #ifdef RUNTIME_ENDIAN 55 | int littleEndian; 56 | #endif /* RUNTIME_ENDIAN */ 57 | }; 58 | 59 | typedef struct _SHA1Context SHA1Context; 60 | 61 | #ifdef __cplusplus 62 | extern "C" { 63 | #endif 64 | 65 | void SHA1Init (SHA1Context *sc); 66 | void SHA1Update (SHA1Context *sc, const void *data, uint32_t len); 67 | void SHA1Final (SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE]); 68 | void SHA1End (SHA1Context *sc, char *hashstrbuf); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* _SHA1_H */ 75 | -------------------------------------------------------------------------------- /src/sha2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FILE: sha2.h 3 | * AUTHOR: Aaron D. Gifford 4 | * 5 | * Copyright (c) 2000-2001, Aaron D. Gifford 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of the copyright holder nor the names of contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | * SUCH DAMAGE. 31 | * 32 | * $Id: sha2.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 33 | */ 34 | 35 | #ifndef __SHA2_H__ 36 | #define __SHA2_H__ 37 | 38 | # if HAVE_CONFIG_H 39 | # include 40 | # endif 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | 47 | /* 48 | * Import u_intXX_t size_t type definitions from system headers. You 49 | * may need to change this, or define these things yourself in this 50 | * file. 51 | */ 52 | #include 53 | 54 | #include 55 | 56 | /* 57 | * Define the followingsha2_* types to types of the correct length on 58 | * the native archtecture. Most BSD systems and Linux define u_intXX_t 59 | * types. Machines with very recent ANSI C headers, can use the 60 | * uintXX_t definintions from inttypes.h by defining HAVE_INTTYPES_H 61 | * during compile or in the sha.h header file. 62 | * 63 | * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t 64 | * will need to define these three typedefs below (and the appropriate 65 | * ones in sha.h too) by hand according to their system architecture. 66 | * 67 | * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t 68 | * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. 69 | */ 70 | #ifdef HAVE_INTTYPES_H 71 | 72 | #include 73 | 74 | typedef uint8_t sha2_byte; /* Exactly 1 byte */ 75 | typedef uint32_t sha2_word32; /* Exactly 4 bytes */ 76 | typedef uint64_t sha2_word64; /* Exactly 8 bytes */ 77 | 78 | #else /* HAVE_INTTYPES_H */ 79 | 80 | typedef u_int8_t sha2_byte; /* Exactly 1 byte */ 81 | typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ 82 | typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ 83 | 84 | #endif /* HAVE_INTTYPES_H */ 85 | 86 | /*** SHA-256/384/512 Various Length Definitions ***********************/ 87 | #define SHA256_BLOCK_LENGTH 64 88 | #define SHA256_DIGEST_LENGTH 32 89 | #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) 90 | #define SHA384_BLOCK_LENGTH 128 91 | #define SHA384_DIGEST_LENGTH 48 92 | #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) 93 | #define SHA512_BLOCK_LENGTH 128 94 | #define SHA512_DIGEST_LENGTH 64 95 | #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) 96 | 97 | 98 | /*** SHA-256/384/512 Context Structures *******************************/ 99 | /* NOTE: If your architecture does not define either u_intXX_t types or 100 | * uintXX_t (from inttypes.h), you may need to define things by hand 101 | * for your system: 102 | */ 103 | #if 0 104 | typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ 105 | typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ 106 | typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ 107 | #endif 108 | /* 109 | * Most BSD systems already define u_intXX_t types, as does Linux. 110 | * Some systems, however, like Compaq's Tru64 Unix instead can use 111 | * uintXX_t types defined by very recent ANSI C standards and included 112 | * in the file: 113 | * 114 | * #include 115 | * 116 | * If you choose to use then please define: 117 | * 118 | * #define HAVE_INTTYPES_H 119 | * 120 | * Or on the command line during compile: 121 | * 122 | * cc -DHAVE_INTTYPES_H ... 123 | */ 124 | #ifdef HAVE_INTTYPES_H 125 | 126 | typedef struct _SHA256_CTX { 127 | uint32_t state[8]; 128 | uint64_t bitcount; 129 | uint8_t buffer[SHA256_BLOCK_LENGTH]; 130 | } SHA256_CTX; 131 | typedef struct _SHA512_CTX { 132 | uint64_t state[8]; 133 | uint64_t bitcount[2]; 134 | uint8_t buffer[SHA512_BLOCK_LENGTH]; 135 | } SHA512_CTX; 136 | 137 | #else /* HAVE_INTTYPES_H */ 138 | 139 | typedef struct _SHA256_CTX { 140 | u_int32_t state[8]; 141 | u_int64_t bitcount; 142 | u_int8_t buffer[SHA256_BLOCK_LENGTH]; 143 | } SHA256_CTX; 144 | typedef struct _SHA512_CTX { 145 | u_int64_t state[8]; 146 | u_int64_t bitcount[2]; 147 | u_int8_t buffer[SHA512_BLOCK_LENGTH]; 148 | } SHA512_CTX; 149 | 150 | #endif /* HAVE_INTTYPES_H */ 151 | 152 | typedef SHA512_CTX SHA384_CTX; 153 | 154 | 155 | /*** SHA-256/384/512 Function Prototypes ******************************/ 156 | #ifndef NOPROTO 157 | #ifdef HAVE_INTTYPES_H 158 | 159 | void SHA256_Init(SHA256_CTX *); 160 | void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); 161 | void SHA256_Final(SHA256_CTX *, uint8_t[SHA256_DIGEST_LENGTH]); 162 | char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); 163 | char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); 164 | 165 | void SHA384_Init(SHA384_CTX*); 166 | void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); 167 | void SHA384_Final(SHA384_CTX*, uint8_t[SHA384_DIGEST_LENGTH]); 168 | char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); 169 | char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); 170 | 171 | void SHA512_Init(SHA512_CTX*); 172 | void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); 173 | void SHA512_Final(SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]); 174 | char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); 175 | char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); 176 | 177 | #else /* HAVE_INTTYPES_H */ 178 | 179 | void SHA256_Init(SHA256_CTX *); 180 | void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); 181 | void SHA256_Final(SHA256_CTX*, u_int8_t[SHA256_DIGEST_LENGTH]); 182 | char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); 183 | char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); 184 | 185 | void SHA384_Init(SHA384_CTX*); 186 | void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); 187 | void SHA384_Final(SHA384_CTX*, u_int8_t[SHA384_DIGEST_LENGTH]); 188 | char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); 189 | char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); 190 | 191 | void SHA512_Init(SHA512_CTX*); 192 | void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); 193 | void SHA512_Final(SHA512_CTX*, u_int8_t[SHA512_DIGEST_LENGTH]); 194 | char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); 195 | char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); 196 | 197 | #endif /* HAVE_INTTYPES_H */ 198 | 199 | #else /* NOPROTO */ 200 | 201 | void SHA256_Init(); 202 | void SHA256_Update(); 203 | void SHA256_Final(); 204 | char* SHA256_End(); 205 | char* SHA256_Data(); 206 | 207 | void SHA384_Init(); 208 | void SHA384_Update(); 209 | void SHA384_Final(); 210 | char* SHA384_End(); 211 | char* SHA384_Data(); 212 | 213 | void SHA512_Init(); 214 | void SHA512_Update(); 215 | void SHA512_Final(); 216 | char* SHA512_End(); 217 | char* SHA512_Data(); 218 | 219 | #endif /* NOPROTO */ 220 | 221 | #ifdef __cplusplus 222 | } 223 | #endif /* __cplusplus */ 224 | 225 | #endif /* __SHA2_H__ */ 226 | 227 | -------------------------------------------------------------------------------- /src/sizeprobe.c: -------------------------------------------------------------------------------- 1 | /* $Id: sizeprobe.c,v 1.4 2005/05/15 20:15:28 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | * Copyright 2014 Vangelis Koukis 8 | * Copyright 2020 David Polverari 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 2, or (at your option) 13 | 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, write to the Free Software Foundation, 22 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 | 24 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 25 | 26 | #include "dcfldd.h" 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "config.h" 33 | #include "system.h" 34 | #include "sizeprobe.h" 35 | #include "log.h" 36 | 37 | static off_t midpoint(off_t a, off_t b, long blksize); 38 | static off_t get_dev_size(int, long); 39 | 40 | /* Which file (if any) to probe the size of */ 41 | int probe = PROBE_NONE; 42 | off_t probed_size; 43 | 44 | /* 45 | * Compute a block-resolution midpoint (c) of a and b 46 | */ 47 | static off_t midpoint(off_t a, off_t b, long blksize) 48 | { 49 | off_t aprime = a / blksize; 50 | off_t bprime = b / blksize; 51 | off_t c, cprime; 52 | 53 | cprime = (bprime - aprime) / 2 + aprime; 54 | c = cprime * blksize; 55 | 56 | return c; 57 | } 58 | 59 | #if defined (__linux__) 60 | 61 | #include 62 | #include 63 | 64 | /* I stole this from Jesse Kornblum's md5deep */ 65 | static off_t get_dev_size(int fd, long blksize) 66 | { 67 | off_t num_bytes = 0; 68 | 69 | /* 70 | * Use BLKGETSIZE64 unconditionally, since dcfldd.h #defines _FILE_OFFSET_BITS 64 71 | * and off_t is guaranteed to be large enough to hold the result. 72 | */ 73 | if (ioctl(fd, BLKGETSIZE64, &num_bytes)) 74 | log_info("%s: ioctl call to BLKGETSIZE64 failed.\n", program_name); 75 | else 76 | return (num_bytes); 77 | } 78 | 79 | #elif defined (__MacOSX__) 80 | 81 | #include 82 | #include 83 | #include 84 | #include 85 | 86 | /* I also stole this from Jesse Kornblum's md5deep */ 87 | static static off_t get_dev_size(int fd, long blksize) 88 | { 89 | FILE *f = fdopen(fd, "r"); 90 | off_t total = 0; 91 | off_t original = ftello(f); 92 | int ok = TRUE; 93 | 94 | if (S_ISBLK(info.st_mode)) { 95 | daddr_t blocksize = 0; 96 | daddr_t blockcount = 0; 97 | 98 | 99 | /* Get the block size */ 100 | if (ioctl(fd, DKIOCGETBLOCKSIZE,blocksize) < 0) { 101 | ok = FALSE; 102 | #if defined(__DEBUG) 103 | perror("DKIOCGETBLOCKSIZE failed"); 104 | #endif 105 | } 106 | 107 | /* Get the number of blocks */ 108 | if (ok) { 109 | if (ioctl(fd, DKIOCGETBLOCKCOUNT, blockcount) < 0) { 110 | #if defined(__DEBUG) 111 | perror("DKIOCGETBLOCKCOUNT failed"); 112 | #endif 113 | } 114 | } 115 | 116 | total = blocksize * blockcount; 117 | 118 | } else { 119 | 120 | /* I don't know why, but if you don't initialize this value you'll 121 | get wildly innacurate results when you try to run this function */ 122 | 123 | if ((fseeko(f,0,SEEK_END))) 124 | return 0; 125 | total = ftello(f); 126 | if ((fseeko(f,original,SEEK_SET))) 127 | return 0; 128 | } 129 | 130 | return (total - original); 131 | } 132 | 133 | #else /* all other *nix */ 134 | /* 135 | * Guess the size of a device file. 136 | * Note: this is only used to give time estimates. 137 | * Even if this is way off or broken, 138 | * the forensic validity of the tool remains. 139 | ************************************************** 140 | * This algorithm works by reading a block starting 141 | * at offset 0 then 1, 2, 4, 8, 16, etc and doubles 142 | * until it reaches a point where it fails, then it 143 | * iteratively backtracks by half the distance to 144 | * the last known good read. It goes back and forth 145 | * until it knows the last readable block on the 146 | * device. Theoretically, this should give EXACTLY 147 | * the size of the device considering that the 148 | * seeks and reads work. this algorithm will 149 | * obviously wreak havok if you try it against a 150 | * tape device, you have been warned. 151 | */ 152 | static off_t get_dev_size(int fd, long blksize) 153 | { /* this function is awesome */ 154 | off_t curr = 0, amount = 0; 155 | void *buf; 156 | off_t told; 157 | 158 | if (blksize == 0) 159 | return 0; 160 | 161 | buf = malloc(blksize); 162 | 163 | for (;;) { 164 | ssize_t nread; 165 | 166 | lseek(fd, curr, SEEK_SET); 167 | nread = read(fd, buf, blksize); 168 | if (nread < blksize) { 169 | if (nread <= 0) { 170 | if (curr == amount) { 171 | free(buf); 172 | lseek(fd, 0, SEEK_SET); 173 | return amount; 174 | } 175 | curr = midpoint(amount, curr, blksize); 176 | } else { /* 0 < nread < blksize */ 177 | free(buf); 178 | lseek(fd, 0, SEEK_SET); 179 | return amount + nread; 180 | } 181 | } else { 182 | amount = curr + blksize; 183 | curr = amount * 2; 184 | } 185 | } 186 | free(buf); 187 | lseek(fd, 0, SEEK_SET); 188 | return amount; 189 | } 190 | 191 | #endif /* if defined (__linux__), etc.. */ 192 | 193 | void sizeprobe(int fd) 194 | { 195 | struct stat statbuf; 196 | 197 | if (fstat(fd, &statbuf) == -1) { 198 | log_info("%s: stating file", strerror(errno)); 199 | return; 200 | } 201 | 202 | if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode)) 203 | probed_size = statbuf.st_size; 204 | else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) 205 | probed_size = get_dev_size(fd, statbuf.st_blksize); 206 | } 207 | -------------------------------------------------------------------------------- /src/sizeprobe.h: -------------------------------------------------------------------------------- 1 | /* $Id: sizeprobe.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2008 David Loveall 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 2, or (at your option) 12 | 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, write to the Free Software Foundation, 21 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 | 23 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 24 | 25 | #ifndef SIZEPROBE_H 26 | #define SIZEPROBE_H 27 | 28 | #include "dcfldd.h" 29 | #include 30 | 31 | enum {PROBE_NONE = 0, PROBE_INPUT, PROBE_OUTPUT, PROBE_INPUT_PROVIDED}; 32 | 33 | extern int probe; 34 | extern off_t probed_size; 35 | 36 | extern void sizeprobe(int); 37 | 38 | #endif /* SIZEPROBE_H */ 39 | -------------------------------------------------------------------------------- /src/split.c: -------------------------------------------------------------------------------- 1 | /* $Id: split.c,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 6 | Copyright 2008 David Loveall 7 | Copyright 2012 Miah Gregory 8 | Copyright 2015-2019 Joao Eriberto Mota Filho 9 | Copyright 2019 Bernhard Übelacker 10 | Copyright 2022 Tibor Szolnoki 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 2, or (at your option) 15 | 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, write to the Free Software Foundation, 24 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 25 | 26 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 27 | 28 | #define _GNU_SOURCE 1 29 | 30 | #include "dcfldd.h" 31 | 32 | #include 33 | 34 | #include "split.h" 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "full-write.h" 42 | #include "log.h" 43 | 44 | 45 | /* for portability, use these arrays for referencing numbers and letters */ 46 | static char *numbers = "0123456789"; 47 | #define NUM_NUMBERS 10 48 | static char *letters = "abcdefghijklmnopqrstuvwxyz"; 49 | #define NUM_LETTERS 26 50 | 51 | static char *getext(char *, int); 52 | static int maxsplits(char *); 53 | 54 | /* Generate a split file extension string based on 55 | * the specified format string and a given number 56 | */ 57 | static char *getext(char *fmt, int num) 58 | { 59 | int fmtlen = strlen(fmt); 60 | int i; 61 | char *retval; 62 | 63 | assert(fmtlen > 0); 64 | 65 | if (strcmp(fmt, "MAC") == 0) { 66 | if (num == 0) { 67 | if(asprintf(&retval, "dmg")) {}; 68 | } else { 69 | if(asprintf(&retval, "%03d.dmgpart", num+1)) {}; 70 | } 71 | return retval; 72 | } 73 | 74 | if (strcmp(fmt, "WIN") == 0) { 75 | if(asprintf(&retval, "%03d", num+1)) {}; 76 | return retval; 77 | } 78 | 79 | retval = malloc(fmtlen); 80 | 81 | /* Fill the retval in reverse while constantly dividing num apropriately */ 82 | for (i = fmtlen - 1; i >= 0; i--) { 83 | int x; 84 | 85 | if (fmt[i] == 'a') { 86 | x = num % NUM_LETTERS; 87 | retval[i] = letters[x]; 88 | num = num / NUM_LETTERS; 89 | } else { 90 | x = num % NUM_NUMBERS; 91 | retval[i] = numbers[x]; 92 | num = num / NUM_NUMBERS; 93 | } 94 | } 95 | 96 | retval[fmtlen] = '\0'; 97 | 98 | return retval; 99 | } 100 | 101 | /* Given a format string, determine the maximum number of splits 102 | * that can be used. */ 103 | static int maxsplits(char *fmt) 104 | { 105 | int fmtlen = strlen(fmt); 106 | int i; 107 | int retval = 1; 108 | 109 | assert(fmtlen > 0); 110 | 111 | for (i = fmtlen - 1; i >= 0; i--) 112 | retval *= fmt[i] == 'a' ? NUM_LETTERS : NUM_NUMBERS; 113 | 114 | return retval; 115 | } 116 | 117 | /* Open the next extension in a split sequence */ 118 | static void open_split(split_t *split) 119 | { 120 | int fd; 121 | int splitnum = split->total_bytes / split->max_bytes; 122 | mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 123 | char *ext, *fname; 124 | 125 | ext = getext(split->format, splitnum); 126 | /* [FIX] split.c:105:5: warning: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Wunused-result] */ 127 | if( asprintf(&fname, "%s.%s", split->name, ext) == -1) { 128 | free(ext); 129 | return; 130 | } 131 | free(ext); 132 | 133 | fd = open(fname, O_WRONLY | O_CREAT, perms); 134 | 135 | if (fd < 0) 136 | syscall_error(fname); 137 | 138 | close(split->currfd); 139 | split->currfd = fd; 140 | split->curr_bytes = 0; 141 | 142 | free(fname); 143 | } 144 | 145 | int split_write(split_t *split, const char *buf, size_t len, int diffwr) 146 | { 147 | off_t left = split->max_bytes - split->curr_bytes; 148 | int nwritten = 0; 149 | 150 | if (left == 0 || split->currfd == -1) { 151 | open_split(split); 152 | left = split->max_bytes; 153 | } 154 | 155 | if (len <= left) { 156 | nwritten = full_write(split->currfd, buf, len, diffwr); 157 | split->total_bytes += nwritten; 158 | split->curr_bytes += nwritten; 159 | } else { 160 | nwritten = full_write(split->currfd, buf, left, diffwr); 161 | split->total_bytes += nwritten; 162 | split->curr_bytes += nwritten; 163 | nwritten += split_write(split, &buf[nwritten], len - nwritten, diffwr); 164 | } 165 | 166 | return nwritten; 167 | } 168 | -------------------------------------------------------------------------------- /src/split.h: -------------------------------------------------------------------------------- 1 | /* $Id: split.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 6 | Copyright 2022 Tibor Szolnoki 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef SPLIT_H 25 | #define SPLIT_H 26 | 27 | #include "dcfldd.h" 28 | #include 29 | 30 | typedef struct 31 | { 32 | int currfd; 33 | off_t max_bytes; /* The split size */ 34 | off_t total_bytes; /* Total Bytes written sofar */ 35 | off_t curr_bytes; /* Bytes written to current split file */ 36 | char *name; 37 | char *format; 38 | } split_t; 39 | 40 | extern int split_write(split_t *, const char *, size_t, int diffwr); 41 | 42 | #endif /* SPLIT_H */ 43 | -------------------------------------------------------------------------------- /src/system.h: -------------------------------------------------------------------------------- 1 | /* system-dependent definitions for fileutils, textutils, and sh-utils packages. 2 | Copyright (C) 1989, 1991-2000 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Include sys/types.h before this file. */ 19 | 20 | #include 21 | 22 | #if !defined(HAVE_MKFIFO) 23 | # define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0)) 24 | #endif 25 | 26 | #if HAVE_SYS_PARAM_H 27 | # include 28 | #endif 29 | 30 | /* should be included before any preprocessor test 31 | of _POSIX_VERSION. */ 32 | #if HAVE_UNISTD_H 33 | # include 34 | #endif 35 | 36 | #ifndef STDIN_FILENO 37 | # define STDIN_FILENO 0 38 | #endif 39 | 40 | #ifndef STDOUT_FILENO 41 | # define STDOUT_FILENO 1 42 | #endif 43 | 44 | #ifndef STDERR_FILENO 45 | # define STDERR_FILENO 2 46 | #endif 47 | 48 | 49 | #if HAVE_LIMITS_H 50 | /* limits.h must come before pathmax.h because limits.h on some systems 51 | undefs PATH_MAX, whereas pathmax.h sets PATH_MAX. */ 52 | # include 53 | #endif 54 | 55 | #include "pathmax.h" 56 | 57 | #if TIME_WITH_SYS_TIME 58 | # include 59 | # include 60 | #else 61 | # if HAVE_SYS_TIME_H 62 | # include 63 | # else 64 | # include 65 | # endif 66 | #endif 67 | 68 | /* Since major is a function on SVR4, we can't use `ifndef major'. */ 69 | #if MAJOR_IN_MKDEV 70 | # include 71 | # define HAVE_MAJOR 72 | #endif 73 | #if MAJOR_IN_SYSMACROS 74 | # include 75 | # define HAVE_MAJOR 76 | #endif 77 | #ifdef major /* Might be defined in sys/types.h. */ 78 | # define HAVE_MAJOR 79 | #endif 80 | 81 | #ifndef HAVE_MAJOR 82 | # define major(dev) (((dev) >> 8) & 0xff) 83 | # define minor(dev) ((dev) & 0xff) 84 | # define makedev(maj, min) (((maj) << 8) | (min)) 85 | #endif 86 | #undef HAVE_MAJOR 87 | 88 | #if HAVE_UTIME_H 89 | # include 90 | #endif 91 | 92 | /* Don't use bcopy! Use memmove if source and destination may overlap, 93 | memcpy otherwise. */ 94 | 95 | #if HAVE_STRING_H 96 | # if !STDC_HEADERS && HAVE_MEMORY_H 97 | # include 98 | # endif 99 | # include 100 | #else 101 | # include 102 | #endif 103 | 104 | #include 105 | #ifndef errno 106 | extern int errno; 107 | #endif 108 | 109 | #if HAVE_STDLIB_H 110 | # define getopt system_getopt 111 | # include 112 | # undef getopt 113 | #endif 114 | 115 | /* The following test is to work around the gross typo in 116 | systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE 117 | is defined to 0, not 1. */ 118 | #if !EXIT_FAILURE 119 | # undef EXIT_FAILURE 120 | # define EXIT_FAILURE 1 121 | #endif 122 | 123 | #ifndef EXIT_SUCCESS 124 | # define EXIT_SUCCESS 0 125 | #endif 126 | 127 | #if HAVE_FCNTL_H 128 | # include 129 | #else 130 | # include 131 | #endif 132 | 133 | #if !defined (SEEK_SET) 134 | # define SEEK_SET 0 135 | # define SEEK_CUR 1 136 | # define SEEK_END 2 137 | #endif 138 | #ifndef F_OK 139 | # define F_OK 0 140 | # define X_OK 1 141 | # define W_OK 2 142 | # define R_OK 4 143 | #endif 144 | 145 | /* For systems that distinguish between text and binary I/O. 146 | O_BINARY is usually declared in fcntl.h */ 147 | #if !defined O_BINARY && defined _O_BINARY 148 | /* For MSC-compatible compilers. */ 149 | # define O_BINARY _O_BINARY 150 | # define O_TEXT _O_TEXT 151 | #endif 152 | 153 | #ifdef __BEOS__ 154 | /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ 155 | # undef O_BINARY 156 | # undef O_TEXT 157 | #endif 158 | 159 | #if O_BINARY 160 | # ifndef __DJGPP__ 161 | # define setmode _setmode 162 | # define fileno(_fp) _fileno (_fp) 163 | # endif /* not DJGPP */ 164 | # define SET_BINARY(_f) do {if (!isatty(_f)) setmode (_f, O_BINARY);} while (0) 165 | # define SET_BINARY2(_f1, _f2) \ 166 | do { \ 167 | if (!isatty (_f1)) \ 168 | { \ 169 | setmode (_f1, O_BINARY); \ 170 | if (!isatty (_f2)) \ 171 | setmode (_f2, O_BINARY); \ 172 | } \ 173 | } while(0) 174 | #else 175 | # define SET_BINARY(f) (void)0 176 | # define SET_BINARY2(f1,f2) (void)0 177 | # define O_BINARY 0 178 | # define O_TEXT 0 179 | #endif /* O_BINARY */ 180 | 181 | #if HAVE_DIRENT_H 182 | # include 183 | # define NLENGTH(direct) (strlen((direct)->d_name)) 184 | #else /* not HAVE_DIRENT_H */ 185 | # define dirent direct 186 | # define NLENGTH(direct) ((direct)->d_namlen) 187 | # if HAVE_SYS_NDIR_H 188 | # include 189 | # endif /* HAVE_SYS_NDIR_H */ 190 | # if HAVE_SYS_DIR_H 191 | # include 192 | # endif /* HAVE_SYS_DIR_H */ 193 | # if HAVE_NDIR_H 194 | # include 195 | # endif /* HAVE_NDIR_H */ 196 | #endif /* HAVE_DIRENT_H */ 197 | 198 | #if CLOSEDIR_VOID 199 | /* Fake a return value. */ 200 | # define CLOSEDIR(d) (closedir (d), 0) 201 | #else 202 | # define CLOSEDIR(d) closedir (d) 203 | #endif 204 | 205 | /* Get or fake the disk device blocksize. 206 | Usually defined by sys/param.h (if at all). */ 207 | #if !defined DEV_BSIZE && defined BSIZE 208 | # define DEV_BSIZE BSIZE 209 | #endif 210 | #if !defined DEV_BSIZE && defined BBSIZE /* SGI */ 211 | # define DEV_BSIZE BBSIZE 212 | #endif 213 | #ifndef DEV_BSIZE 214 | # define DEV_BSIZE 4096 215 | #endif 216 | 217 | /* Extract or fake data from a `struct stat'. 218 | ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes. 219 | ST_NBLOCKS: Number of blocks in the file, including indirect blocks. 220 | ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */ 221 | #ifndef HAVE_STRUCT_STAT_ST_BLOCKS 222 | # define ST_BLKSIZE(statbuf) DEV_BSIZE 223 | # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */ 224 | # define ST_NBLOCKS(statbuf) \ 225 | (S_ISREG ((statbuf).st_mode) \ 226 | || S_ISDIR ((statbuf).st_mode) \ 227 | ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0) 228 | # else /* !_POSIX_SOURCE && BSIZE */ 229 | # define ST_NBLOCKS(statbuf) \ 230 | (S_ISREG ((statbuf).st_mode) \ 231 | || S_ISDIR ((statbuf).st_mode) \ 232 | ? st_blocks ((statbuf).st_size) : 0) 233 | # endif /* !_POSIX_SOURCE && BSIZE */ 234 | #else /* HAVE_STRUCT_STAT_ST_BLOCKS */ 235 | /* Some systems, like Sequents, return st_blksize of 0 on pipes. */ 236 | # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \ 237 | ? (statbuf).st_blksize : DEV_BSIZE) 238 | # if defined(hpux) || defined(__hpux__) || defined(__hpux) 239 | /* HP-UX counts st_blocks in 1024-byte units. 240 | This loses when mixing HP-UX and BSD filesystems with NFS. */ 241 | # define ST_NBLOCKSIZE 1024 242 | # else /* !hpux */ 243 | # if defined(_AIX) && defined(_I386) 244 | /* AIX PS/2 counts st_blocks in 4K units. */ 245 | # define ST_NBLOCKSIZE (4 * 1024) 246 | # else /* not AIX PS/2 */ 247 | # if defined(_CRAY) 248 | # define ST_NBLOCKS(statbuf) \ 249 | (S_ISREG ((statbuf).st_mode) \ 250 | || S_ISDIR ((statbuf).st_mode) \ 251 | ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0) 252 | # endif /* _CRAY */ 253 | # endif /* not AIX PS/2 */ 254 | # endif /* !hpux */ 255 | #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */ 256 | 257 | #ifndef ST_NBLOCKS 258 | # define ST_NBLOCKS(statbuf) \ 259 | (S_ISREG ((statbuf).st_mode) \ 260 | || S_ISDIR ((statbuf).st_mode) \ 261 | ? (statbuf).st_blocks : 0) 262 | #endif 263 | 264 | #ifndef ST_NBLOCKSIZE 265 | # define ST_NBLOCKSIZE 512 266 | #endif 267 | 268 | #include "sys2.h" 269 | -------------------------------------------------------------------------------- /src/translate.c: -------------------------------------------------------------------------------- 1 | /* $Id: translate.c,v 1.4 2005/05/15 20:15:28 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2012 Miah Gregory 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 2, or (at your option) 12 | 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, write to the Free Software Foundation, 21 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 | 23 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 24 | 25 | #include "dcfldd.h" 26 | #include "log.h" 27 | #include "util.h" 28 | 29 | /* Output representation of newline and space characters. 30 | They change if we're converting to EBCDIC. */ 31 | unsigned char newline_character = '\n'; 32 | unsigned char space_character = ' '; 33 | 34 | /* Translation table formed by applying successive transformations. */ 35 | unsigned char trans_table[256]; 36 | 37 | unsigned char const ascii_to_ebcdic[] = 38 | { 39 | 0, 01, 02, 03, 067, 055, 056, 057, 40 | 026, 05, 045, 013, 014, 015, 016, 017, 41 | 020, 021, 022, 023, 074, 075, 062, 046, 42 | 030, 031, 077, 047, 034, 035, 036, 037, 43 | 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175, 44 | 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, 45 | 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, 46 | 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, 47 | 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, 48 | 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, 49 | 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, 50 | 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155, 51 | 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, 52 | 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, 53 | 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, 54 | 0247, 0250, 0251, 0300, 0152, 0320, 0241, 07, 55 | 040, 041, 042, 043, 044, 025, 06, 027, 56 | 050, 051, 052, 053, 054, 011, 012, 033, 57 | 060, 061, 032, 063, 064, 065, 066, 010, 58 | 070, 071, 072, 073, 04, 024, 076, 0341, 59 | 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, 60 | 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, 61 | 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, 62 | 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, 63 | 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, 64 | 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, 65 | 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, 66 | 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, 67 | 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, 68 | 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, 69 | 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, 70 | 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377 71 | }; 72 | 73 | unsigned char const ascii_to_ibm[] = 74 | { 75 | 0, 01, 02, 03, 067, 055, 056, 057, 76 | 026, 05, 045, 013, 014, 015, 016, 017, 77 | 020, 021, 022, 023, 074, 075, 062, 046, 78 | 030, 031, 077, 047, 034, 035, 036, 037, 79 | 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, 80 | 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, 81 | 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, 82 | 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, 83 | 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, 84 | 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, 85 | 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, 86 | 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155, 87 | 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, 88 | 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, 89 | 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, 90 | 0247, 0250, 0251, 0300, 0117, 0320, 0241, 07, 91 | 040, 041, 042, 043, 044, 025, 06, 027, 92 | 050, 051, 052, 053, 054, 011, 012, 033, 93 | 060, 061, 032, 063, 064, 065, 066, 010, 94 | 070, 071, 072, 073, 04, 024, 076, 0341, 95 | 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, 96 | 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, 97 | 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, 98 | 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, 99 | 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, 100 | 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, 101 | 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, 102 | 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, 103 | 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, 104 | 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, 105 | 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, 106 | 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377 107 | }; 108 | 109 | unsigned char const ebcdic_to_ascii[] = 110 | { 111 | 0, 01, 02, 03, 0234, 011, 0206, 0177, 112 | 0227, 0215, 0216, 013, 014, 015, 016, 017, 113 | 020, 021, 022, 023, 0235, 0205, 010, 0207, 114 | 030, 031, 0222, 0217, 034, 035, 036, 037, 115 | 0200, 0201, 0202, 0203, 0204, 012, 027, 033, 116 | 0210, 0211, 0212, 0213, 0214, 05, 06, 07, 117 | 0220, 0221, 026, 0223, 0224, 0225, 0226, 04, 118 | 0230, 0231, 0232, 0233, 024, 025, 0236, 032, 119 | 040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, 120 | 0247, 0250, 0133, 056, 074, 050, 053, 041, 121 | 046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, 122 | 0260, 0261, 0135, 044, 052, 051, 073, 0136, 123 | 055, 057, 0262, 0263, 0264, 0265, 0266, 0267, 124 | 0270, 0271, 0174, 054, 045, 0137, 076, 077, 125 | 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, 126 | 0302, 0140, 072, 043, 0100, 047, 075, 042, 127 | 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, 128 | 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, 129 | 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, 130 | 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320, 131 | 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170, 132 | 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327, 133 | 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, 134 | 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, 135 | 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, 136 | 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, 137 | 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, 138 | 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, 139 | 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, 140 | 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, 141 | 060, 061, 062, 063, 064, 065, 066, 067, 142 | 070, 071, 0372, 0373, 0374, 0375, 0376, 0377 143 | }; 144 | 145 | 146 | static void translate_charset(const unsigned char *new_trans) 147 | { 148 | unsigned int i; 149 | 150 | for (i = 0; i < 256; i++) 151 | trans_table[i] = new_trans[trans_table[i]]; 152 | translation_needed = 1; 153 | } 154 | 155 | /* Fix up translation table. */ 156 | 157 | void apply_translations(void) 158 | { 159 | unsigned int i; 160 | 161 | #define MX(a) (bit_count (conversions_mask & (a))) 162 | if ((MX (C_ASCII | C_EBCDIC | C_IBM) > 1) 163 | || (MX (C_BLOCK | C_UNBLOCK) > 1) 164 | || (MX (C_LCASE | C_UCASE) > 1) 165 | || (MX (C_UNBLOCK | C_SYNC) > 1)) 166 | { 167 | log_info("\ 168 | only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"); 169 | } 170 | #undef MX 171 | 172 | if (conversions_mask & C_ASCII) 173 | translate_charset(ebcdic_to_ascii); 174 | 175 | if (conversions_mask & C_UCASE) { 176 | for (i = 0; i < 256; i++) 177 | if (ISLOWER(trans_table[i])) 178 | trans_table[i] = TOUPPER(trans_table[i]); 179 | translation_needed = 1; 180 | } else if (conversions_mask & C_LCASE) { 181 | for (i = 0; i < 256; i++) 182 | if (ISUPPER(trans_table[i])) 183 | trans_table[i] = TOLOWER(trans_table[i]); 184 | translation_needed = 1; 185 | } 186 | 187 | if (conversions_mask & C_EBCDIC) { 188 | translate_charset (ascii_to_ebcdic); 189 | newline_character = ascii_to_ebcdic['\n']; 190 | space_character = ascii_to_ebcdic[' ']; 191 | } else if (conversions_mask & C_IBM) { 192 | translate_charset (ascii_to_ibm); 193 | newline_character = ascii_to_ibm['\n']; 194 | space_character = ascii_to_ibm[' ']; 195 | } 196 | } 197 | 198 | /* Apply the character-set translations specified by the user 199 | to the NREAD bytes in BUF. */ 200 | 201 | void translate_buffer(unsigned char *buf, size_t nread) 202 | { 203 | unsigned char *cp; 204 | size_t i; 205 | 206 | for (i = nread, cp = buf; i; i--, cp++) 207 | *cp = trans_table[*cp]; 208 | } 209 | -------------------------------------------------------------------------------- /src/translate.h: -------------------------------------------------------------------------------- 1 | /* $Id: translate.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef TRANSLATE_H 25 | #define TRANSLATE_H 26 | 27 | #include "dcfldd.h" 28 | #include 29 | 30 | extern unsigned char newline_character; 31 | extern unsigned char space_character; 32 | 33 | extern unsigned char trans_table[]; 34 | extern unsigned char const ascii_to_ebcdic[]; 35 | extern unsigned char const ascii_to_ibm[]; 36 | extern unsigned char const ebcdic_to_ascii[]; 37 | 38 | extern void translate_buffer(unsigned char *, size_t); 39 | extern void apply_translations(void); 40 | 41 | #endif /* TRANSLATE_H */ 42 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* $Id: util.h,v 1.6 2005/06/15 14:33:04 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2012 Miah Gregory 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 2, or (at your option) 12 | 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, write to the Free Software Foundation, 21 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 | 23 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 24 | 25 | #ifndef UTIL_H 26 | #define UTIL_H 27 | 28 | #include "dcfldd.h" 29 | #include "config.h" 30 | 31 | #if HAVE_INTTYPES_H 32 | # include 33 | #endif 34 | #include 35 | #include 36 | #include 37 | 38 | extern int buggy_lseek_support(int); 39 | extern uintmax_t skip(int, char *, uintmax_t, size_t, unsigned char *); 40 | extern unsigned char *swab_buffer(unsigned char *, size_t *); 41 | extern void time_left(char *, size_t, int); 42 | extern int bit_count(register unsigned int); 43 | extern void replace_escapes(char *); 44 | extern FILE *popen2(const char *, const char *); 45 | extern int pclose2(FILE *); 46 | 47 | #if (!HAVE_DECL_STRNDUP) 48 | extern char *strndup(const char *, size_t); 49 | #endif 50 | 51 | #endif /* UTIL_H */ 52 | -------------------------------------------------------------------------------- /src/verify.c: -------------------------------------------------------------------------------- 1 | /* $Id: verify.c,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 7 | Copyright 2015 Joao Eriberto Mota Filho 8 | Copyright 2019 Bernhard Übelacker 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 2, or (at your option) 13 | 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, write to the Free Software Foundation, 22 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 | 24 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 25 | 26 | #include "dcfldd.h" 27 | #include 28 | #include 29 | #include 30 | #include "config.h" 31 | #include "hash.h" 32 | #include "getpagesize.h" 33 | #include "safe-read.h" 34 | #include "sizeprobe.h" 35 | #include "pattern.h" 36 | #include "util.h" 37 | #include "log.h" 38 | 39 | static int verify_update(hashlist_t *, void *, void *, size_t, size_t); 40 | static void verify_remainder(hashlist_t *); 41 | 42 | /* The name of the verify file, or NULL if none. 43 | * Verify file is used as a secondary input file and the input 44 | * file is compared against it via the use of their hashes. */ 45 | char *verify_file = NULL; 46 | int verify_fd; 47 | FILE *verify_log; 48 | 49 | /* Skip this many records of `input_blocksize' bytes before reading */ 50 | uintmax_t vskip_records = 0; 51 | 52 | static int verify_update(hashlist_t *hashl, 53 | void *ibuf, void *vbuf, 54 | size_t ilen, size_t vlen) 55 | { 56 | size_t left_in_window = hash_windowlen - (bytes_in_window); 57 | int cmp = 0; 58 | 59 | if (bytes_in_total == 0) { 60 | hashl_init(hashl, TOTAL_CTX); 61 | hashl_init(hashl, VTOTAL_CTX); 62 | } 63 | 64 | if (hash_windowlen == 0) { 65 | hash_update_buf(hashl, WINDOW_CTX, TOTAL_CTX, ibuf, ilen); 66 | hash_update_buf(hashl, VWINDOW_CTX, VTOTAL_CTX, vbuf, vlen); 67 | } else { 68 | if (bytes_in_window == 0) { 69 | hashl_init(hashl, WINDOW_CTX); 70 | hashl_init(hashl, VWINDOW_CTX); 71 | } 72 | 73 | if (ilen >= left_in_window || vlen >= left_in_window) { 74 | char *ihash, *vhash; 75 | 76 | hash_update_buf(hashl, WINDOW_CTX, TOTAL_CTX, 77 | ibuf, min(ilen, left_in_window)); 78 | hash_update_buf(hashl, VWINDOW_CTX, VTOTAL_CTX, 79 | vbuf, min(vlen, left_in_window)); 80 | 81 | /* if verify ever wants to do more than one hash, change this */ 82 | hashl_final(hashl, WINDOW_CTX); 83 | ihash = strdup(hashl->hash->hashstr_buf); 84 | hashl_final(hashl, VWINDOW_CTX); 85 | vhash = hashl->hash->hashstr_buf; 86 | 87 | cmp = memcmp(ihash, vhash, hashl->hash->hashstr_buf_size); 88 | free(ihash); 89 | 90 | if (cmp != 0) 91 | { 92 | log_verifywindow(hashl->hash, window_beginning, 93 | (window_beginning + hash_windowlen), cmp); 94 | return 1; 95 | } 96 | 97 | window_beginning += hash_windowlen; 98 | 99 | bytes_in_window = 0; 100 | 101 | verify_update(hashl, ibuf + left_in_window, vbuf + left_in_window, 102 | ilen - left_in_window, vlen - left_in_window); 103 | } else { 104 | hash_update_buf(hashl, WINDOW_CTX, TOTAL_CTX, ibuf, ilen); 105 | hash_update_buf(hashl, VWINDOW_CTX, VTOTAL_CTX, vbuf, vlen); 106 | } 107 | } 108 | 109 | return 0; 110 | } 111 | 112 | static void verify_remainder(hashlist_t *hashl) 113 | { 114 | int cmp = 0; 115 | 116 | if (hash_windowlen > 0 && bytes_in_window > 0) { 117 | char *ihash, *vhash; 118 | 119 | hashl_final(hashl, WINDOW_CTX); 120 | ihash = strdup(hashl->hash->hashstr_buf); 121 | hashl_final(hashl, VWINDOW_CTX); 122 | vhash = hashl->hash->hashstr_buf; 123 | 124 | cmp = memcmp(ihash, vhash, hashl->hash->hashstr_buf_size); 125 | free(ihash); 126 | 127 | if (cmp != 0) 128 | log_verifywindow(hashl->hash, window_beginning, 129 | (window_beginning + hash_windowlen), cmp); 130 | } 131 | } 132 | 133 | /* The main loop when using the verify option. */ 134 | int dd_verify(void) 135 | { 136 | unsigned char *ibuf; /* Input buffer. */ 137 | unsigned char *vbuf; /* Verify buffer. */ 138 | unsigned char *real_ibuf; 139 | unsigned char *real_vbuf; 140 | ssize_t i_nread; /* Bytes read in the current input block. */ 141 | ssize_t v_nread; /* Bytes read in the current verify block. */ 142 | int exit_status = 0; 143 | int input_from_stream = !!input_file; 144 | int input_from_pattern = !input_from_stream; 145 | size_t page_size = getpagesize(); 146 | size_t n_bytes_read; 147 | size_t left_in_window; 148 | int mismatch = 0; 149 | int cmp = 0; 150 | 151 | real_ibuf = (unsigned char *) malloc(input_blocksize 152 | + 2 * SWAB_ALIGN_OFFSET 153 | + 2 * page_size - 1); 154 | ibuf = real_ibuf; 155 | ibuf += SWAB_ALIGN_OFFSET; /* allow space for swab */ 156 | 157 | ibuf = PTR_ALIGN(ibuf, page_size); 158 | 159 | real_vbuf = (unsigned char *) malloc(input_blocksize 160 | + 2 * SWAB_ALIGN_OFFSET 161 | + 2 * page_size - 1); 162 | vbuf = real_vbuf; 163 | vbuf += SWAB_ALIGN_OFFSET; /* allow space for swab */ 164 | 165 | vbuf = PTR_ALIGN(vbuf, page_size); 166 | 167 | if (!input_from_pattern) 168 | if (skip_records != 0) 169 | skip(STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf); 170 | 171 | if (vskip_records != 0) 172 | skip(verify_fd, verify_file, vskip_records, input_blocksize, vbuf); 173 | 174 | if (max_records == 0) 175 | quit(exit_status); 176 | 177 | if (input_from_pattern) { 178 | replicate_pattern(pattern, ibuf, input_blocksize); 179 | i_nread = input_blocksize; 180 | } 181 | 182 | while (1) 183 | { 184 | /* Display an update message */ 185 | if (do_status && w_full % update_thresh == 0 && w_full != 0) 186 | { 187 | off_t total_bytes = w_full * input_blocksize; 188 | off_t total_mb = total_bytes / 1048576; 189 | 190 | if (probe == PROBE_NONE || probed_size == 0) 191 | fprintf(stderr, "\r%llu blocks (%lluMb) written.", 192 | /* [FIX] verify.c:195:25: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument {3,4} has type ‘uintmax_t’ [-Wformat=] */ 193 | (long long unsigned int) w_full, (long long unsigned int) total_mb); 194 | else { 195 | time_t curr_time = time(NULL); 196 | int seconds = (int)difftime(curr_time, start_time); 197 | off_t probed_mb = probed_size / 1048576; 198 | float fprcnt = total_bytes / (float)probed_size; 199 | float fprcnt_remaining = 1.0 - fprcnt; 200 | int prcnt = (int)(fprcnt * 100); 201 | int seconds_remaining = (int)(seconds * 202 | (fprcnt_remaining / fprcnt)); 203 | char secstr[100]; 204 | 205 | time_left(secstr, sizeof secstr, seconds_remaining); 206 | fprintf(stderr, 207 | "\r[%d%% of %lluMb] %llu blocks (%lluMb) written. %s", 208 | /* [FIX] verify.c:210:25: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument {4,5,6} has type ‘off_t’ [-Wformat=] */ 209 | prcnt, (long long unsigned int) probed_mb, (long long unsigned int) w_full, (long long unsigned int) total_mb, secstr); 210 | } 211 | } 212 | 213 | if (r_partial + r_full >= max_records) 214 | break; 215 | 216 | v_nread = safe_read(verify_fd, vbuf, input_blocksize); 217 | 218 | if (v_nread < 0) 219 | syscall_error(input_file); 220 | 221 | /* Zero the buffer before reading, so that if we get a read error, 222 | whatever data we are able to read is followed by zeros. 223 | This minimizes data loss. */ 224 | if (input_from_pattern) { 225 | replicate_pattern(pattern, ibuf, v_nread); 226 | i_nread = v_nread; 227 | } else 228 | i_nread = safe_read(STDIN_FILENO, ibuf, input_blocksize); 229 | 230 | if (i_nread < 0 && !input_from_pattern) 231 | syscall_error(input_file); 232 | 233 | if (i_nread == 0 && v_nread == 0) 234 | break; 235 | 236 | left_in_window = hash_windowlen - bytes_in_window; 237 | mismatch = verify_update(ihashlist, ibuf, vbuf, i_nread, v_nread); 238 | 239 | if (i_nread != v_nread || (mismatch && i_nread < left_in_window)) { 240 | log_verifywindow(ihashlist->hash, window_beginning, 241 | (window_beginning + bytes_in_window), 1); 242 | mismatch = 1; 243 | } 244 | 245 | if (mismatch) 246 | break; 247 | } 248 | 249 | free(real_ibuf); 250 | free(real_vbuf); 251 | 252 | /* verifying a remainder and total wouldnt make sense if we 253 | * they won't match due to different amounts read. 254 | */ 255 | if (!mismatch) { 256 | char *ihash, *vhash; 257 | 258 | verify_remainder(ihashlist); 259 | 260 | hashl_final(ihashlist, TOTAL_CTX); 261 | ihash = strdup(ihashlist->hash->hashstr_buf); 262 | hashl_final(ihashlist, VTOTAL_CTX); 263 | vhash = ihashlist->hash->hashstr_buf; 264 | 265 | cmp = memcmp(ihash, vhash, ihashlist->hash->hashstr_buf_size); 266 | free(ihash); 267 | 268 | if (cmp != 0) 269 | log_verifywindow(ihashlist->hash, window_beginning, 270 | (window_beginning + bytes_in_window), cmp); 271 | 272 | log_verifytotal(ihashlist->hash, cmp); 273 | } else 274 | log_verifytotal(ihashlist->hash, 1); 275 | 276 | return exit_status; 277 | } 278 | -------------------------------------------------------------------------------- /src/verify.h: -------------------------------------------------------------------------------- 1 | /* $Id: verify.h,v 1.3 2005/05/13 18:52:06 harbourn Exp $ 2 | * dcfldd - The Enhanced Forensic DD 3 | * By Nicholas Harbour 4 | */ 5 | 6 | /* Copyright (C) 85, 90, 91, 1995-2001, 2005 Free Software Foundation, Inc. 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 2, or (at your option) 11 | 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, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 | 22 | /* GNU dd originally written by Paul Rubin, David MacKenzie, and Stuart Kemp. */ 23 | 24 | #ifndef VERIFY_H 25 | #define VERIFY_H 26 | 27 | #if HAVE_INTTYPES_H 28 | # include 29 | #endif 30 | #include 31 | #include "config.h" 32 | #include "dcfldd.h" 33 | #include "hash.h" 34 | 35 | extern char *verify_file; 36 | extern int verify_fd; 37 | extern FILE *verify_log; 38 | extern uintmax_t vskip_records; 39 | 40 | extern int dd_verify(void); 41 | 42 | #endif /* VERIFY_H */ 43 | -------------------------------------------------------------------------------- /src/version-etc.c: -------------------------------------------------------------------------------- 1 | /* Utility to help print --version output in a consistent format. 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by Jim Meyering. */ 19 | 20 | #if HAVE_CONFIG_H 21 | # include 22 | #endif 23 | 24 | #include 25 | #include "version-etc.h" 26 | 27 | /* Default copyright goes to the FSF. */ 28 | 29 | char* version_etc_copyright = 30 | "Copyright (C) 1985-2006 Free Software Foundation, Inc."; 31 | 32 | 33 | /* Display the --version information the standard way. 34 | 35 | If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of 36 | the program. The formats are therefore: 37 | 38 | PACKAGE VERSION 39 | 40 | or 41 | 42 | COMMAND_NAME (PACKAGE) VERSION. */ 43 | void 44 | version_etc (FILE *stream, 45 | const char *command_name, const char *package, 46 | const char *version, const char *authors) 47 | { 48 | if (command_name) 49 | fprintf (stream, "%s (%s) %s\n", command_name, package, version); 50 | else 51 | fprintf (stream, "%s %s\n", package, version); 52 | fprintf (stream, "Written by: %s.\n", authors); 53 | putc ('\n', stream); 54 | 55 | fputs (version_etc_copyright, stream); 56 | putc ('\n', stream); 57 | 58 | fputs ("\ 59 | This is free software; see the source for copying conditions. There is NO\n\ 60 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", 61 | stream); 62 | } 63 | -------------------------------------------------------------------------------- /src/version-etc.h: -------------------------------------------------------------------------------- 1 | /* Utility to help print --version output in a consistent format. 2 | Copyright (C) 1999 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by Jim Meyering. */ 19 | 20 | #ifndef VERSION_ETC_H 21 | # define VERSION_ETC_H 1 22 | 23 | # ifndef PARAMS 24 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 25 | # define PARAMS(Args) Args 26 | # else 27 | # define PARAMS(Args) () 28 | # endif 29 | # endif 30 | 31 | extern char *version_etc_copyright; 32 | 33 | void 34 | version_etc PARAMS ((FILE *stream, 35 | const char *command_name, const char *package, 36 | const char *version, const char *authors)); 37 | 38 | #endif /* VERSION_ETC_H */ 39 | -------------------------------------------------------------------------------- /src/xalloc.h: -------------------------------------------------------------------------------- 1 | /* xalloc.h -- malloc with out-of-memory checking 2 | Copyright (C) 1990-1998, 1999, 2000 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | #ifndef XALLOC_H_ 19 | # define XALLOC_H_ 20 | 21 | # ifndef PARAMS 22 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 23 | # define PARAMS(Args) Args 24 | # else 25 | # define PARAMS(Args) () 26 | # endif 27 | # endif 28 | 29 | # ifndef __attribute__ 30 | # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ 31 | # define __attribute__(x) 32 | # endif 33 | # endif 34 | 35 | # ifndef ATTRIBUTE_NORETURN 36 | # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 37 | # endif 38 | 39 | /* Exit value when the requested amount of memory is not available. 40 | It is initialized to EXIT_FAILURE, but the caller may set it to 41 | some other value. */ 42 | extern int xalloc_exit_failure; 43 | 44 | /* If this pointer is non-zero, run the specified function upon each 45 | allocation failure. It is initialized to zero. */ 46 | extern void (*xalloc_fail_func) PARAMS ((void)); 47 | 48 | /* If XALLOC_FAIL_FUNC is undefined or a function that returns, this 49 | message is output. It is translated via gettext. 50 | Its value is "memory exhausted". */ 51 | extern char const xalloc_msg_memory_exhausted[]; 52 | 53 | /* This function is always triggered when memory is exhausted. It is 54 | in charge of honoring the three previous items. This is the 55 | function to call when one wants the program to die because of a 56 | memory allocation failure. */ 57 | extern void xalloc_die PARAMS ((void)) ATTRIBUTE_NORETURN; 58 | 59 | void *xmalloc PARAMS ((size_t n)); 60 | void *xcalloc PARAMS ((size_t n, size_t s)); 61 | void *xrealloc PARAMS ((void *p, size_t n)); 62 | char *xstrdup PARAMS ((const char *str)); 63 | 64 | # define XMALLOC(Type, N_items) ((Type *) xmalloc (sizeof (Type) * (N_items))) 65 | # define XCALLOC(Type, N_items) ((Type *) xcalloc (sizeof (Type), (N_items))) 66 | # define XREALLOC(Ptr, Type, N_items) \ 67 | ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_items))) 68 | 69 | /* Declare and alloc memory for VAR of type TYPE. */ 70 | # define NEW(Type, Var) Type *(Var) = XMALLOC (Type, 1) 71 | 72 | /* Free VAR only if non NULL. */ 73 | # define XFREE(Var) \ 74 | do { \ 75 | if (Var) \ 76 | free (Var); \ 77 | } while (0) 78 | 79 | /* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */ 80 | # define CCLONE(Src, Num) \ 81 | (memcpy (xmalloc (sizeof (*Src) * (Num)), (Src), sizeof (*Src) * (Num))) 82 | 83 | /* Return a malloc'ed copy of SRC. */ 84 | # define CLONE(Src) CCLONE (Src, 1) 85 | 86 | 87 | #endif /* !XALLOC_H_ */ 88 | -------------------------------------------------------------------------------- /src/xstrtol.c: -------------------------------------------------------------------------------- 1 | /* A more useful interface to strtol. 2 | Copyright (C) 1995, 1996, 1998-2000 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by Jim Meyering. */ 19 | 20 | #if HAVE_CONFIG_H 21 | # include 22 | #endif 23 | 24 | #ifndef __strtol 25 | # define __strtol strtol 26 | # define __strtol_t long int 27 | # define __xstrtol xstrtol 28 | #endif 29 | 30 | /* Some pre-ANSI implementations (e.g. SunOS 4) 31 | need stderr defined if assertion checking is enabled. */ 32 | #include 33 | 34 | #if STDC_HEADERS 35 | # include 36 | #endif 37 | 38 | #if HAVE_STRING_H 39 | # include 40 | #else 41 | # include 42 | # ifndef strchr 43 | # define strchr index 44 | # endif 45 | #endif 46 | 47 | #include 48 | #include 49 | 50 | #include 51 | #ifndef errno 52 | extern int errno; 53 | #endif 54 | 55 | #if HAVE_LIMITS_H 56 | # include 57 | #endif 58 | 59 | #ifndef CHAR_BIT 60 | # define CHAR_BIT 8 61 | #endif 62 | 63 | /* The extra casts work around common compiler bugs. */ 64 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) 65 | /* The outer cast is needed to work around a bug in Cray C 5.0.3.0. 66 | It is necessary at least when t == time_t. */ 67 | #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ 68 | ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) 69 | #define TYPE_MAXIMUM(t) (~ (t) 0 - TYPE_MINIMUM (t)) 70 | 71 | #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) 72 | # define IN_CTYPE_DOMAIN(c) 1 73 | #else 74 | # define IN_CTYPE_DOMAIN(c) isascii(c) 75 | #endif 76 | 77 | #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) 78 | 79 | #include "xstrtol.h" 80 | 81 | static int 82 | bkm_scale (__strtol_t *x, int scale_factor) 83 | { 84 | __strtol_t product = *x * scale_factor; 85 | if (*x != product / scale_factor) 86 | return 1; 87 | *x = product; 88 | return 0; 89 | } 90 | 91 | static int 92 | bkm_scale_by_power (__strtol_t *x, int base, int power) 93 | { 94 | while (power--) 95 | if (bkm_scale (x, base)) 96 | return 1; 97 | 98 | return 0; 99 | } 100 | 101 | /* FIXME: comment. */ 102 | 103 | strtol_error 104 | __xstrtol (const char *s, char **ptr, int strtol_base, 105 | __strtol_t *val, const char *valid_suffixes) 106 | { 107 | char *t_ptr; 108 | char **p; 109 | __strtol_t tmp; 110 | 111 | assert (0 <= strtol_base && strtol_base <= 36); 112 | 113 | p = (ptr ? ptr : &t_ptr); 114 | 115 | if (! TYPE_SIGNED (__strtol_t)) 116 | { 117 | const char *q = s; 118 | while (ISSPACE ((unsigned char) *q)) 119 | ++q; 120 | if (*q == '-') 121 | return LONGINT_INVALID; 122 | } 123 | 124 | errno = 0; 125 | tmp = __strtol (s, p, strtol_base); 126 | if (errno != 0) 127 | return LONGINT_OVERFLOW; 128 | if (*p == s) 129 | return LONGINT_INVALID; 130 | 131 | /* Let valid_suffixes == NULL mean `allow any suffix'. */ 132 | /* FIXME: update all callers except the ones that allow suffixes 133 | after the number, changing last parameter NULL to `""'. */ 134 | if (!valid_suffixes) 135 | { 136 | *val = tmp; 137 | return LONGINT_OK; 138 | } 139 | 140 | if (**p != '\0') 141 | { 142 | int base = 1024; 143 | int suffixes = 1; 144 | int overflow; 145 | 146 | if (!strchr (valid_suffixes, **p)) 147 | { 148 | *val = tmp; 149 | return LONGINT_INVALID_SUFFIX_CHAR; 150 | } 151 | 152 | if (strchr (valid_suffixes, '0')) 153 | { 154 | /* The ``valid suffix'' '0' is a special flag meaning that 155 | an optional second suffix is allowed, which can change 156 | the base, e.g. "100MD" for 100 megabytes decimal. */ 157 | 158 | switch (p[0][1]) 159 | { 160 | case 'B': 161 | suffixes++; 162 | break; 163 | 164 | case 'D': 165 | base = 1000; 166 | suffixes++; 167 | break; 168 | } 169 | } 170 | 171 | switch (**p) 172 | { 173 | case 'b': 174 | overflow = bkm_scale (&tmp, 512); 175 | break; 176 | 177 | case 'B': 178 | overflow = bkm_scale (&tmp, 1024); 179 | break; 180 | 181 | case 'c': 182 | overflow = 0; 183 | break; 184 | 185 | case 'E': /* Exa */ 186 | overflow = bkm_scale_by_power (&tmp, base, 6); 187 | break; 188 | 189 | case 'G': /* Giga */ 190 | case 'g': /* 'g' is undocumented; for compatibility only */ 191 | overflow = bkm_scale_by_power (&tmp, base, 3); 192 | break; 193 | 194 | case 'k': /* kilo */ 195 | overflow = bkm_scale_by_power (&tmp, base, 1); 196 | break; 197 | 198 | case 'M': /* Mega */ 199 | case 'm': /* 'm' is undocumented; for compatibility only */ 200 | overflow = bkm_scale_by_power (&tmp, base, 2); 201 | break; 202 | 203 | case 'P': /* Peta */ 204 | overflow = bkm_scale_by_power (&tmp, base, 5); 205 | break; 206 | 207 | case 'T': /* Tera */ 208 | case 't': /* 't' is undocumented; for compatibility only */ 209 | overflow = bkm_scale_by_power (&tmp, base, 4); 210 | break; 211 | 212 | case 'w': 213 | overflow = bkm_scale (&tmp, 2); 214 | break; 215 | 216 | case 'Y': /* Yotta */ 217 | overflow = bkm_scale_by_power (&tmp, base, 8); 218 | break; 219 | 220 | case 'Z': /* Zetta */ 221 | overflow = bkm_scale_by_power (&tmp, base, 7); 222 | break; 223 | 224 | default: 225 | *val = tmp; 226 | return LONGINT_INVALID_SUFFIX_CHAR; 227 | break; 228 | } 229 | 230 | if (overflow) 231 | return LONGINT_OVERFLOW; 232 | 233 | (*p) += suffixes; 234 | } 235 | 236 | *val = tmp; 237 | return LONGINT_OK; 238 | } 239 | 240 | #ifdef TESTING_XSTRTO 241 | 242 | # include 243 | # include "dcfldd_error.h" 244 | 245 | char *program_name; 246 | 247 | int 248 | main (int argc, char** argv) 249 | { 250 | strtol_error s_err; 251 | int i; 252 | 253 | program_name = argv[0]; 254 | for (i=1; i%lu (%s)\n", argv[i], val, p); 263 | } 264 | else 265 | { 266 | STRTOL_FATAL_ERROR (argv[i], "arg", s_err); 267 | } 268 | } 269 | exit (0); 270 | } 271 | 272 | #endif /* TESTING_XSTRTO */ 273 | -------------------------------------------------------------------------------- /src/xstrtol.h: -------------------------------------------------------------------------------- 1 | #ifndef XSTRTOL_H_ 2 | # define XSTRTOL_H_ 1 3 | 4 | # if HAVE_INTTYPES_H 5 | # include /* for uintmax_t */ 6 | # endif 7 | 8 | # ifndef PARAMS 9 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) 10 | # define PARAMS(Args) Args 11 | # else 12 | # define PARAMS(Args) () 13 | # endif 14 | # endif 15 | 16 | # ifndef _STRTOL_ERROR 17 | enum strtol_error 18 | { 19 | LONGINT_OK, LONGINT_INVALID, LONGINT_INVALID_SUFFIX_CHAR, LONGINT_OVERFLOW 20 | }; 21 | typedef enum strtol_error strtol_error; 22 | # endif 23 | 24 | # define _DECLARE_XSTRTOL(name, type) \ 25 | strtol_error \ 26 | name PARAMS ((const char *s, char **ptr, int base, \ 27 | type *val, const char *valid_suffixes)); 28 | _DECLARE_XSTRTOL (xstrtol, long int) 29 | _DECLARE_XSTRTOL (xstrtoul, unsigned long int) 30 | _DECLARE_XSTRTOL (xstrtoumax, uintmax_t) 31 | 32 | # define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \ 33 | do \ 34 | { \ 35 | switch ((Err)) \ 36 | { \ 37 | case LONGINT_OK: \ 38 | abort (); \ 39 | \ 40 | case LONGINT_INVALID: \ 41 | dcfldd_error ((Exit_code), 0, "invalid %s `%s'", \ 42 | (Argument_type_string), (Str)); \ 43 | break; \ 44 | \ 45 | case LONGINT_INVALID_SUFFIX_CHAR: \ 46 | dcfldd_error ((Exit_code), 0, "invalid character following %s `%s'", \ 47 | (Argument_type_string), (Str)); \ 48 | break; \ 49 | \ 50 | case LONGINT_OVERFLOW: \ 51 | dcfldd_error ((Exit_code), 0, "%s `%s' too large", \ 52 | (Argument_type_string), (Str)); \ 53 | break; \ 54 | } \ 55 | } \ 56 | while (0) 57 | 58 | # define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \ 59 | _STRTOL_ERROR (2, Str, Argument_type_string, Err) 60 | 61 | # define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \ 62 | _STRTOL_ERROR (0, Str, Argument_type_string, Err) 63 | 64 | #endif /* not XSTRTOL_H_ */ 65 | -------------------------------------------------------------------------------- /src/xstrtoul.c: -------------------------------------------------------------------------------- 1 | #if HAVE_CONFIG_H 2 | # include "config.h" 3 | #endif 4 | 5 | #if HAVE_DECL_STRTOUL 6 | #define __strtol strtoul 7 | #define __strtol_t unsigned long int 8 | #define __xstrtol xstrtoul 9 | #include "xstrtol.c" 10 | #endif 11 | -------------------------------------------------------------------------------- /src/xstrtoumax.c: -------------------------------------------------------------------------------- 1 | /* xstrtoumax.c -- A more useful interface to strtoumax. 2 | Copyright 1999 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 | 18 | /* Written by Paul Eggert. */ 19 | 20 | #if HAVE_CONFIG_H 21 | # include 22 | #endif 23 | 24 | #if HAVE_INTTYPES_H 25 | # include 26 | #endif 27 | 28 | #if HAVE_DECL_STRTOUMAX 29 | #define __strtol strtoumax 30 | #define __strtol_t uintmax_t 31 | #define __xstrtol xstrtoumax 32 | #include "xstrtol.c" 33 | #endif 34 | --------------------------------------------------------------------------------