code:
Summary: A file integrity checksum tool
Name: @PACKAGE@
Version: @VERSION@
Release: 1
License: GPL
Group: System
Source: @PACKAGE@-@VERSION@.tar.gz
#Source0: http://dennisk.customer.netspace.net.au/checkit/@PACKAGE@-@VERSION@.tar.gz

URL: http://dennisk.customer.netspace.net.au/checkit.html
Distribution: Fedora
Vendor: DK Soft
Packager: Dennis Katsonis <dennisk@netspace.net.au>
%global debug_package %{nil}

%description
Checksum adds additions data assurance
capabilities to filesystems which support
extended attributes.  Checkit allows you
to detect any otherwise undetected data
integrity issues or file changes to any file.
By storing a checksum as an extended attribute,
checkit provides an easy way to detect any
silent data corruption, bit rot or otherwise
undetected error.

%prep
%setup

%build
%_configure --prefix=/usr CFLAGS="-DNDEBUG -O3" --without-gcc-arch
make

%install
rm -rf $RPM_BUILD_ROOT
make install-strip DESTDIR=$RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%{_docdir}/*
%{_bindir}/*
%{_mandir}/man1/*
#/usr/share/doc/checkit/README

%clean
rm -rf $RPM_BUILD_ROOT


code:
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Name of package */
#undef PACKAGE

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Define to 1 if all of the C90 standard headers exist (not just the ones
   required in a freestanding environment). This macro is provided for
   backward compatibility; new code need not use it. */
#undef STDC_HEADERS

/* Version number of package */
#undef VERSION

/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
   #define below would cause a syntax error. */
#undef _UINT64_T

/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
   #define below would cause a syntax error. */
#undef _UINT8_T

/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

/* Define to the type of an unsigned integer type of width exactly 64 bits if
   such a type exists and the standard includes do not define it. */
#undef uint64_t

/* Define to the type of an unsigned integer type of width exactly 8 bits if
   such a type exists and the standard includes do not define it. */
#undef uint8_t

repo_name: BoraxMan/checkit

license: mit


code:
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([checkit], [0.5.3], [dennisk@netspace.net.au])
AM_INIT_AUTOMAKE()
AC_OUTPUT(Makefile src/Makefile doc/Makefile man/Makefile)
AC_CONFIG_SRCDIR([src/checkit.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h unistd.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T

AC_OUTPUT(checkit.spec)
AC_OUTPUT(man/checkit.1)

AC_OUTPUT


code:
docdir = $(datadir)/doc/@PACKAGE@
dist_doc_DATA = README LICENSE


code:
CHECKIT
=======

Checkit is a file integrity tool for Linux and Unix systems.

Checkit Copyright (C) 2014 Dennis Katsonis

LICENCE INFO
------------

Checkit is free software distributed under the GNU GPL.  See below for
copyright for CRC64.

WHAT THIS PROGRAM DOES:
-----------------------

Checksum adds additions data assurance capabilities to filesystems which
support extended attributes.  Checkit allows you to detect any otherwise
undetected data integrity issues or file changes to any file.  By storing
a checksum as an extended attribute, checkit provides an easy way to
detect any silent data corruption, bit rot or otherwise modified error.

This was inspired by the checksumming that is performed by filesystems
like BTRFS and ZFS.  These filesystems ensure data integrity by storing
a checksum (CRC) of data and checking read data against the checksum.
With mirroring of data, they can silently heal the data should an error
be found.

This program does not duplicate this ability, but offers rudimentary
checksum abilities for other filesystems.  It simply calculates a
checksum and stores the checksum with the file.  It can then be later
used to verify the checksum against the data.  Any data corruption of
file changes would result in a failed check.

WHY IT WAS CREATED:
-------------------

Moving data from disk to disk, or leaving data on the disk, leaves a
very small possibility of silent data corruption.  While rare, the large
amounts of data being handled by drives make silent corruption a real
possibility.  While BTRFS and ZFS can handle this, other filesystems
can't.  This program was created to add an ability to detect (but not
fix) issues.  With the ability to detect, you can easily find out whether
a copy or extract operation occured perfectly, or whether there has been
bit rot in the file.

Backups provide point of reference, but comparison isn't very efficient,
as it involves reading two files.  Using a CRC, you only need to read
the file once, even after a copy operation to determine whether the file
is OK.  Also, should the file be different from the backup, which copy
is OK, the backup or the original?  Checkit will let you know whether
it is the backup or original which has changed.

There are other ways to do this.  You can use a cryptographic hash
and store a SHA-1 or MD5 or SHA-256 value in a seperate file, or even
use GPG and digitally sign the file.  The problem is, that the value
is stored in a seperate file, and doing directory recursion, or all
files of a particular type (i.e., all JPG's isn't as straighforward.
With checkit, the CRC is stored as an extended attribute.  It remains
as part of the file, and can be copied or archived automatically with
the file.  No need for seperate files to store the hash/checksum.

Checkit also has the ability to export this to a hidden file, and import
it back into an extended attribute.

HOW TO USE:
-----------

Checkit calculates and stores the CRC as an extended attribute
(user.crc64) or as a hidden file.  The file must reside on a filesystem
which supports extended attributes (XFS, JFS, EXT2, EXT3, EXT4, BTRFS,
ReiserFS among others) to use the extended attribute (recommended).

First, run checkit to store the CRC as an attribute, then at any time,
you can run checkit to check that the file data still matches the CRC.
If any of the files don't match, or the CRC is missing, checkit will
report it.  If you pass the "verbose" option, checkit will summarise
the files that didn't pass the checksum test at the end of the run.

Checkit allows you to determine whether the checksum is 'read only'
or 'read write', using the -d and -u options.  A 'read only' checksum
will not be updated, unless the '-o' overwrite option is used.  This
way, the checksum is not inadvertantly updated when rerunning checkit
over it.  A 'read write' checksum can be updated, and can be used in
those cases where you want to rerun checkit over the file, and
recompute the checksum because of intended changes.  For the most
part, checkit is intended for files you want to remain static,
such as your precious family photos and movies, archives and such.

OPERATION:
----------

checkit [OPTION] [FILE]

Options:

-V	Print licence
-s	Calcuates and stores the checksum.
-c	Check file against stored checksum.
-v	Verbose.  Print more information.
-p	Display CRC64 checksum.
-x	Remove stored checksum.  This simply deletes the extended
attribute.
-o	Overwite existing checksum.  By default, checkit does not
overwrite an existing checkum.	This option allows you to update the
checksum, should the file be deliberately altered).
-r	Recurse through subdirectories.
-e	Export CRC to a hidden file.
-i	Import CRC from a hidden file.
-d	Disallow updating of CRC on this file
(for files you do not intend to change)
-u	Allow CRC on this file to be updated (for files you intend
to change)
[FILE] can include wildcards.

Examples:

checkit -s -o picture.jpg	;Calculates checksum of picture.jpg and
overwrites old CRC64
checkit -s -r .			;Processes current directory and all
sub-directories and files.
checkit -c -r pictures/		;Check the enture pictures
directory. Checkit will report whether all files are OK or not.

checkit \-d  dissertation.txt	;Sets the CRC as read only.
Checkit will NOT update the CRC if you try to store the checksum again.

checkit \-u dissertation.txt	;Setc the CRC as read write.
Checkit will update the checksum if you run it with the -s option.

LIMITATIONS:
------------

As checkit doesn't repair files, you need to ensure that you have backups
of important data.  Checkit by default stores the CRC in an extended
attribute.

If the checksum is stored as an extended attribute, which is the default,
it will be lost if you transfer the file to a filesystem which does not
support extended attributes, or the method of copying does not preserve
them.  If you export the CRC, then the CRC can travel with the file as long
as you copy the CRC hidden file as well.

Checkit cannot detect changes and recompute the checksum without being run
manually, because it doesn't run in the background.  While having a 'checkit'
daemon, which can automatically update the checksum should the file be
changed is potentially useful, this is better done by migrating to BTRFS
or ZFS, which handles this more efficiently than checkit ever could.

TODO:
-----

* Intergration with file managers.

CRC64 routine.

The checksum routine is the crc-64-jones created by Salvatore Sanfilippo.

path: doc/README


code:
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2011-11-20.07; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

nl='
'
IFS=" ""	$nl"

# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
  doit_exec=exec
else
  doit_exec=$doit
fi

# Put in absolute file names if you don't have them in your path;
# or use environment vars.

chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}

posix_glob='?'
initialize_posix_glob='
  test "$posix_glob" != "?" || {
    if (set -f) 2>/dev/null; then
      posix_glob=
    else
      posix_glob=:
    fi
  }
'

posix_mkdir=

# Desired mode of installed file.
mode=0755

chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

src=
dst=
dir_arg=
dst_arg=

copy_on_change=false
no_target_directory=

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
	shift;;

    --help) echo "$usage"; exit $?;;

    -m) mode=$2
	case $mode in
	  *' '* | *'	'* | *'
'*	  | *'*'* | *'?'* | *'['*)
	    echo "$0: invalid mode: $mode" >&2
	    exit 1;;
	esac
	shift;;

    -o) chowncmd="$chownprog $2"
	shift;;

    -s) stripcmd=$stripprog;;

    -t) dst_arg=$2
	# Protect names problematic for 'test' and other utilities.
	case $dst_arg in
	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
	esac
	shift;;

    -T) no_target_directory=true;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --)	shift
	break;;

    -*)	echo "$0: invalid option: $1" >&2
	exit 1;;

    *)  break;;
  esac
  shift
done

if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg
    # Protect names problematic for 'test' and other utilities.
    case $dst_arg in
      -* | [=\(\)!]) dst_arg=./$dst_arg;;
    esac
  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call 'install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
	u_plus_rw=
      else
	u_plus_rw='% 200'
      fi
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
	u_plus_rw=
      else
	u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names problematic for 'test' and other utilities.
  case $src in
    -* | [=\(\)!]) src=./$src;;
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
      exit 1
    fi

    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi
    dst=$dst_arg

    # If destination is a directory, append the input filename; won't work
    # if double slashes aren't ignored.
    if test -d "$dst"; then
      if test -n "$no_target_directory"; then
	echo "$0: $dst_arg: Is a directory" >&2
	exit 1
      fi
      dstdir=$dst
      dst=$dstdir/`basename "$src"`
      dstdir_status=0
    else
      # Prefer dirname, but fall back on a substitute if dirname fails.
      dstdir=`
	(dirname "$dst") 2>/dev/null ||
	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	     X"$dst" : 'X\(//\)[^/]' \| \
	     X"$dst" : 'X\(//\)$' \| \
	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
	echo X"$dst" |
	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)[^/].*/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\).*/{
		   s//\1/
		   q
		 }
		 s/.*/./; q'
      `

      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
	# Create intermediate dirs using mode 755 as modified by the umask.
	# This is like FreeBSD 'install' as of 1997-10-28.
	umask=`umask`
	case $stripcmd.$umask in
	  # Optimize common cases.
	  *[2367][2367]) mkdir_umask=$umask;;
	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;

	  *[0-7])
	    mkdir_umask=`expr $umask + 22 \
	      - $umask % 100 % 40 + $umask % 20 \
	      - $umask % 10 % 4 + $umask % 2
	    `;;
	  *) mkdir_umask=$umask,go-w;;
	esac

	# With -d, create the new directory with the user-specified mode.
	# Otherwise, rely on $mkdir_umask.
	if test -n "$dir_arg"; then
	  mkdir_mode=-m$mode
	else
	  mkdir_mode=
	fi

	posix_mkdir=false
	case $umask in
	  *[123567][0-7][0-7])
	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
	    ;;
	  *)
	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0

	    if (umask $mkdir_umask &&
		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
	    then
	      if test -z "$dir_arg" || {
		   # Check for POSIX incompatibilities with -m.
		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
		   # other-writable bit of parent directory when it shouldn't.
		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
		   case $ls_ld_tmpdir in
		     d????-?r-*) different_mode=700;;
		     d????-?--*) different_mode=755;;
		     *) false;;
		   esac &&
		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
		   }
		 }
	      then posix_mkdir=:
	      fi
	      rmdir "$tmpdir/d" "$tmpdir"
	    else
	      # Remove any dirs left behind by ancient mkdir implementations.
	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
	    fi
	    trap '' 0;;
	esac;;
    esac

    if
      $posix_mkdir && (
	umask $mkdir_umask &&
	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )
    then :
    else

      # The umask is ridiculous, or mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
	/*) prefix='/';;
	[-=\(\)!]*) prefix='./';;
	*)  prefix='';;
      esac

      eval "$initialize_posix_glob"

      oIFS=$IFS
      IFS=/
      $posix_glob set -f
      set fnord $dstdir
      shift
      $posix_glob set +f
      IFS=$oIFS

      prefixes=

      for d
      do
	test X"$d" = X && continue

	prefix=$prefix$d
	if test -d "$prefix"; then
	  prefixes=
	else
	  if $posix_mkdir; then
	    (umask=$mkdir_umask &&
	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
	    # Don't fail if two instances are running concurrently.
	    test -d "$prefix" || exit 1
	  else
	    case $prefix in
	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
	      *) qprefix=$prefix;;
	    esac
	    prefixes="$prefixes '$qprefix'"
	  fi
	fi
	prefix=$prefix/
      done

      if test -n "$prefixes"; then
	# Don't fail if two instances are running concurrently.
	(umask $mkdir_umask &&
	 eval "\$doit_exec \$mkdirprog $prefixes") ||
	  test -d "$dstdir" || exit 1
	obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=$dstdir/_inst.$$_
    rmtmp=$dstdir/_rm.$$_

    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0

    # Copy the file name to the temp name.
    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #
    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&

       eval "$initialize_posix_glob" &&
       $posix_glob set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       $posix_glob set +f &&

       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
	# Now remove or move aside any old file at destination location.
	# We try this two ways since rm can't unlink itself on some
	# systems and the destination file might be busy for other
	# reasons.  In this case, the final cleanup might fail but the new
	# file should still install successfully.
	{
	  test ! -f "$dst" ||
	  $doit $rmcmd -f "$dst" 2>/dev/null ||
	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
	  } ||
	  { echo "$0: cannot unlink or rename $dst" >&2
	    (exit 1); exit 1
	  }
	} &&

	# Now rename the file to the real destination.
	$doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

path: install-sh


code:
man_MANS = checkit.1
#dist_doc_DATA = checkit.1


code:
.\" Manpage for checkit.
.\" Contact dennisk@netspace.net.au.
.TH "man" "8" "28 June 2015" "@VERSION@" "checkit man page"
.SH "NAME"
checkit \- Checkit is a file integrity tool for Linux and Unix systems.
.SH "SYNOPSIS"
checkit [OPTIONS]
.I [FILES]
.SH "DESCRIPTION"
Checksum adds additions data assurance capabilities to filesystems which support extended attributes.  Checkit allows you to detect any otherwise undetected data integrity issues or file changes to any file.  By storing a checksum as an extended attribute, checkit provides an easy way to detect any silent data corruption, bit rot or otherwise modified error.

.SH "OPTIONS"
.IP \-V
Print license
.IP \-s
Calcuates and stores the checksum.
.IP \-c
Check file against stored checksum.
.IP \-v
Verbose.  Print more information.
.IP \-p
Display CRC64 checksum.
.IP \-x
Remove stored checksum.  This simply deletes the extended attribute.
.IP \-o
Overwrite existing checksum.  By default, checkit does not overwrite an existing checksum.  This option allows you to update the checksum, should the file be deliberately altered).
.IP \-r
Recurse through subdirectories.
.IP\-e
Export CRC to a hidden file.
.IP\-i
Import CRC from a hidden file.
.IP\-d
Disallow updating of CRC on this file (for files you do not intend to change)
.IP\-u
Allow CRC on this file to be updated (for files you intend to change)
.IP\-m
Force monochrome (disable colours).

.SH "EXAMPLES"
checkit \-s \-o picture.jpg	;Calculates checksum of picture.jpg and overwrites old CRC64

checkit \-s \-r .			;Processes current directory and all sub\-directories and files.

checkit \-c \-r pictures/         ;Check the entire pictures directory. Checkit will report whether all files are OK or not.

checkit \-d  dissertation.txt	;Sets the CRC as read only.  Checkit will NOT update the CRC if you try to store the checksum again.

checkit \-u dissertation.txt	;Sets the CRC as read write.  Checkit will update the checksum if you run it with the -s option.

.SH "NOTES"

By default, once checkit has created a checksum on a file, it will refuse to update or overwrite it if you try to calculate and store the CRC again.
This is to protect against inadvertent updates, should it accidentally be ran again.  This way, you can detect any changes or errors.
If you DO plan to edit or modify the file, then you can set the checksum as 'read/write' by using the \-d option, which will allows checkit to update the checksum if run again on the file.  This gives you a 'per file' level of control as to whether you want checkit to recalculate files you plan to change, or to avoid recalculating files you don't want changed at all.

Checkit will use a 'hidden file', which has the same name as the files name, but with a '.' at the beginning and a '.crc64' at the end, if it cannot use extended attributes (i.e., you are running it on a file over NFS or on a FAT32 formatted flash drive).

Output will be monochrome when the output is not a terminal, or if the NO_COLOR environmental variable is set to any non-empty value.  See https://no-color.org for info on this informal standard.  Otherwise, output will be coloured.

.SH "LIMITATIONS"
As checkit doesn't repair files, you need to ensure that you have backups of important data.  Checkit stores the CRC in an extended attribute.  This attribute won't be transferred when copying to a filesystem which doesn't support extended attributes, or archived using an archiver which doesn't store them.  Also, when copying, ensure the file manager/copy utility copies attributes.  If you transfer the file to a filesystem which does not support extended attributes, you can use the 'export' function to create a hidden files, to allow checkit to continue to function on the file for other filesystems (such as UDF/ISO9660).

.SH "BUGS"
No known bugs.

.SH "AUTHOR"
Dennis Katsonis (dennisk@netspace.net.au)


code:
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.

scriptversion=2013-10-28.13; # UTC

# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

if test $# -eq 0; then
  echo 1>&2 "Try '$0 --help' for more information"
  exit 1
fi

case $1 in

  --is-lightweight)
    # Used by our autoconf macros to check whether the available missing
    # script is modern enough.
    exit 0
    ;;

  --run)
    # Back-compat with the calling convention used by older automake.
    shift
    ;;

  -h|--h|--he|--hel|--help)
    echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...

Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.

Options:
  -h, --help      display this help and exit
  -v, --version   output version information and exit

Supported PROGRAM values:
  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
  bison     yacc      flex         lex       help2man

Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.

Send bug reports to <bug-automake@gnu.org>."
    exit $?
    ;;

  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
    echo "missing $scriptversion (GNU Automake)"
    exit $?
    ;;

  -*)
    echo 1>&2 "$0: unknown '$1' option"
    echo 1>&2 "Try '$0 --help' for more information"
    exit 1
    ;;

esac

# Run the given program, remember its exit status.
"$@"; st=$?

# If it succeeded, we are done.
test $st -eq 0 && exit 0

# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac

# Exit code 63 means version mismatch.  This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
  msg="probably too old"
elif test $st -eq 127; then
  # Program was missing.
  msg="missing on your system"
else
  # Program was found and executed, but failed.  Give up.
  exit $st
fi

perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software

program_details ()
{
  case $1 in
    aclocal|automake)
      echo "The '$1' program is part of the GNU Automake package:"
      echo "<$gnu_software_URL/automake>"
      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
      echo "<$gnu_software_URL/autoconf>"
      echo "<$gnu_software_URL/m4/>"
      echo "<$perl_URL>"
      ;;
    autoconf|autom4te|autoheader)
      echo "The '$1' program is part of the GNU Autoconf package:"
      echo "<$gnu_software_URL/autoconf/>"
      echo "It also requires GNU m4 and Perl in order to run:"
      echo "<$gnu_software_URL/m4/>"
      echo "<$perl_URL>"
      ;;
  esac
}

give_advice ()
{
  # Normalize program name to check for.
  normalized_program=`echo "$1" | sed '
    s/^gnu-//; t
    s/^gnu//; t
    s/^g//; t'`

  printf '%s\n' "'$1' is $msg."

  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
  case $normalized_program in
    autoconf*)
      echo "You should only need it if you modified 'configure.ac',"
      echo "or m4 files included by it."
      program_details 'autoconf'
      ;;
    autoheader*)
      echo "You should only need it if you modified 'acconfig.h' or"
      echo "$configure_deps."
      program_details 'autoheader'
      ;;
    automake*)
      echo "You should only need it if you modified 'Makefile.am' or"
      echo "$configure_deps."
      program_details 'automake'
      ;;
    aclocal*)
      echo "You should only need it if you modified 'acinclude.m4' or"
      echo "$configure_deps."
      program_details 'aclocal'
      ;;
   autom4te*)
      echo "You might have modified some maintainer files that require"
      echo "the 'autom4te' program to be rebuilt."
      program_details 'autom4te'
      ;;
    bison*|yacc*)
      echo "You should only need it if you modified a '.y' file."
      echo "You may want to install the GNU Bison package:"
      echo "<$gnu_software_URL/bison/>"
      ;;
    lex*|flex*)
      echo "You should only need it if you modified a '.l' file."
      echo "You may want to install the Fast Lexical Analyzer package:"
      echo "<$flex_URL>"
      ;;
    help2man*)
      echo "You should only need it if you modified a dependency" \
           "of a man page."
      echo "You may want to install the GNU Help2man package:"
      echo "<$gnu_software_URL/help2man/>"
    ;;
    makeinfo*)
      echo "You should only need it if you modified a '.texi' file, or"
      echo "any other file indirectly affecting the aspect of the manual."
      echo "You might want to install the Texinfo package:"
      echo "<$gnu_software_URL/texinfo/>"
      echo "The spurious makeinfo call might also be the consequence of"
      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
      echo "want to install GNU make:"
      echo "<$gnu_software_URL/make/>"
      ;;
    *)
      echo "You might have modified some files without having the proper"
      echo "tools for further handling them.  Check the 'README' file, it"
      echo "often tells you about the needed prerequisites for installing"
      echo "this package.  You may also peek at any GNU archive site, in"
      echo "case some other package contains this missing '$1' program."
      ;;
  esac
}

give_advice "$1" | sed -e '1s/^/WARNING: /' \
                       -e '2,$s/^/         /' >&2

# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

path: missing


code:
#AM_CFLAGS = -Wall -O3 -s
#AM_LDFLAGS =
AM_CFLAGS =  '-DDATADIR="$(datadir)"' -I$(srcdir)/../include -I$(srcdir)

bin_PROGRAMS = checkit
checkit_SOURCES = checkit_cli.c checkit.c checkit_attr.c crc64.c vfat_attr.c ntfs_attr.c strarray.c checkit_attr.h crc64.h checkit_attr.h strarray.h fsmagic.h


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <fcntl.h>
#include <stdio.h>
#include <attr/xattr.h>
#include <linux/limits.h>
#include <sys/statfs.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <libgen.h>

#include "checkit.h"
#include "fsmagic.h"

const int MAX_BUF_LEN  = 65536;
int processed = 0;
int failed = 0;
int nocrc = 0;

const char* attributeName = "user.crc64";

const char* errorMessage(int error)
{ /* Standardised error messages. */
  char *_error[] = {
    "Success",
    "Failed to calculate CRC from file.",
    "Failed to remove extended attribute.",
    "Could not store CRC.",
    "Could not open directory.",
    "Could not open file.",
    "Could not read file.",
    "Setting CRC failed.  Could not write attribute.",
    "Could not remove hidden checksum file.",
    "No extended attribute to export.",
    "Can not overwrite existing checksum.",
    "Could not write to file.",
    "Filename too long."
  };
  return _error[error];
}

char* hiddenCRCFile(const char *file)
{ /* Returns a string with the filename of the hidden CRC file */
  static char crc_file[PATH_MAX - 1] = "\0";
  char *base_filename;
  char *dir_filename;
  char *_filename;

  _filename = strdup(file);

  base_filename = basename(_filename);
  dir_filename = dirname(_filename);
  sprintf(crc_file, "%s//.%s.crc64", dir_filename, base_filename);

  free(_filename); /* It seems basename() and dirname() refer to this string,
		    * so we cannot free it until we are done with the strings
		    * it provides. */
  return(crc_file);
}

static int fileExists(const char* file) {
  struct stat buf;
  return (stat(file, &buf) == 0);
}

int presentCRC64(const char *file)
{  /* Check if CRC64 attribute is present. Returns XATTR if xattr, HIDDEN if hidden file. */
  char buf[LIST_XATTR_BUFFER_SIZE];
  char *current_attr = NULL;
  int x;

  x = listxattr(file,buf,LIST_XATTR_BUFFER_SIZE);
  current_attr = buf;

  if (x != 0)
  {
  do {
      if (strcmp(current_attr, attributeName) == 0)
      {
          return XATTR;
      }
      else
      {
        current_attr += (strlen(current_attr) + 1);
      }

    } while ((current_attr - buf) < x);
  }
  /* No attribute?  Lets look for an existing hidden file. */

  if (fileExists(hiddenCRCFile(file)))
    return HIDDEN_ATTR;

  errno = 0; /* Clear errno from any previous issue. We will be printing
	      * an error message, but it is not related to any previous error
	      * encountered (such as not finding the hidden CRC file. */

 return 0;
}

int exportCRC(const char *filename, int flags)
{
  int file_handle;
  fileCRC result;

  if (presentCRC64(filename) != XATTR)
    return ERROR_NO_XATTR; /* No extended attribute to export. */

  if (fileExists(hiddenCRCFile(filename)) && (!(flags & OVERWRITE)))
    return ERROR_NO_OVERWRITE; /* Don't overwrite attribute unless allowed. */

  if ((file_handle = open(hiddenCRCFile(filename), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1)
    return ERROR_OPEN_FILE;

  result = getCRC(filename);
  if(result.status != SUCCESS) /* If 0 returned (error), return with error being we couldn't read the file.
	      * perror will print more detail. */
    return ERROR_READ_FILE;

  write(file_handle, &crc64, sizeof (t_crc64));
  close(file_handle);

  if ((removexattr(filename, attributeName)) == -1)
    return ERROR_REMOVE_XATTR;

  return SUCCESS;
}

int removeCRC(const char *filename)
{ /* Removes CRC, either the xattr, hidden file, or both */
  if (presentCRC64(filename) == XATTR)
  {
    if ((removexattr(filename, attributeName)) == -1)
      return ERROR_REMOVE_XATTR;
  }
  if (presentCRC64(filename) == HIDDEN_ATTR)
    if ((unlink(hiddenCRCFile(filename)) == -1) && VERBOSE)
      return ERROR_REMOVE_HIDDEN;

  return SUCCESS;
}

int importCRC(const char *filename, int flags)
{
  int file_handle;
  t_crc64 crc64;
  int ATTRFLAGS;

  ATTRFLAGS = (flags & OVERWRITE) ? 0 : XATTR_CREATE;

  if ((presentCRC64(filename) != HIDDEN_ATTR) && (flags & OVERWRITE))
    return ERROR_NO_OVERWRITE;

  if ((file_handle = open(hiddenCRCFile(filename), O_RDONLY)) == -1)
    return ERROR_OPEN_FILE;

  read(file_handle, &crc64, sizeof (t_crc64));
  close(file_handle);
  if ((setxattr(filename, attributeName, (const char *)&crc64, sizeof(crc64), ATTRFLAGS)) == -1)
    return ERROR_SET_CRC;

  unlink(hiddenCRCFile(filename));

  return SUCCESS;
}

fileCRC FileCRC64(const char *filename)
{ /* Open file and calcuate CRC.  Returns 0 on failure, otherwise returns the CRC. */
  unsigned char buf[MAX_BUF_LEN];
  size_t bufread = MAX_BUF_LEN;
  int cont = 1;
  int fd;
  uint64_t tot = 0;
  uint64_t temp = 0;
  fileCRC crcResult;

  if ((fd = open(filename,O_RDONLY)) == -1)
  {
    crcResult.status = ERROR_CRC_CALC;
    return crcResult;
  }

  while (cont)
  {
    bufread = read(fd, buf, bufread);
      if (bufread == -1)
      {
	close(fd);
        crcResult.status = ERROR_CRC_CALC;
        return crcResult;
      }
    temp =  (t_crc64) crc64(temp, buf, (unsigned int)bufread);
    tot = tot + bufread;
    if (bufread < MAX_BUF_LEN)
      cont = 0;
  }

  close(fd);
  crcResult.status = SUCCESS;
  crcResult.crc64 = temp;

  return crcResult;
}

int putCRC(const char *file, int flags)
{
  fileCRC checksum_file;
  fileCRC oldCRC;

  int file_handle;
  int ATTRFLAGS;
  int fstype;
  fstype = getfsType(file);

  ATTRFLAGS = (flags & OVERWRITE) ? 0 : XATTR_CREATE;

  oldCRC = getCRC(file);

  /* Lets see if there is an existing CRC, if so get it. */
  if ((oldCRC.status != SUCCESS) && (oldCRC.status != ERROR_NO_XATTR))
  {
    return oldCRC.status;
  }
  /* If there is, and we aren't overwriting, bail out. */
  if ((oldCRC.status == SUCCESS) && !(flags & OVERWRITE))
    {
      return ERROR_NO_OVERWRITE;
    }

  checksum_file = FileCRC64(file);

  if (checksum_file.status != SUCCESS)
  {
    return checksum_file.status;
  }

  if ((checksum_file.crc64 != oldCRC.crc64) && (oldCRC.status == SUCCESS))
  {
    /* If we have a valid checksum for the file already, notify if the new checksum is different. */
    printf("File %s has been changed since checksum last computed!\n", file);
  }

  if(fstype != VFAT && fstype != UDF && fstype != NFS)
  { /* If not VFAT or UDF or NFS, attempt to store CRC in extended attribute */
    if ((setxattr(file, attributeName, (const char *)&checksum_file.crc64, sizeof(checksum_file.crc64), ATTRFLAGS)) == -1)
    {
      return ERROR_SET_CRC;
    }
    else
    {
      return SUCCESS; /* And we're done here, return to process next file */
    }
  }

  if ((file_handle = open(hiddenCRCFile(file), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1)
    return ERROR_OPEN_FILE;
  if (write(file_handle, &checksum_file.crc64, sizeof (t_crc64)) == -1)
    return ERROR_WRITE_FILE;

  close(file_handle);
  if(fstype == VFAT) /* Set hidden flag for VFAT */
    vfat_attr(hiddenCRCFile(file));
  else if (fstype == NTFS) /* or NTFS */
    ntfs_attr(hiddenCRCFile(file));

  return SUCCESS;
}

fileCRC getCRC(const char *file)
{ /* This retreives the CRC, first by checking for an extended attribute
    then by looking for a hidden file.  Returns 0 if unsuccessful, otherwise
    return the checksum.*/
  int attribute_format;
  t_crc64 checksum_attr;
  int file_handle;
  fileCRC crcResult;

  attribute_format = presentCRC64(file);

  if (attribute_format == 0)
  {
    crcResult.status = ERROR_NO_XATTR;
    return crcResult;
  }

  if (attribute_format == XATTR)
  {
    if (getxattr(file, attributeName, (char *)&checksum_attr, sizeof(t_crc64)) == -1)
    {
      crcResult.status = ERROR_CRC_CALC;
      return crcResult;
    }
    else
    {
      crcResult.status = SUCCESS;
      crcResult.crc64 = checksum_attr;
      return crcResult;
    }
  }
  if (attribute_format == HIDDEN_ATTR)
  {
    if ((file_handle = open(hiddenCRCFile(file), O_RDONLY)) == -1)
    {
      crcResult.status = ERROR_CRC_CALC;
      return crcResult;
    }
    if (read(file_handle, &checksum_attr, sizeof(t_crc64)) == -1)
    {
      perror("Failure reading hidden checksum file.");
      crcResult.status = ERROR_READ_FILE;
      crcResult.crc64 = 0;
      return crcResult;
    }
    crcResult.status = SUCCESS;
    crcResult.crc64 = checksum_attr;
    return crcResult;
  }
  crcResult.status = ERROR_CRC_CALC;
  return crcResult;
}

int getfsType(const char *file)
{
  int fstype;
  struct statfs sstat;

  statfs(file, &sstat);
  switch (sstat.f_type)
    {
    case MSDOS_SUPER_MAGIC:
      fstype = VFAT;
      break;
    case NTFS_SUPER_MAGIC:
      fstype = NTFS;
      break;
    case UDF_SUPER_MAGIC:
      fstype = UDF;
      break;
    case XFS_SUPER_MAGIC:
      fstype = XFS;
      break;
    case JFS_SUPER_MAGIC:
      fstype = JFS;
      break;
    case NFS_SUPER_MAGIC:
      fstype = NFS;
      break;
    case SMB_SUPER_MAGIC:
      fstype = SMB;
      break;
    case BTRFS_TEST_MAGIC:
      fstype = BTRFS;
      break;
    case BTRFS_SUPER_MAGIC:
      fstype = BTRFS;
      break;
    default:
      fstype = 0;
      break;
    }
  return fstype;
}


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>
#include "config.h"
#include "crc64.h"

#define RESET_TEXT()	printf("\033[0;0m")
#define Version VERSION

typedef unsigned long long t_crc64;

enum validities
{
  VALID = 0,
  INVALID = 1
};

enum errorTypes
{
    SUCCESS,
    ERROR_CRC_CALC,
    ERROR_REMOVE_XATTR,
    ERROR_STORE_CRC,
    ERROR_OPEN_DIR,
    ERROR_OPEN_FILE,
    ERROR_READ_FILE,
    ERROR_SET_CRC,
    ERROR_REMOVE_HIDDEN,
    ERROR_NO_XATTR,
    ERROR_NO_OVERWRITE,
    ERROR_WRITE_FILE,
    ERROR_FILENAME_OVERFLOW,
    ERROR_NO_MEM
};

enum characterAttributes
{
  RESET		= 0,
  BRIGHT	= 1,
  DIM		= 2,
  UNDERLINE	= 3,
  BLINK		= 4,
  REVERSE	= 7,
  HIDDEN	= 8,
  MONO		= 9
};

enum characterColours
{
  BLACK		= 0,
  RED		= 1,
  GREEN		= 2,
  YELLOW	= 3,
  BLUE		= 4,
  MAGENTA	= 5,
  CYAN		= 6

};

enum flags
{
  VERBOSE		= 0x01,
  STORE			= 0x02,
  CHECK			= 0x04,
  DISPLAY		= 0x08,
  REMOVE		= 0x10,
  RECURSE		= 0x20,
  OVERWRITE		= 0x40,
  PRINT			= 0x80,
  EXPORT		= 0x100,
  IMPORT		= 0x200,
  PIPEDFILES	= 0x400,
  SETCRCRO		= 0x800, /* Set CRC to be read only */
  SETCRCRW		= 0x1000, /* set CRC to be read write */
  MONOCHROME	= 0x2000
};

enum extendedAttributeTypes
{
  NO_ATTR = 0,
  XATTR = 1,
  HIDDEN_ATTR = 2
};

enum checkitOptionsEnum
{
  UPDATEABLE	= 0x01,
  STATIC	= 0x02,
  OPT_ERROR	= 0x04,
  NO_XATTR_SUPPORT = 0x08
};

typedef struct {
  int status;
  t_crc64 crc64;
} fileCRC;

enum fsTypes {
VFAT = 1,
NTFS = 2,
UDF = 3,
XFS = 4,
JFS = 5,
NFS = 6,
SMB = 7,
CIFS = 8,
BTRFS = 9
};

static const int LIST_XATTR_BUFFER_SIZE =  2048; /* Statically allocated buffer. */

char* hiddenCRCFile(const char *file);
fileCRC FileCRC64(const char *filename);
uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l);
void textcolor(int attr, int fg, int bg);
fileCRC getCRC(const char *filename);
int presentCRC64(const char *file);
int exportCRC(const char *filename, int flags);
int removeCRC(const char *filename);
int importCRC(const char *filename, int flags);
int putCRC(const char *file, int flags);

int vfat_attr(char *file);
int ntfs_attr(char *file);
const char* errorMessage(int error);
int getfsType(const char *file);


code:
/*  CHECKIT
 *    A file checksummer and integrity tester
 *    Copyright (C) 2014 Dennis Katsonis
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/* Set user customized option for files */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <attr/xattr.h>
#include <stdint.h>

#include "checkit.h"
#include "fsmagic.h"
#include "checkit_attr.h"

extern int failed;
extern int processed;
const char* checkitOptionsName = "user.checkit";

int setCheckitOptions(const char *file, char checkitOptions)
{
  int fstype;
  fstype = getfsType(file);

  if(fstype != VFAT && fstype != UDF && fstype != NFS)
  { /* If not VFAT or UDF, attempt to store attribute/option in extended attribute */
    if ((setxattr(file, checkitOptionsName, (const char *)&checkitOptions, sizeof(checkitOptions), 0)) == -1)
      return ERROR_SET_CRC;
    else
      return 0; /* And we're done here, return to process next file */
  }
  else
  {
    return ERROR_SET_CRC;
  }
  return SUCCESS;
}

char getCheckitOptions(const char *file)
{
  char buf[LIST_XATTR_BUFFER_SIZE];
  char *current_attr;
  int x;
  char checkitOptions;
  int fstype;
  fstype = getfsType(file);

  if(fstype != VFAT && fstype != UDF && fstype != NFS)
  { /* If not VFAT or UDF, attempt to read attribute/option in extended attribute */

    x = listxattr(file,buf,LIST_XATTR_BUFFER_SIZE);

    current_attr = buf;
    if (x != -1)
    {
      do
      {
	if (strcmp(current_attr, checkitOptionsName) == 0)
	{
	  if ((getxattr(file, checkitOptionsName, (char *)&checkitOptions, sizeof(checkitOptions)) == -1))
	  {
	    checkitOptions = OPT_ERROR;
	  }
	  break;
	}
	else
	  current_attr += (strlen(current_attr) + 1);
      } while ((current_attr - buf) < x);
    }
  }
  else
  {
    checkitOptions = NO_XATTR_SUPPORT; /* If its VFAT/UDF, don't update.  We don't support the option for these filesystems, yet...*/
  }
  return checkitOptions;
}

int removeCheckitOptions(const char *file)
{
  char buf[LIST_XATTR_BUFFER_SIZE];
  int x;
  int fstype;
  char *current_attr;
  fstype = getfsType(file);

  if(fstype != VFAT && fstype != UDF && fstype != NFS && fstype != SMB && fstype != CIFS)
  { /* If not VFAT or UDF or SMB or CIFS, attempt to read attribute/option in extended attribute */

    x = listxattr(file,buf,LIST_XATTR_BUFFER_SIZE);
    current_attr = buf;

    if (x == -1)
    {
      return ERROR_REMOVE_XATTR;
    }

    do
    {
      if (strcmp(current_attr, checkitOptionsName) == 0)
      {
	if ((removexattr(file, checkitOptionsName)) == -1)
	{
	  return ERROR_REMOVE_XATTR;
	}
	break;
      }
      else
	current_attr += (strlen(current_attr) + 1);
    } while ((current_attr - buf) < x);

  }
  return SUCCESS;
}


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

char getCheckitOptions(const char *file);
int setCheckitOptions(const char *file, char checkitOptions);
int removeCheckitOptions(const char *file);


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <linux/limits.h>
#include <errno.h>
#include <dirent.h>
#include <libgen.h>

#include "checkit.h"
#include "checkit_attr.h"
#include "strarray.h"

extern int failed;
extern int processed;
extern int nocrc;

static int processFile(char *filename, int flags);
static int processDir(char *path, char *dir, int flags);
static void printErrorMessage(int result, const char *filename);

fileList noCRCFiles;
fileList badCRCFiles;

const char *help =
  "Checkit stores a checksum (CRC64) as an extended attribute.  Using\n" \
  "this program you can easily calculate and store a checksum as\n" \
  "a file attribute, and check the file data against the checksum\n" \
  "at any time, to determine if there have been any changes to\n" \
  "the file.\n\n" \
  "Options :\n" \
  " -s  Calculate and store checksum\t-c   Check file against stored checksum\n" \
  " -v  Verbose.  Print more information\t-p   Display CRC64 checksum and status\n" \
  " -x  Remove stored CRC64 checksum\t-o   Overwrite existing checksum\n" \
  " -r  Recurse through directories\t-i   Import CRC from hidden file\n" \
  " -e  Export CRC to hidden file  \t-f   Read list of files from stdin\n" \
  " -u  Allow CRC on this file to be updated (for files you intend to change)\n" \
  " -d  Disallow updating of CRC on this file (for files you do not intend to change)\n" \
  " -V  Print license\t\t\t-m  No colours.";

const char *license =
  "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\n" \
  "This program is free software: you can redistribute it and/or modify\n" \
  "it under the terms of the GNU General Public License as published by\n" \
  "the Free Software Foundation, either version 3 of the License, or\n" \
  "(at your option) any later version.\n\n" \
  "This program is distributed in the hope that it will be useful,\n" \
  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" \
  "GNU General Public License for more details.\n" \
  "You should have received a copy of the GNU General Public License\n" \
	"along with this program.  If not, see <http://www.gnu.org/licenses/>.\n";

void cprintf(char *msg, char *directory, char *base_filename, int mono, int colour)
{
  printf("%s%-20s\t", directory, base_filename);
   if (!mono)
    {
      printf("[");
      textcolor(BRIGHT,colour,BLACK);
    }
    printf("%s",msg);
    if (!mono)
    {
      RESET_TEXT();
    }
}

void printErrorMessage(int result, const char *filename)
{
  fprintf(stderr, "For file %s: %s\n", filename, errorMessage(result));
}

void printHeader(void)
{
  printf("CHECKIT: A file checksum utility.\tVersion : %s\n",Version);
  puts("(C) Dennis Katsonis (2014)");
  puts("");
  puts("CRC64 Copyright (c) 2012, Salvatore Sanfilippo <antirez at gmail dot com>");
  puts("All rights reserved.");
  puts("");
}

int processFile(char *filename, int flags)
{
  struct stat statbuf;
  int file;
  fileCRC result;
  fileCRC resultCRC;
  int dirResult;
  static char directory[PATH_MAX - 1];

  char *base_filename;
  char *dir_filename;
  char *_filename;
  char checkitAttributes;

  /* Seperate filename into directory and filename parts. */
  _filename = strdup(filename);
  if (_filename == NULL)
  {
    perror("Could not allocate memory :");
    exit(1);
  }
  base_filename = basename(_filename);
  dir_filename = dirname(_filename);

  if ((file = stat (filename, &statbuf)) != 0 )
  {
    printErrorMessage(ERROR_OPEN_FILE, filename);
    free(_filename);
    return ERROR_OPEN_FILE;
  }

  if (S_ISDIR(statbuf.st_mode) && (flags & RECURSE))
  {
    dirResult = processDir(directory, filename, flags);
    if (dirResult)
    {
      printErrorMessage(dirResult, filename);
      free(_filename);
      return dirResult;
    }
    else
    {
      free(_filename);
      return 0;
    }
  }

  if (base_filename[0] == '.')
    return 0; /* Don't process hidden files */

  if (strcmp(dir_filename, ".") != 0)
    sprintf(directory, "%s/", dir_filename);

  checkitAttributes = getCheckitOptions(filename);

  if (S_ISREG (statbuf.st_mode))
  {

    if (flags & DISPLAY) /* Display CRC64 */
      {
	result = getCRC(filename);
	if(result.status != SUCCESS)
	{ /* getCRC returns 0 on error, so if 0, print error messsage and exit. */
	  printErrorMessage(result.status, filename);
	  return -1;
	}
	printf("Checksum for %s: %llx\n", filename, result.crc64);
	checkitAttributes = getCheckitOptions(filename);
	if (checkitAttributes == UPDATEABLE)
	  fprintf(stderr, "R/W Checksum: Checkit can update this checksum.\n");
	if (checkitAttributes == STATIC)
	  fprintf(stderr, "R/O Checksum: Checkit will not update this checksum.\n");
      }

    if (flags & SETCRCRO)
    {
      if(flags & VERBOSE)
	    fprintf(stderr, "Setting CRC for %s to remain static/read only.\n", filename);
      if (setCheckitOptions(filename, STATIC))
      {
	printErrorMessage(dirResult,filename);
        free(_filename);
	return -1;
      }
    } /* End of set CRC option routine */

    if (flags & SETCRCRW)
    {
      if(flags & VERBOSE)
		fprintf(stderr, "Setting CRC for %s to allow updates/read-write.\n", filename);

      if (setCheckitOptions(filename, UPDATEABLE))
      {
		  printErrorMessage(dirResult,filename);
		  free(_filename);
	return -1;
      }
    } /* End of set CRC option routine */

    if (flags & EXPORT) /* Export CRC to file */
    {
      if (flags & VERBOSE)
		  printf("Exporting attribute for %s to %s\n", filename, hiddenCRCFile(basename(filename)));
      dirResult = exportCRC(filename, flags);
      if (dirResult)
      {
	printErrorMessage(dirResult, filename);
        free(_filename);
	return dirResult;
      }
    } /* End of export routine. */

    if (flags & IMPORT) /* Export CRC to file */
    {
      dirResult = importCRC(filename, flags);
      if (dirResult)
      {
	printErrorMessage(dirResult, filename);
        free(_filename);
	return dirResult;
      }

    } /* End of export routine. */

    if (flags & STORE) /* Calculate and store CRC64 */
    {
	  fprintf(stderr, "Storing checksum for file %s\n", filename);

      if (checkitAttributes == STATIC)
      {
        /* If checkit attributes say its not updateable
         * bail out...  Even if there is no CRC64 stored.*/
          printErrorMessage(ERROR_NO_OVERWRITE, filename);
          return ERROR_NO_OVERWRITE;
      }
      else if (checkitAttributes == UPDATEABLE)
      { /* Always overwrite, if explicitely indicated as R/W in the attributes.*/
        flags |= OVERWRITE;
      }

      dirResult = putCRC(filename, flags);

      if (dirResult != SUCCESS)
      {
	printErrorMessage(dirResult, filename);
        free(_filename);
	return dirResult;
      }
    } /* End of store routine. */

    if (flags & CHECK) /* Check CRC */
    {
      resultCRC = getCRC(filename);

      if (resultCRC.status != ERROR_NO_XATTR)
      { /* An error reading the CRC, if there was one */
        if(resultCRC.status != SUCCESS)
        { /* getCRC returns 0 on error, so if 0, print error messsage (couldn't read file) and exit. */
          printErrorMessage(ERROR_READ_FILE, filename);
          free(_filename);
          return -1;
        }
        result = FileCRC64(filename);
        if(result.status != SUCCESS)
        { /* FileCRC64 returns 0 on error, so if 0, print error message (couldn't calculate CRC) and exit. */
          printErrorMessage(ERROR_CRC_CALC, filename);
          free(_filename);
          return -1;
        }
      }
      /* If no CRC, that is OK, We will just skip the check against the file.*/

      if ((result.crc64 == resultCRC.crc64) && (resultCRC.status != ERROR_NO_XATTR))
      {
	  cprintf("  OK  ", directory, base_filename, (flags & MONOCHROME), GREEN);
      }
      else if (resultCRC.status == ERROR_NO_XATTR)
      {
	    cprintf("NO CRC", directory, base_filename, (flags & MONOCHROME), YELLOW);
        ++nocrc;
        if (flags & VERBOSE)
        {
          if (appendFileList(&noCRCFiles, directory, base_filename) == ERROR_NO_MEM)
          {
			fprintf(stderr, "Out of memory.\n");
            exit(ERROR_NO_MEM);
          }
        }
      }
      else
      {
		cprintf("FAILED", directory, base_filename, (flags & MONOCHROME), RED);
		++failed;
        if (flags & VERBOSE)
        {
          if (appendFileList(&badCRCFiles, directory, base_filename) == ERROR_NO_MEM)
          {
			fprintf(stderr, "Out of memory.\n");
            exit(ERROR_NO_MEM);
          }
        }
      }
	  if (!(flags & MONOCHROME))
		  {
			  printf("]\n");
		  }
	  else
		  printf("\n");
    } /* End of Check CRC routine */

    if (flags & REMOVE)
    {
      if (flags & VERBOSE)
		  fprintf(stderr, "Removing checksum.\n");

      dirResult = removeCRC(filename);
      dirResult |= removeCheckitOptions(filename);

      if (dirResult)
		  {
			  printErrorMessage(dirResult, filename);
			  free(_filename);
			  return dirResult;
		  }
    } /* End of Remove CRC routine */

  } /* End of file processing regime */
  free(_filename);
  ++processed;
  return SUCCESS;
}

int processDir(char *path, char *dir, int flags)
{ /* Process directory and files within it */
  DIR *dp;
  char *dirend;
  struct dirent *entry;
  struct stat statbuf;
  struct statfs sstat;

  if((dp = opendir(dir)) == NULL)
    return ERROR_OPEN_DIR;

  chdir(dir);
  strcat(path, dir);
  strcat(path, "/"); /* Assemble directory name. */

  while((entry = readdir(dp)) != NULL)
  {
    stat(entry->d_name, &statbuf);
    statfs(entry->d_name, &sstat);

    if (S_ISDIR(statbuf.st_mode))
    {
    if(strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0)
      continue;
      processDir(path, entry->d_name, flags);
    }
    else
    {
      processFile(entry->d_name, flags);
      if (flags & VERBOSE)
      {
	    printf("Processing file %s.\n",entry->d_name);
      }
    }
  } /* End while */
  chdir("..");
  /* As we go up a directory, we remove the directory name from
   * the path by setting the '/' character prior to the directory name
   * to NULL, to truncate the string. */
  dirend = strrchr(path,'/'); /* The '/' at the end of the path. */
  if (dirend != NULL)
    *dirend = 0;
  dirend = strrchr(path,'/'); /* The '/' at the start of the path. */
  if (dirend != NULL) /* Make it null, to terminate the string here. */
  {
    *++dirend = 0;
  } else {
    path[0] = 0; /* Wasn't found, truncate string to zero.
                        It may not be found if the original path did not begin with
                        a / */
  }
  closedir(dp);
  /* We remove the '/' twice because there is one at the end of the path, but we want to delete
   * the one prior to the last directory entry in the string.*/
  return 0;
}

void textcolor(int attr, int fg, int bg)
{ /*Change textcolour */
  char command[13];

  /* Command is the control command to the terminal */
  sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
  printf("%s", command);
} /* end of textcolor() */

int main(int argc, char *argv[])
{
  int optch;
  char *line = NULL;
  size_t size;
  ssize_t read;
  char *ptr;
  int flags = 0;

  while ((optch = getopt(argc, argv,"mhscvVudexirfop")) != -1)
    switch (optch)
    {
      case 'h' :
    puts(help);
	return 0;
	break;
      case 'V' :
 	  printHeader();
      puts(license);
	return 0;
	break;
      case 's' :
	flags |= STORE;
	break;
      case 'c' :
	flags |= CHECK;
	if ((flags & CHECK) && (flags & STORE))
	{
	  fprintf(stderr, "Cannot store and check CRC at same time.\n");
	  return 1;
	}
	break;

      case 'v' :
	flags |= VERBOSE;
	break;
      case 'x' :
	flags |= REMOVE;
	if (flags & CHECK)
	{
	  fprintf(stderr, "Cannot remove and check CRC at same time.\n");
	  return 1;
	}
	if (flags & STORE)
	{
	  fprintf(stderr, "Cannot remove and store CRC at same time.\n");
	  return 1;
	}
	break;
      case 'o' :
	flags |= OVERWRITE;
	break;
      case 'm' :
	flags |= MONOCHROME;
	break;
      case 'r' :
	flags |= RECURSE;
	break;
      case 'i' :
        flags |= IMPORT;
	break;
      case 'u' :
	flags |= SETCRCRW;
	if (flags & SETCRCRO)
	{
	  fprintf(stderr, "Cannot disallow and allow changes to CRC at the same time!\n");
	  return 1;
	}
	break;
      case 'd' :
	flags |= SETCRCRO;
	if (flags & SETCRCRW)
	{
      fprintf(stderr, "Cannot disallow and allow changes to CRC at the same time!\n");
	  return 1;
	}
	break;
      case 'e' :
	flags |= EXPORT;
	if (flags & IMPORT)
	{
	  fprintf(stderr, "Cannot import and export at the same time.\n");
	  return 1;
	}
	break;
      case 'f' :
	flags |= PIPEDFILES;
	break;
      case 'p' :
	flags |= DISPLAY;
	break;
      case '?' :
	printHeader();
    puts(help);

	break;
  }

  char *no_color = getenv("NO_COLOR");
  // Check if we are a not a tty, or if NO_COLOR environmental variable set, default to monochrome.
  if (!isatty(fileno(stdout)) || (no_color != NULL && no_color[0] != '\0'))
  {
	  flags |= MONOCHROME;
  }

  if (argc <=1)
  {
	printHeader();
    puts(help);
    return(0);
  }

  if (flags & VERBOSE) /* If verbose, we will print faulty files at the end
                          Otherwise, don't bother.*/
  {
    if (initFileList(&noCRCFiles))
    {
	  fprintf(stderr, "Failed to allocate memory to start the program.\n");
      exit(ERROR_NO_MEM);
    }

      if (initFileList(&badCRCFiles))
    {
	  fprintf(stderr, "Failed to allocate memory to start the program.\n");
      exit(ERROR_NO_MEM);
    }
  }

  if (flags & PIPEDFILES)  {
    while ((read = getline(&line, &size, stdin) != -1))
    {
    ptr = strrchr(line, '\n');
    if (ptr != NULL)
      *ptr = 0;
    processFile(line, flags);
    }
  free(line);
  }

  optch = optind;

  if (optch < argc)
  {
    do
    {
      processFile(argv[optch], flags);
    }
    while ( ++optch < argc);
  }
  else if (!(flags & PIPEDFILES))
  {
	fprintf(stderr, "No files specified.\n");
    return 0;
  }
  fprintf(stderr, "Total of %d file(s) processed.\n", processed);
  if (nocrc && processed)
  {
	fprintf(stderr, "\nWARNING: **** %d file(s) without a checksum ****\n", nocrc);
    if (flags & VERBOSE)
    {
	  fprintf(stderr, "%s\n", getFileList(&noCRCFiles));
      freeFileList(&noCRCFiles);
    }
  }
  if (failed && processed)
    {
   	fprintf(stderr, "\nERROR: **** %d file(s) failed ****\n", failed);
    if (flags & VERBOSE)
    {
		fprintf(stderr, "%s\n", getFileList(&badCRCFiles));
      freeFileList(&noCRCFiles);
    }
    return(failed);
    } /* Return the number of failed checks if any errors. */
  else if (processed && (flags & CHECK) && (!nocrc))
  return 0;
}


code:
/* Redis uses the CRC64 variant with "Jones" coefficients and init value of 0.
 *
 * Specification of this CRC64 variant follows:
 * Name: crc-64-jones
 * Width: 64 bites
 * Poly: 0xad93d23594c935a9
 * Reflected In: True
 * Xor_In: 0xffffffffffffffff
 * Reflected_Out: True
 * Xor_Out: 0x0
 * Check("123456789"): 0xe9c6d914c4b8d9ca
 *
 * Copyright (c) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE. */

#include <stdint.h>

static const uint64_t crc64_tab[256] = {
    UINT64_C(0x0000000000000000), UINT64_C(0x7ad870c830358979),
    UINT64_C(0xf5b0e190606b12f2), UINT64_C(0x8f689158505e9b8b),
    UINT64_C(0xc038e5739841b68f), UINT64_C(0xbae095bba8743ff6),
    UINT64_C(0x358804e3f82aa47d), UINT64_C(0x4f50742bc81f2d04),
    UINT64_C(0xab28ecb46814fe75), UINT64_C(0xd1f09c7c5821770c),
    UINT64_C(0x5e980d24087fec87), UINT64_C(0x24407dec384a65fe),
    UINT64_C(0x6b1009c7f05548fa), UINT64_C(0x11c8790fc060c183),
    UINT64_C(0x9ea0e857903e5a08), UINT64_C(0xe478989fa00bd371),
    UINT64_C(0x7d08ff3b88be6f81), UINT64_C(0x07d08ff3b88be6f8),
    UINT64_C(0x88b81eabe8d57d73), UINT64_C(0xf2606e63d8e0f40a),
    UINT64_C(0xbd301a4810ffd90e), UINT64_C(0xc7e86a8020ca5077),
    UINT64_C(0x4880fbd87094cbfc), UINT64_C(0x32588b1040a14285),
    UINT64_C(0xd620138fe0aa91f4), UINT64_C(0xacf86347d09f188d),
    UINT64_C(0x2390f21f80c18306), UINT64_C(0x594882d7b0f40a7f),
    UINT64_C(0x1618f6fc78eb277b), UINT64_C(0x6cc0863448deae02),
    UINT64_C(0xe3a8176c18803589), UINT64_C(0x997067a428b5bcf0),
    UINT64_C(0xfa11fe77117cdf02), UINT64_C(0x80c98ebf2149567b),
    UINT64_C(0x0fa11fe77117cdf0), UINT64_C(0x75796f2f41224489),
    UINT64_C(0x3a291b04893d698d), UINT64_C(0x40f16bccb908e0f4),
    UINT64_C(0xcf99fa94e9567b7f), UINT64_C(0xb5418a5cd963f206),
    UINT64_C(0x513912c379682177), UINT64_C(0x2be1620b495da80e),
    UINT64_C(0xa489f35319033385), UINT64_C(0xde51839b2936bafc),
    UINT64_C(0x9101f7b0e12997f8), UINT64_C(0xebd98778d11c1e81),
    UINT64_C(0x64b116208142850a), UINT64_C(0x1e6966e8b1770c73),
    UINT64_C(0x8719014c99c2b083), UINT64_C(0xfdc17184a9f739fa),
    UINT64_C(0x72a9e0dcf9a9a271), UINT64_C(0x08719014c99c2b08),
    UINT64_C(0x4721e43f0183060c), UINT64_C(0x3df994f731b68f75),
    UINT64_C(0xb29105af61e814fe), UINT64_C(0xc849756751dd9d87),
    UINT64_C(0x2c31edf8f1d64ef6), UINT64_C(0x56e99d30c1e3c78f),
    UINT64_C(0xd9810c6891bd5c04), UINT64_C(0xa3597ca0a188d57d),
    UINT64_C(0xec09088b6997f879), UINT64_C(0x96d1784359a27100),
    UINT64_C(0x19b9e91b09fcea8b), UINT64_C(0x636199d339c963f2),
    UINT64_C(0xdf7adabd7a6e2d6f), UINT64_C(0xa5a2aa754a5ba416),
    UINT64_C(0x2aca3b2d1a053f9d), UINT64_C(0x50124be52a30b6e4),
    UINT64_C(0x1f423fcee22f9be0), UINT64_C(0x659a4f06d21a1299),
    UINT64_C(0xeaf2de5e82448912), UINT64_C(0x902aae96b271006b),
    UINT64_C(0x74523609127ad31a), UINT64_C(0x0e8a46c1224f5a63),
    UINT64_C(0x81e2d7997211c1e8), UINT64_C(0xfb3aa75142244891),
    UINT64_C(0xb46ad37a8a3b6595), UINT64_C(0xceb2a3b2ba0eecec),
    UINT64_C(0x41da32eaea507767), UINT64_C(0x3b024222da65fe1e),
    UINT64_C(0xa2722586f2d042ee), UINT64_C(0xd8aa554ec2e5cb97),
    UINT64_C(0x57c2c41692bb501c), UINT64_C(0x2d1ab4dea28ed965),
    UINT64_C(0x624ac0f56a91f461), UINT64_C(0x1892b03d5aa47d18),
    UINT64_C(0x97fa21650afae693), UINT64_C(0xed2251ad3acf6fea),
    UINT64_C(0x095ac9329ac4bc9b), UINT64_C(0x7382b9faaaf135e2),
    UINT64_C(0xfcea28a2faafae69), UINT64_C(0x8632586aca9a2710),
    UINT64_C(0xc9622c4102850a14), UINT64_C(0xb3ba5c8932b0836d),
    UINT64_C(0x3cd2cdd162ee18e6), UINT64_C(0x460abd1952db919f),
    UINT64_C(0x256b24ca6b12f26d), UINT64_C(0x5fb354025b277b14),
    UINT64_C(0xd0dbc55a0b79e09f), UINT64_C(0xaa03b5923b4c69e6),
    UINT64_C(0xe553c1b9f35344e2), UINT64_C(0x9f8bb171c366cd9b),
    UINT64_C(0x10e3202993385610), UINT64_C(0x6a3b50e1a30ddf69),
    UINT64_C(0x8e43c87e03060c18), UINT64_C(0xf49bb8b633338561),
    UINT64_C(0x7bf329ee636d1eea), UINT64_C(0x012b592653589793),
    UINT64_C(0x4e7b2d0d9b47ba97), UINT64_C(0x34a35dc5ab7233ee),
    UINT64_C(0xbbcbcc9dfb2ca865), UINT64_C(0xc113bc55cb19211c),
    UINT64_C(0x5863dbf1e3ac9dec), UINT64_C(0x22bbab39d3991495),
    UINT64_C(0xadd33a6183c78f1e), UINT64_C(0xd70b4aa9b3f20667),
    UINT64_C(0x985b3e827bed2b63), UINT64_C(0xe2834e4a4bd8a21a),
    UINT64_C(0x6debdf121b863991), UINT64_C(0x1733afda2bb3b0e8),
    UINT64_C(0xf34b37458bb86399), UINT64_C(0x8993478dbb8deae0),
    UINT64_C(0x06fbd6d5ebd3716b), UINT64_C(0x7c23a61ddbe6f812),
    UINT64_C(0x3373d23613f9d516), UINT64_C(0x49aba2fe23cc5c6f),
    UINT64_C(0xc6c333a67392c7e4), UINT64_C(0xbc1b436e43a74e9d),
    UINT64_C(0x95ac9329ac4bc9b5), UINT64_C(0xef74e3e19c7e40cc),
    UINT64_C(0x601c72b9cc20db47), UINT64_C(0x1ac40271fc15523e),
    UINT64_C(0x5594765a340a7f3a), UINT64_C(0x2f4c0692043ff643),
    UINT64_C(0xa02497ca54616dc8), UINT64_C(0xdafce7026454e4b1),
    UINT64_C(0x3e847f9dc45f37c0), UINT64_C(0x445c0f55f46abeb9),
    UINT64_C(0xcb349e0da4342532), UINT64_C(0xb1eceec59401ac4b),
    UINT64_C(0xfebc9aee5c1e814f), UINT64_C(0x8464ea266c2b0836),
    UINT64_C(0x0b0c7b7e3c7593bd), UINT64_C(0x71d40bb60c401ac4),
    UINT64_C(0xe8a46c1224f5a634), UINT64_C(0x927c1cda14c02f4d),
    UINT64_C(0x1d148d82449eb4c6), UINT64_C(0x67ccfd4a74ab3dbf),
    UINT64_C(0x289c8961bcb410bb), UINT64_C(0x5244f9a98c8199c2),
    UINT64_C(0xdd2c68f1dcdf0249), UINT64_C(0xa7f41839ecea8b30),
    UINT64_C(0x438c80a64ce15841), UINT64_C(0x3954f06e7cd4d138),
    UINT64_C(0xb63c61362c8a4ab3), UINT64_C(0xcce411fe1cbfc3ca),
    UINT64_C(0x83b465d5d4a0eece), UINT64_C(0xf96c151de49567b7),
    UINT64_C(0x76048445b4cbfc3c), UINT64_C(0x0cdcf48d84fe7545),
    UINT64_C(0x6fbd6d5ebd3716b7), UINT64_C(0x15651d968d029fce),
    UINT64_C(0x9a0d8ccedd5c0445), UINT64_C(0xe0d5fc06ed698d3c),
    UINT64_C(0xaf85882d2576a038), UINT64_C(0xd55df8e515432941),
    UINT64_C(0x5a3569bd451db2ca), UINT64_C(0x20ed197575283bb3),
    UINT64_C(0xc49581ead523e8c2), UINT64_C(0xbe4df122e51661bb),
    UINT64_C(0x3125607ab548fa30), UINT64_C(0x4bfd10b2857d7349),
    UINT64_C(0x04ad64994d625e4d), UINT64_C(0x7e7514517d57d734),
    UINT64_C(0xf11d85092d094cbf), UINT64_C(0x8bc5f5c11d3cc5c6),
    UINT64_C(0x12b5926535897936), UINT64_C(0x686de2ad05bcf04f),
    UINT64_C(0xe70573f555e26bc4), UINT64_C(0x9ddd033d65d7e2bd),
    UINT64_C(0xd28d7716adc8cfb9), UINT64_C(0xa85507de9dfd46c0),
    UINT64_C(0x273d9686cda3dd4b), UINT64_C(0x5de5e64efd965432),
    UINT64_C(0xb99d7ed15d9d8743), UINT64_C(0xc3450e196da80e3a),
    UINT64_C(0x4c2d9f413df695b1), UINT64_C(0x36f5ef890dc31cc8),
    UINT64_C(0x79a59ba2c5dc31cc), UINT64_C(0x037deb6af5e9b8b5),
    UINT64_C(0x8c157a32a5b7233e), UINT64_C(0xf6cd0afa9582aa47),
    UINT64_C(0x4ad64994d625e4da), UINT64_C(0x300e395ce6106da3),
    UINT64_C(0xbf66a804b64ef628), UINT64_C(0xc5bed8cc867b7f51),
    UINT64_C(0x8aeeace74e645255), UINT64_C(0xf036dc2f7e51db2c),
    UINT64_C(0x7f5e4d772e0f40a7), UINT64_C(0x05863dbf1e3ac9de),
    UINT64_C(0xe1fea520be311aaf), UINT64_C(0x9b26d5e88e0493d6),
    UINT64_C(0x144e44b0de5a085d), UINT64_C(0x6e963478ee6f8124),
    UINT64_C(0x21c640532670ac20), UINT64_C(0x5b1e309b16452559),
    UINT64_C(0xd476a1c3461bbed2), UINT64_C(0xaeaed10b762e37ab),
    UINT64_C(0x37deb6af5e9b8b5b), UINT64_C(0x4d06c6676eae0222),
    UINT64_C(0xc26e573f3ef099a9), UINT64_C(0xb8b627f70ec510d0),
    UINT64_C(0xf7e653dcc6da3dd4), UINT64_C(0x8d3e2314f6efb4ad),
    UINT64_C(0x0256b24ca6b12f26), UINT64_C(0x788ec2849684a65f),
    UINT64_C(0x9cf65a1b368f752e), UINT64_C(0xe62e2ad306bafc57),
    UINT64_C(0x6946bb8b56e467dc), UINT64_C(0x139ecb4366d1eea5),
    UINT64_C(0x5ccebf68aecec3a1), UINT64_C(0x2616cfa09efb4ad8),
    UINT64_C(0xa97e5ef8cea5d153), UINT64_C(0xd3a62e30fe90582a),
    UINT64_C(0xb0c7b7e3c7593bd8), UINT64_C(0xca1fc72bf76cb2a1),
    UINT64_C(0x45775673a732292a), UINT64_C(0x3faf26bb9707a053),
    UINT64_C(0x70ff52905f188d57), UINT64_C(0x0a2722586f2d042e),
    UINT64_C(0x854fb3003f739fa5), UINT64_C(0xff97c3c80f4616dc),
    UINT64_C(0x1bef5b57af4dc5ad), UINT64_C(0x61372b9f9f784cd4),
    UINT64_C(0xee5fbac7cf26d75f), UINT64_C(0x9487ca0fff135e26),
    UINT64_C(0xdbd7be24370c7322), UINT64_C(0xa10fceec0739fa5b),
    UINT64_C(0x2e675fb4576761d0), UINT64_C(0x54bf2f7c6752e8a9),
    UINT64_C(0xcdcf48d84fe75459), UINT64_C(0xb71738107fd2dd20),
    UINT64_C(0x387fa9482f8c46ab), UINT64_C(0x42a7d9801fb9cfd2),
    UINT64_C(0x0df7adabd7a6e2d6), UINT64_C(0x772fdd63e7936baf),
    UINT64_C(0xf8474c3bb7cdf024), UINT64_C(0x829f3cf387f8795d),
    UINT64_C(0x66e7a46c27f3aa2c), UINT64_C(0x1c3fd4a417c62355),
    UINT64_C(0x935745fc4798b8de), UINT64_C(0xe98f353477ad31a7),
    UINT64_C(0xa6df411fbfb21ca3), UINT64_C(0xdc0731d78f8795da),
    UINT64_C(0x536fa08fdfd90e51), UINT64_C(0x29b7d047efec8728),
};

uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) {
    uint64_t j;

    for (j = 0; j < l; j++) {
        uint8_t byte = s[j];
        crc = crc64_tab[(uint8_t)crc ^ byte] ^ (crc >> 8);
    }
    return crc;
}

#ifdef TEST_MAIN
#include <stdio.h>
int main(void) {
    printf("e9c6d914c4b8d9ca == %016llx\n",
        (unsigned long long) crc64(0,(unsigned char*)"123456789",9));
    return 0;
}
#endif


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

static const uint64_t crc64_tab[256];
uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l);


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* This is a slightly modified version of linux_fsinfo.h from the Linux kernel sources.
 * This is included as a header so that one doesn't need the kernel-headers installed
 * to compile this. */

/* Constants from kernel header for various FSes.
   Copyright (C) 1998-2019 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#ifndef _LINUX_FSINFO_H
#define _LINUX_FSINFO_H        1
/* These definitions come from the kernel headers.  But we cannot
   include the headers here because of type clashes.  If new
   filesystem types will become available we have to add the
   appropriate definitions here.  */
/* Constant that identifies the `adfs' filesystem.  */
#define ADFS_SUPER_MAGIC        0xadf5
/* Constant that identifies the `affs' filesystem.  */
#define AFFS_SUPER_MAGIC        0xadff
/* Constant that identifies the `afs' filesystem.  */
#define AFS_SUPER_MAGIC                0x5346414F
/* Constant that identifies the `anon_inodefs' filesystem.  */
#define ANON_INODE_FS_MAGIC        0x09041934
/* Constant that identifies the `autofs' filesystem.  */
#define AUTOFS_SUPER_MAGIC        0x187
/* Constant that identifies the `bdev' filesystem.  */
#define BDEVFS_MAGIC                0x62646576
/* Constant that identifies the `bfs' filesystem.  */
#define BFS_MAGIC                0x1badface
/* Constant that identifies the `binfmt_misc' filesystem.  */
#define BINFMTFS_MAGIC                0x42494e4d
/* Constant that identifies the `btrfs' filesystem.  */
#define BTRFS_SUPER_MAGIC        0x9123683e
/* Constant that identifies the `btrfs_test_fs' filesystem.  */
#define BTRFS_TEST_MAGIC        0x73727279
/* Constant that identifies the `cgroup' filesystem.  */
#define CGROUP_SUPER_MAGIC        0x27e0eb
/* Constant that identifies the `coda' filesystem.  */
#define CODA_SUPER_MAGIC        0x73757245
/* Constant that identifies the `coherent' filesystem.  */
#define COH_SUPER_MAGIC                0x012ff7b7
/* Constant that identifies the `cramfs' filesystem.  */
#define CRAMFS_MAGIC                0x28cd3d45
/* Constant that identifies the `cramfs' filesystem w/opposite endianness.  */
#define CRAMFS_MAGIC_WEND        0x453dcd28
/* Constant that identifies the `debugfs' filesystem.  */
#define DEBUGFS_MAGIC                0x64626720
/* Constant that identifies the `devfs' filesystem.  */
#define DEVFS_SUPER_MAGIC        0x1373
/* Constant that identifies the `devpts' filesystem.  */
#define DEVPTS_SUPER_MAGIC        0x1cd1
/* Constants that identifies the `ecryptfs' filesystem.  */
#define ECRYPTFS_SUPER_MAGIC        0xf15f
/* Constants that identifies the `efs' filesystem.  */
#define EFS_SUPER_MAGIC                0x414a53
#define EFS_MAGIC                0x072959
/* Constants that identifies the `evivar' filesystem.  */
#define EFIVARFS_MAGIC                0xde5e81e4
/* Constant that identifies the `ext2' filesystem.  */
#define EXT2_SUPER_MAGIC        0xef53
/* Constant that identifies the `ext3' filesystem.  */
#define EXT3_SUPER_MAGIC        0xef53
/* Constant that identifies the `ext3' filesystem.  */
#define EXT4_SUPER_MAGIC        0xef53
/* Constant that identifies the `f2fs' filesystem.  */
#define F2FS_SUPER_MAGIC        0xf2f52010
/* Constant that identifies the `futexfs' filesystem.  */
#define FUTEXFS_SUPER_MAGIC        0xBAD1DEA
/* Constant that identifies the `hostfs' filesystem.  */
#define HOSTFS_SUPER_MAGIC        0x00c0ffee
/* Constant that identifies the `hpfs' filesystem.  */
#define HPFS_SUPER_MAGIC        0xf995e849
/* Constant that identifies the `hugetlbfs' filesystem.  */
#define HUGETLBFS_MAGIC         0x958458f6
/* Constant that identifies the `iso9660' filesystem.  */
#define ISOFS_SUPER_MAGIC        0x9660
/* Constant that identifies the `jffs' filesystem.  */
#define JFFS_SUPER_MAGIC        0x07c0
/* Constant that identifies the `jffs2' filesystem.  */
#define JFFS2_SUPER_MAGIC        0x72b6
/* Constant that identifies the `jfs' filesystem.  */
#define JFS_SUPER_MAGIC                0x3153464a
/* Constant that identifies the `logfs' filesystem.  */
#define LOGFS_MAGIC_U32                0xc97e8168u
/* Constant that identifies the `lustre' filesystem.  */
#define LUSTRE_SUPER_MAGIC        0x0BD00BD0
/* Constants that identify the `minix2' filesystem.  */
#define MINIX2_SUPER_MAGIC        0x2468
#define MINIX2_SUPER_MAGIC2        0x2478
/* Constants that identify the `minix3' filesystem.  */
#define MINIX3_SUPER_MAGIC        0x4d5a
/* Constants that identify the `minix' filesystem.  */
#define MINIX_SUPER_MAGIC        0x137f
#define MINIX_SUPER_MAGIC2        0x138F
/* Constant that identifies the `msdos' filesystem.  */
#define MSDOS_SUPER_MAGIC        0x4d44
/* Constant that identifies the `mtd_inodefs' filesystem.  */
#define MTD_INODE_FS_MAGIC        0x11307854
/* Constant that identifies the `ncp' filesystem.  */
#define NCP_SUPER_MAGIC                0x564c
/* Constant that identifies the `nilfs' filesystem.  */
#define NILFS_SUPER_MAGIC        0x3434
/* Constant that identifies the `nfs' filesystem.  */
#define NFS_SUPER_MAGIC                0x6969
/* Constant that identifies the `ntfs' filesystem.  */
#define NTFS_SUPER_MAGIC        0x5346544e
/* Constant that identifies the `openpromfs' filesystem.  */
#define OPENPROM_SUPER_MAGIC        0x9fa1
/* Constant that identifies the `pipefs' filesystem.  */
#define PIPEFS_MAGIC                0x50495045
/* Constant that identifies the `proc' filesystem.  */
#define PROC_SUPER_MAGIC        0x9fa0
/* Constant that identifies the `pstorefs' filesystem.  */
#define PSTOREFS_MAGIC                0x6165676C
/* Constant that identifies the `qnx4' filesystem.  */
#define QNX4_SUPER_MAGIC        0x002f
/* Constant that identifies the `qnx6' filesystem.  */
#define QNX6_SUPER_MAGIC        0x68191122
/* Constant that identifies the `ramfs' filesystem.  */
#define RAMFS_MAGIC                0x858458f6
/* Constant that identifies the `reiser' filesystem.  */
#define REISERFS_SUPER_MAGIC        0x52654973
#define REISERFS_SUPER_MAGIC_STRING        "ReIsErFs"
#define REISER2FS_SUPER_MAGIC_STRING        "ReIsEr2Fs"
#define REISER2FS_JR_SUPER_MAGIC_STRING        "ReIsEr3Fs"
/* Constant that identifies the `romfs' filesystem.  */
#define ROMFS_SUPER_MAGIC        0x7275
/* Constant that identifies the `securityfs' filesystem.  */
#define SECURITYFS_MAGIC        0x73636673
/* Constant that identifies the `selinuxfs' filesystem.  */
#define SELINUX_MAGIC                0xf97cff8c
/* Constant that identifies the `smackfs' filesystem.  */
#define SMACK_MAGIC                0x43415d53        /* "SMAC" */
/* Constant that identifies the `shm' filesystem.  */
#define SHMFS_SUPER_MAGIC        0x01021994
/* Constant that identifies the `smb' filesystem.  */
#define SMB_SUPER_MAGIC                0x517b
/* Constant that identifies the `sockfs' filesystem.  */
#define SOCKFS_MAGIC                0x534F434B
/* Constant that identifies the `squashfs' filesystem.  */
#define SQUASHFS_MAGIC                0x73717368
/* Constant that identifies the end of stacks allocated by the kernel.  */
#define STACK_END_MAGIC                0x57AC6E9D
/* Constant that identifies the `sysfs' filesystem.  */
#define SYSFS_MAGIC                0x62656572
/* Constants that identify the `sysV' filesystem.  */
#define SYSV2_SUPER_MAGIC        0x012ff7b6
#define SYSV4_SUPER_MAGIC        0x012ff7b5
/* Constant that identifies the `tmpfs' filesystem.  */
#define TMPFS_MAGIC                0x01021994
/* Constant that identifies the `udf' filesystem.  */
#define UDF_SUPER_MAGIC                0x15013346
/* Constant that identify the `ufs' filesystem.  */
#define UFS_MAGIC                0x00011954
#define UFS_CIGAM                0x54190100 /* byteswapped MAGIC */
/* Constant that identifies the `usbdevfs' filesystem.  */
#define USBDEVFS_SUPER_MAGIC        0x9fa2
#define USBDEVICE_SUPER_MAGIC        0x9fa2
/* Constant that identifies the `9p' filesystem.  */
#define V9FS_MAGIC                0x01021997
/* Constant that identifies the `vxfs' filesystem.  */
#define VXFS_SUPER_MAGIC        0xa501fcf5
/* Constant that identifies the `xenfs' filesystem.  */
#define XENFS_SUPER_MAGIC        0xabba1974
/* Constant that identifies the `xenix' filesystem.  */
#define XENIX_SUPER_MAGIC        0x012ff7b4
/* Constant that identifies the `xfs' filesystem.  */
#define XFS_SUPER_MAGIC                0x58465342
/* Maximum link counts.  */
#define COH_LINK_MAX                10000
#define EXT2_LINK_MAX                32000
#define EXT4_LINK_MAX                65000
#define F2FS_LINK_MAX                32000
#define LUSTRE_LINK_MAX                EXT4_LINK_MAX
#define MINIX2_LINK_MAX                65530
#define MINIX_LINK_MAX                250
#define REISERFS_LINK_MAX        64535
#define SYSV_LINK_MAX                126     /* 127? 251? */
#define UFS_LINK_MAX                EXT2_LINK_MAX
#define XENIX_LINK_MAX                126     /* ?? */
#define XFS_LINK_MAX                2147483647
/* The Linux kernel header mentioned this as a kind of generic value.  */
#define LINUX_LINK_MAX        127
#endif        /* linux_fsinfo.h */


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* Sets hidden attribute for NTFS filesystems.
It seems NTFS can support extended attributes with Linux, at
least with NTFS-3G so this probably won't be necessary in most cases.*/

#include <stdlib.h>
#include <stdio.h>
#include <attr/attributes.h>
#include <attr/xattr.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>

#define FILE_ATTRIBUTE_HIDDEN 0x2

int ntfs_attr(const char *file)
{
  int fd;
  int32_t checksum_attr;
  int attr_len = sizeof(int32_t);

  if ((fd = open(file, O_WRONLY)) == -1)
    return 1;

  if ((getxattr(file, "system.ntfs_attrib", (char *)&checksum_attr, sizeof(int32_t))) == -1)
  {
    close(fd);
    return 1;
  }
  checksum_attr |= FILE_ATTRIBUTE_HIDDEN;

  if ((setxattr(file, "system.ntfs_attrib", (const char *)&checksum_attr, sizeof(attr_len), XATTR_REPLACE)) == -1)
  {
    close(fd);
    return 1;
  }
  close(fd);
  return 0;
}


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "strarray.h"
#include "checkit.h"

const int chunkSize = 4096;

int initFileList(fileList *list)
{
  list->files = malloc(chunkSize);
  if (list->files == NULL)
  {
    return ERROR_NO_MEM;
  }
  list->freeSpace = chunkSize;
  list->size = chunkSize;
  list->ptr = list->files;
  return SUCCESS;
}

int appendFileList(fileList *list, const char *basename, const char *filename)
{
  int strlenBasename = strlen(basename);
  int strSize = (strlenBasename + strlen(filename) + 1); /* +1 for the "\n" we add to the end. */

  if (list->files == NULL)
    return ERROR_NO_MEM;

  if (list->freeSpace <= (strSize + 4))
  {

    /* Save ptr offset */
    size_t offset = list->ptr - list->files;

    list->files = realloc(list->files, list->size + chunkSize);
    if (list->files == NULL)
    {
      return ERROR_NO_MEM;
    }

    list->size+=chunkSize;
    list->freeSpace+=chunkSize;
    /* Restore ptr offset
     The ptr offset avoid having to scan the entire string
     for the terminating null on each call of strlen */
    list->ptr = list->files;
    list->ptr += offset;
  }
  if (strlenBasename)
  {
    strcat(list->ptr, basename);
  }
  strcat(list->ptr, filename);
  strcat(list->ptr, "\n");
  list->ptr+=strSize;
  list->freeSpace-= (strSize + strlenBasename - 1);

  return SUCCESS;
}

void freeFileList(fileList *list)
{
  list->ptr = NULL;
  list->freeSpace = 0;
  list->size = 0;
  if (list->files != NULL)
    free(list->files);
  list->files = NULL;
}

const char *getFileList(const fileList *list)
{
  if (list->files != NULL)
    return list->files;
  else
    return NULL;
}


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

typedef struct {
  char *files;
  char *ptr;
  int freeSpace;
  int size;
} fileList;

int initFileList(fileList *list);
int appendFileList(fileList *list, const char *basename, const char *filename);
const char *getFileList(const fileList *list);
void freeFileList(fileList *list);


code:
/*  CHECKIT
    A file checksummer and integrity tester
    Copyright (C) 2014 Dennis Katsonis

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* Sets hidden attribute for FAT filesystems */

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <inttypes.h>
#include <linux/msdos_fs.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int vfat_attr(char *file)
{
  __u32 attrs;
  int fd;

  fd = open(file, O_WRONLY | O_NOATIME);
  if (fd < 0)
  {
    return 1;
  }
  if (ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, &attrs) != 0)
  {
    close(fd);
    return 1;
  }
  attrs |= ATTR_HIDDEN;

  if (ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attrs) != 0)
  {
    close(fd);
    return 1;
  }

  close (fd);
  return 0;

}


code:
# IDE, temp, generated, and other local-only files
.idea/
*.iml
node_modules/
tweego.exe
*.html

*.gif

# Ignoring working folder for Quin2k
mod/

repo_name: ALambert/degrees

path: .gitignore

license: unknown


code:
@set TWEEGO_PATH=%USERPROFILE%\Documents\Twine\StoryFormats
@tweego -o "Degrees of Lewdity VERSION.html" game


code:
function colourContainerClasses() {
	var V = State.variables;
	return 'hair-'  + (V.haircolour||'').replace(/ /g,'-') +
		' ' + 'eye-'   + (V.eyecolour||'').replace(/ /g,'-') +
		' ' + 'upper-' + (V.uppercolour||'').replace(/ /g,'-') +
		' ' + 'lower-' + (V.lowercolour||'').replace(/ /g,'-') +
		' ' + 'under-' + (V.undercolour||'').replace(/ /g,'-')
}
window.colourContainerClasses = colourContainerClasses; // export function