Updating skeinsum with a new scheme for reading large files, simplifying command...
authorJason Self <j@jxself.org>
Tue, 8 Sep 2015 22:29:28 +0000 (15:29 -0700)
committerJason Self <j@jxself.org>
Tue, 8 Sep 2015 22:29:28 +0000 (15:29 -0700)
12 files changed:
.gitignore
compile [new symlink]
config.h.in
configure
configure.ac
makefile.am
makefile.in
missing
skein1024.c
skein256.c
skein512.c
skein_cli.c [new file with mode: 0644]

index 4dc9f31d8903f734b8bdd124f6e06f13427ed149..c3554f80d3d7bd2c07a90a010f6087d6d41bf22f 100644 (file)
@@ -1,7 +1,6 @@
 *.o
 .deps
 autom4te.cache/
-compile
 config.h
 config.h.in~
 config.log
diff --git a/compile b/compile
new file mode 120000 (symlink)
index 0000000..d3164c8
--- /dev/null
+++ b/compile
@@ -0,0 +1 @@
+/usr/share/automake-1.14/compile
\ No newline at end of file
index 38010f7af1fc539a478f1516b1f40a1063d039d3..eadd4cb2abddd013bec89b855491979dad178877 100644 (file)
@@ -1,5 +1,8 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
index 8b47871fb81fc748043e83d64d60aba1397b4113..a4c3b40df55918436f94d3b733b155b9eb0e0ad9 100755 (executable)
--- a/configure
+++ b/configure
@@ -2712,9 +2712,8 @@ fi
 
 
 # Define the identity of the package.
-
- PACKAGE=skeinsum
- VERSION=1.0
+ PACKAGE='skeinsum'
+ VERSION='1.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4249,7 +4248,7 @@ fi
 done
 
 
-for ac_header in limits.h malloc.h stddef.h stdlib.h string.h unistd.h
+for ac_header in limits.h malloc.h stddef.h stdlib.h string.h unistd.h errno.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
index 05488e2155976d267838eccd949096197dd3f3ad..8bc5fe1f5d4b03b635f3f6cf9417d91898a42cc5 100644 (file)
@@ -5,7 +5,7 @@ AC_PREREQ([2.68])
 AC_INIT([skeinsum], [1.0], [j@jxself.org])
 AC_CONFIG_SRCDIR([skein.h])
 AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE([skeinsum],[1.0])
+AM_INIT_AUTOMAKE
 
 # Checks for programs.
 AC_PROG_CC
@@ -13,7 +13,7 @@ AC_PROG_CC
 # Checks for libraries.
 
 # Checks for header files.
-AC_CHECK_HEADERS([limits.h malloc.h stddef.h stdlib.h string.h unistd.h])
+AC_CHECK_HEADERS([limits.h malloc.h stddef.h stdlib.h string.h unistd.h errno.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_SIZE_T
index 31b47bd006c7a285806224757e4b9fba9890161e..741052d994c1f1f9070bf7f86feb39a7c4079af7 100644 (file)
@@ -1,5 +1,5 @@
 bin_PROGRAMS = skein256sum skein512sum skein1024sum
-skein256sum_SOURCES = SHA3api_ref.c skein.c skein256.c skein_block.c skein_debug.c
-skein512sum_SOURCES = SHA3api_ref.c skein.c skein512.c skein_block.c skein_debug.c
-skein1024sum_SOURCES = SHA3api_ref.c skein.c skein1024.c skein_block.c skein_debug.c
+skein256sum_SOURCES = SHA3api_ref.c skein.c skein256.c skein_block.c skein_debug.c skein_cli.c
+skein512sum_SOURCES = SHA3api_ref.c skein.c skein512.c skein_block.c skein_debug.c skein_cli.c
+skein1024sum_SOURCES = SHA3api_ref.c skein.c skein1024.c skein_block.c skein_debug.c skein_cli.c
 include_HEADERS = brg_endian.h brg_types.h SHA3api_ref.h skein.h skein_debug.h skein_port.h
index b9692188ac6be503a78963ce9d14bb4f49dd1cba..86d4afdc6771f870bf08f98e868311147ea6ec78 100644 (file)
@@ -99,15 +99,17 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"
 PROGRAMS = $(bin_PROGRAMS)
 am_skein1024sum_OBJECTS = SHA3api_ref.$(OBJEXT) skein.$(OBJEXT) \
        skein1024.$(OBJEXT) skein_block.$(OBJEXT) \
-       skein_debug.$(OBJEXT)
+       skein_debug.$(OBJEXT) skein_cli.$(OBJEXT)
 skein1024sum_OBJECTS = $(am_skein1024sum_OBJECTS)
 skein1024sum_LDADD = $(LDADD)
 am_skein256sum_OBJECTS = SHA3api_ref.$(OBJEXT) skein.$(OBJEXT) \
-       skein256.$(OBJEXT) skein_block.$(OBJEXT) skein_debug.$(OBJEXT)
+       skein256.$(OBJEXT) skein_block.$(OBJEXT) skein_debug.$(OBJEXT) \
+       skein_cli.$(OBJEXT)
 skein256sum_OBJECTS = $(am_skein256sum_OBJECTS)
 skein256sum_LDADD = $(LDADD)
 am_skein512sum_OBJECTS = SHA3api_ref.$(OBJEXT) skein.$(OBJEXT) \
-       skein512.$(OBJEXT) skein_block.$(OBJEXT) skein_debug.$(OBJEXT)
+       skein512.$(OBJEXT) skein_block.$(OBJEXT) skein_debug.$(OBJEXT) \
+       skein_cli.$(OBJEXT)
 skein512sum_OBJECTS = $(am_skein512sum_OBJECTS)
 skein512sum_LDADD = $(LDADD)
 AM_V_P = $(am__v_P_@AM_V@)
@@ -301,9 +303,9 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-skein256sum_SOURCES = SHA3api_ref.c skein.c skein256.c skein_block.c skein_debug.c
-skein512sum_SOURCES = SHA3api_ref.c skein.c skein512.c skein_block.c skein_debug.c
-skein1024sum_SOURCES = SHA3api_ref.c skein.c skein1024.c skein_block.c skein_debug.c
+skein256sum_SOURCES = SHA3api_ref.c skein.c skein256.c skein_block.c skein_debug.c skein_cli.c
+skein512sum_SOURCES = SHA3api_ref.c skein.c skein512.c skein_block.c skein_debug.c skein_cli.c
+skein1024sum_SOURCES = SHA3api_ref.c skein.c skein1024.c skein_block.c skein_debug.c skein_cli.c
 include_HEADERS = brg_endian.h brg_types.h SHA3api_ref.h skein.h skein_debug.h skein_port.h
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-am
@@ -426,6 +428,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skein256.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skein512.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skein_block.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skein_cli.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skein_debug.Po@am__quote@
 
 .c.o:
diff --git a/missing b/missing
index 86a8fc31e3c2aa268688a5be47d161c586772e78..db98974ff5d59295d7e0edfec2eb2069dc78ef1a 100755 (executable)
--- a/missing
+++ b/missing
@@ -1,11 +1,10 @@
 #! /bin/sh
-# Common stub for a few missing GNU programs while installing.
+# Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2012-01-06.13; # UTC
+scriptversion=2013-10-28.13; # UTC
 
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
-# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+# 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
@@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC
 # 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"
+  echo 1>&2 "Try '$0 --help' for more information"
   exit 1
 fi
 
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
-  configure_ac=configure.ac
-else
-  configure_ac=configure.in
-fi
+case $1 in
 
-msg="missing on your system"
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
 
-case $1 in
---run)
-  # Try to run requested program, and just exit if it succeeds.
-  run=
-  shift
-  "$@" && exit 0
-  # Exit code 63 means version mismatch.  This often happens
-  # when the user try to use an ancient version of a tool on
-  # a file that requires a minimum version.  In this case we
-  # we should proceed has if the program had been absent, or
-  # if --run hadn't been passed.
-  if test $? = 63; then
-    run=:
-    msg="probably too old"
-  fi
-  ;;
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
 
   -h|--h|--he|--hel|--help)
     echo "\
 $0 [OPTION]... PROGRAM [ARGUMENT]...
 
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
+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
-  --run           try to run the given command, and emulate it if it fails
 
 Supported PROGRAM values:
-  aclocal      touch file \`aclocal.m4'
-  autoconf     touch file \`configure'
-  autoheader   touch file \`config.h.in'
-  autom4te     touch the output file, or create a stub one
-  automake     touch all \`Makefile.in' files
-  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
-  flex         create \`lex.yy.c', if possible, from existing .c
-  help2man     touch the output file
-  lex          create \`lex.yy.c', if possible, from existing .c
-  makeinfo     touch the output file
-  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+  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.
+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 $?
@@ -99,228 +70,141 @@ Send bug reports to <bug-automake@gnu.org>."
     ;;
 
   -*)
-    echo 1>&2 "$0: Unknown \`$1' option"
-    echo 1>&2 "Try \`$0 --help' for more information"
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
     exit 1
     ;;
 
 esac
 
-# normalize program name to check for.
-program=`echo "$1" | sed '
-  s/^gnu-//; t
-  s/^gnu//; t
-  s/^g//; t'`
-
-# Now exit if we have it, but it failed.  Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).  This is about non-GNU programs, so use $1 not
-# $program.
-case $1 in
-  lex*|yacc*)
-    # Not GNU programs, they don't have --version.
-    ;;
-
-  *)
-    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
-       # We have it, but it failed.
-       exit 1
-    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
-       # Could not run --version or --help.  This is probably someone
-       # running `$TOOL --version' or `$TOOL --help' to check whether
-       # $TOOL exists and not knowing $TOOL uses missing.
-       exit 1
-    fi
-    ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $program in
-  aclocal*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
-         to install the \`Automake' and \`Perl' packages.  Grab them from
-         any GNU archive site."
-    touch aclocal.m4
-    ;;
-
-  autoconf*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`${configure_ac}'.  You might want to install the
-         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
-         archive site."
-    touch configure
-    ;;
-
-  autoheader*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
-         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
-         from any GNU archive site."
-    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
-    test -z "$files" && files="config.h"
-    touch_files=
-    for f in $files; do
-      case $f in
-      *:*) touch_files="$touch_files "`echo "$f" |
-                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
-      *) touch_files="$touch_files $f.in";;
-      esac
-    done
-    touch $touch_files
-    ;;
-
-  automake*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
-         You might want to install the \`Automake' and \`Perl' packages.
-         Grab them from any GNU archive site."
-    find . -type f -name Makefile.am -print |
-          sed 's/\.am$/.in/' |
-          while read f; do touch "$f"; done
-    ;;
-
-  autom4te*)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
-         You might have modified some files without having the
-         proper tools for further handling them.
-         You can get \`$1' as part of \`Autoconf' from any GNU
-         archive site."
-
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -f "$file"; then
-       touch $file
-    else
-       test -z "$file" || exec >$file
-       echo "#! /bin/sh"
-       echo "# Created by GNU Automake missing as a replacement of"
-       echo "#  $ $@"
-       echo "exit 0"
-       chmod +x $file
-       exit 1
-    fi
-    ;;
-
-  bison*|yacc*)
-    echo 1>&2 "\
-WARNING: \`$1' $msg.  You should only need it if
-         you modified a \`.y' file.  You may need the \`Bison' package
-         in order for those modifications to take effect.  You can get
-         \`Bison' from any GNU archive site."
-    rm -f y.tab.c y.tab.h
-    if test $# -ne 1; then
-        eval LASTARG=\${$#}
-       case $LASTARG in
-       *.y)
-           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
-           if test -f "$SRCFILE"; then
-                cp "$SRCFILE" y.tab.c
-           fi
-           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
-           if test -f "$SRCFILE"; then
-                cp "$SRCFILE" y.tab.h
-           fi
-         ;;
-       esac
-    fi
-    if test ! -f y.tab.h; then
-       echo >y.tab.h
-    fi
-    if test ! -f y.tab.c; then
-       echo 'main() { return 0; }' >y.tab.c
-    fi
-    ;;
-
-  lex*|flex*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified a \`.l' file.  You may need the \`Flex' package
-         in order for those modifications to take effect.  You can get
-         \`Flex' from any GNU archive site."
-    rm -f lex.yy.c
-    if test $# -ne 1; then
-        eval LASTARG=\${$#}
-       case $LASTARG in
-       *.l)
-           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
-           if test -f "$SRCFILE"; then
-                cp "$SRCFILE" lex.yy.c
-           fi
-         ;;
-       esac
-    fi
-    if test ! -f lex.yy.c; then
-       echo 'main() { return 0; }' >lex.yy.c
-    fi
-    ;;
-
-  help2man*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-        you modified a dependency of a manual page.  You may need the
-        \`Help2man' package in order for those modifications to take
-        effect.  You can get \`Help2man' from any GNU archive site."
-
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -f "$file"; then
-       touch $file
-    else
-       test -z "$file" || exec >$file
-       echo ".ab help2man is required to generate this page"
-       exit $?
-    fi
-    ;;
-
-  makeinfo*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified a \`.texi' or \`.texinfo' file, or any other file
-         indirectly affecting the aspect of the manual.  The spurious
-         call might also be the consequence of using a buggy \`make' (AIX,
-         DU, IRIX).  You might want to install the \`Texinfo' package or
-         the \`GNU make' package.  Grab either from any GNU archive site."
-    # The file to touch is that specified with -o ...
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -z "$file"; then
-      # ... or it is the one specified with @setfilename ...
-      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '
-       /^@setfilename/{
-         s/.* \([^ ]*\) *$/\1/
-         p
-         q
-       }' $infile`
-      # ... or it is derived from the source name (dir/f.texi becomes f.info)
-      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
-    fi
-    # If the file does not exist, the user really needs makeinfo;
-    # let's fail without touching anything.
-    test -f $file || exit 1
-    touch $file
-    ;;
+# 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
 
-  *)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
-         You might have modified some files without having the
-         proper tools for further handling them.  Check the \`README' file,
-         it often tells you about the needed prerequisites for installing
-         this package.  You may also peek at any GNU archive site, in case
-         some other package would contain this missing \`$1' program."
-    exit 1
+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/>"
     ;;
-esac
-
-exit 0
+    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)
index 1fde74ea9af6c94619812b017181b3df715b259a..4fa5e4499330311c73e5f103535458616a2c08a7 100644 (file)
@@ -1,772 +1 @@
-/* Copyright (C) 2014, 2015 Jason Self <j@jxself.org>
-
-This file is part of skeinsum.
-
-skeinsum 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.
-
-skeinsum 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 skeinsum. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <getopt.h>
-#include <malloc.h>
-#include <math.h>
-#include <glob.h>
-#include <sys/stat.h>
-#include "SHA3api_ref.h"
-
-#define hashbitlen 1024
-#define MaxNmberFiles 10
-#define skeinVersion "1.3"
-
-
-char invalidOption = 0;
-
-enum
-{
-  QUIET_OPTION = 11,
-  STATUS_OPTION,
-  TAG_OPTION,
-  HELP_OPTION,
-  VERSION_OPTION
-};
-
-static struct option const long_options[] =
-{
-  { "binary", no_argument, NULL, 'b' },
-  { "check", no_argument, NULL, 'c' },
-  { "quiet", no_argument, NULL, QUIET_OPTION },
-  { "status", no_argument, NULL, STATUS_OPTION },
-  { "text", no_argument, NULL, 't' },
-  { "warn", no_argument, NULL, 'w' },
-  { "tag", no_argument, NULL, TAG_OPTION },
-  { "help", no_argument, NULL, HELP_OPTION },
-  { "version", no_argument, NULL, VERSION_OPTION },
-  { NULL, 0, NULL, 0 }
-};
-
-void printHexMsg(unsigned char *ptr, int size, char result[])
-{
-       int i = 0;
-       int j = 0;
-       char High, Low;
-       for (i = 0 ; i < size ; i ++)
-       {
-               High = ptr[i]>>4;
-               Low = ptr[i]&0x0F;
-
-               if (High >= 0xA && High <= 0xF)
-                       High += 0x37;
-               else if(High >= 0x0 && High <= 0x9)
-                       High += 0x30;
-
-               if (Low >= 0xA && Low <= 0xF)
-                       Low += 0x37;
-               else if(Low >= 0x0 && Low <= 0x9)
-                       Low += 0x30;
-
-               result[j++] = High;
-               result[j++] = Low;
-       }
-       result[i] = 0;
-}
-
-int HashTextMode(char file_name[], char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"r");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       char *hello;
-       hello = (char*) malloc (size_fp_in);
-       fgets(hello,size_fp_in,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashBinaryMode(char file_name[],char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"rb");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       unsigned char *hello;
-       hello = (unsigned char*) malloc (size_fp_in);
-       fread(hello,size_fp_in,1,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashStringMode(char Msg[],char MsgDigest[])
-{
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) Msg,sizeof(Msg),output);
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-       return 1;
-}
-
-/*
- *  return 1 : is File
- *  return 2 : is Directory
- *  return -1 : Something else.
- */
-int isFile(char argument[])
-{
-       struct stat s;
-       if( stat(argument,&s) == 0 )
-       {
-           if( s.st_mode & S_IFDIR )
-           {
-               return 2;
-           }
-           else if( s.st_mode & S_IFREG )
-           {
-               return 1;
-           }
-       }
-       else
-               return -1;
-       return 0;
-}
-
-int isProper(char MsgDigest[])
-{
-       if ((strlen(MsgDigest) - hashbitlen/4) != 0)
-               return 0;
-       int index = 0;
-       char c = 0;
-       for(index = 0; index < strlen(MsgDigest);index++)
-       {
-               c = MsgDigest[index];
-               if(!(( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'F')))
-                       return 0;
-       }
-
-       return 1;
-}
-
-
-int decomposeHashLine(char hash[], char MsgDigest_tmp[], char file_tmp[])
-{
-       char c = 0;
-       int i = 0 , j =0;
-       int isTagFile = 0;
-       char alg[20];
-       char tmp[1000];
-       while(((c = hash[i])!=' ')&&((c = hash[i])!='_'))
-       {
-               tmp[i] = hash[i];
-               i++;
-       }
-       tmp[i] = 0;
-
-       sprintf(alg,"skein%d",hashbitlen);
-       if(!strcmp(alg,tmp))
-       {
-               isTagFile = 1;
-       }
-
-       if(isTagFile == 0)
-       {
-               strcpy(MsgDigest_tmp,tmp);
-               i++;
-               while((c = hash[i])!= '\n')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-       }
-       else if((hash[i]=='_')&&(hash[i+1]=='v'))
-       {
-               i = i + 2;
-               j = 0;
-               char version[5];
-               while((c = hash[i])!=' ')
-               {
-                       version[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               version[i] = 0;
-               float vers = 0, skeinVers = 0;
-               sscanf(version,"%f",&vers);
-               sscanf(skeinVersion,"%f",&skeinVers);
-
-               j = 0;
-               i = i + 2;
-               while((c = hash[i])!=')')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-
-               i = i + 4;
-               j = 0;
-               while((c = hash[i])!='\n')
-               {
-                       MsgDigest_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               MsgDigest_tmp[j] = 0;
-
-               if(skeinVers < vers)
-               {//version newer than mine
-                       return (-1);
-               }
-               else if (skeinVers > vers)
-               {//going to use older version than mine
-                       return (0) ;
-               }
-               else
-               { //versions match
-                       return (1);
-               }
-       }
-       return 1;
-
-}
-
-
-
-int main(int argc, char** argv)
-{
-       char MsgDigest[hashbitlen/2];
-       char **list_files = (char**) malloc(MaxNmberFiles* sizeof(char*));
-       int number_files = 0;
-       int binary = -1,
-                check = -1,
-                quiet = -1,
-                warn = -1,
-                status = -1,
-                help = -1,
-                version = -1,
-                tag = -1,
-                hashString = -1,
-                badParam = -1;
-
-       int errorFound = 0;
-       int opt = 0;
-/*****************************************************************************************
- ************************************* GETTING DATA ***********************************
- *****************************************************************************************/
-  while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
-  {
-         switch (opt)
-         {
-                       case 'b' :
-                       {
-                               binary = 1;
-                               break;
-                       }
-                       case 't' :
-                       {
-                               binary = 0;
-                               break;
-                       }
-                       case 'c' :
-                       {
-                               check = 1;
-                               break;
-                       }
-                       case QUIET_OPTION :
-                       {
-                               quiet = 1;
-                               break;
-                       }
-                       case 'w' :
-                       {
-                               warn = 1;
-                               break;
-                       }
-                       case STATUS_OPTION :
-                       {
-                               status = 1;
-                               break;
-                       }
-                       case HELP_OPTION :
-                       {
-                               help = 1;
-                               break;
-                       }
-                       case VERSION_OPTION :
-                       {
-                               version = 1;
-                               break;
-                       }
-                       case TAG_OPTION :
-                       {
-                               tag = 1;
-                               break;
-                       }
-                       case 0 :
-                       {
-                               hashString = 1;
-                               break;
-                       }
-                       default :
-                       {
-                               badParam = 1;
-                               break;
-                       }
-         }
-       }
-
-  if(badParam == 1)
-       {
-               printf("Try `skein%dsum --help' for more information.\n",hashbitlen);
-               exit(1);
-       }
-
-  for (; optind < argc; ++optind)
-  {
-               switch (opt)
-               {
-                       case -1:
-                       {// no options found, test if there is a file and hash it
-                               if(isFile(argv[optind]) == 1)
-                               {
-                                       char *file_name = malloc(sizeof(argv[optind]));
-                                       file_name = argv[optind];
-                                       list_files[number_files] = (char*) malloc (sizeof(file_name));
-                                       list_files[number_files] = file_name;
-                                       number_files ++;
-                               }
-                               else if (isFile(argv[optind]) == 2)
-                               {
-                                       printf("skein%dsum: %s Is a directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               break;
-                       }
-               }
-       }
-/*****************************************************************************************
- ************************************* PROCESSING DATA ***********************************
- *****************************************************************************************/
-       if(argc > 1 && version == 1)
-       {
-               printf("skein1024sum 1.0\n");
-               printf("License GPLv3+: GNU GPL version 3 or later\n");
-               printf("<http://gnu.org/licenses/gpl.html>\n");
-               printf("This is free software: you are free to change and redistribute it.\n");
-               printf("There is NO WARRANTY, to the extent permitted by law.\n");
-               exit(1);
-       }
-       if(argc > 1 && help == 1)
-       {
-
-               printf("Usage: skein%dsum [OPTION]... [FILE]...\n",hashbitlen);
-               printf("Print or check skein (%d-bit) checksums.\n",hashbitlen);
-               printf("With no FILE, or when FILE is -, read standard input.\n");
-               printf("\n");
-               printf("-b, --binary         read in binary mode\n");
-               printf("-c, --check          read skein sums from the FILEs and check them\n");
-               printf("--tag            create a BSD-style checksum\n");
-               printf("-t, --text           read in text mode (default)\n");
-               printf("\n");
-               printf("The following three options are useful only when verifying checksums:\n");
-               printf("--quiet          don't print OK for each successfully verified file\n");
-               printf("--status         don't output anything, status code shows success\n");
-               printf("-w, --warn           warn about improperly formatted checksum lines\n");
-               printf("\n");
-               printf("--strict         with --check, exit non-zero for any invalid input\n");
-               printf("--help     display this help and exit\n");
-               printf("--version  output version information and exit\n");
-               printf("\n");
-               printf("The sums are computed as described in version 1.3 of the Skein\n");
-               printf("specification. When checking, the input should be a former output of\n");
-               printf("this program. The default mode is to print a line with checksum, a\n");
-               printf("character indicating input mode ('*' for binary, space for text), and\n");
-               printf("name for each FILE.\n");
-               exit(1);
-       }
-
-       if(argc > 1 && binary == 1)
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(hashString == 1)
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,list_files[index_files]);
-                                       index_files++;
-                                       continue;
-                               }
-                               if(HashBinaryMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("*%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s *-\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == 0) // Text Mode
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s -\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == -1)
-       {
-               if(check == -1)
-               {// hashing stdin entries
-                       if(quiet == 1 || status == 1 || warn == 1)
-                       {
-                               if(quiet == 1)
-                                       printf("skein%dsum: the --quiet option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(status ==1)
-                                       printf("skein%dsum: the --status option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(warn == 1)
-                                       printf("skein%dsum: the --warn option is meaningful only when verifying checksums\n",hashbitlen);
-
-                               printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                               exit(1);
-                       }
-                       if(number_files > 0)
-                       {// hashing files
-                               int index_files = 0;
-                               while(index_files < number_files)
-                               {
-                                       if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                                       {
-                                               if(tag == 1)
-                                               {
-                                                       printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                               }
-                                               else
-                                               {
-                                                       printf("%s ",MsgDigest);
-                                                       printf("%s\n",list_files[index_files]);
-                                               }
-                                       }
-                                       index_files++;
-                               }
-                       }
-                       else if(errorFound != 1)
-                       { // hasing strings read from  stdin
-                               char stri[100];
-                               char longstring[1000];
-                               longstring[0] = 0;
-                               while((fgets(stri,100,stdin))!=NULL)
-                               {
-                                       strcat(longstring,stri);
-                               }
-                               HashStringMode(longstring,MsgDigest);
-                               if(tag == 1)
-                               {
-                                       printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                               }
-                               else
-                               {
-                                       printf("%s -\n",MsgDigest);
-                               }
-                       }
-               }
-               else if(check == 1)
-               {
-                       if(tag == 1)
-                       {
-                               printf("skein%dsum: the --tag option is meaningless when verifying checksums\n",hashbitlen);
-                               printf("Try 'skein%dsum --help' for more information\n",hashbitlen);
-                               exit(1);
-                       }
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               FILE *fp;
-                               char hash[500], file_name[100], file_tmp[100], MsgDigest_tmp[hashbitlen/2];
-                               int NoMatch = 0, NotProper = 0, Computed = 0;
-                               strcpy(file_name,list_files[index_files]);
-                               //show everything
-                               int line = 0;
-                               fp = fopen(file_name,"r");
-                               if(fp!=NULL)
-                               {
-                                       while(fgets(hash,500,fp)!=NULL)
-                                       {
-                                               line ++;
-                                               Computed++;
-                                               unsigned int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp);
-                                               if(hashVersion == -1)
-                                               {
-                                                       printf("skein%d: %s is using newer version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should update your algorithm\n");
-                                                       continue;
-                                               }
-                                               else if( hashVersion == 0)
-                                               {
-                                                       printf("skein%d: %s is using an older version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should use the older algorithm\n");
-                                                       continue;
-                                               }
-                                               else
-                                               {
-                                                       if(!isProper(MsgDigest_tmp))
-                                                       {
-                                                               if(status != 1 && warn == 1)
-                                                               {
-                                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_tmp,line,hashbitlen);
-                                                               }
-                                                               NotProper ++;
-                                                               NoMatch ++;
-                                                               continue;
-                                                       }
-                                                       if(file_tmp[0] == '*')
-                                                       {
-                                                               int index_file_tmp = 0;
-                                                               for( ; file_tmp[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                                               {
-                                                                       file_tmp[index_file_tmp] = file_tmp[index_file_tmp + 1];
-                                                               }
-                                                               file_tmp[index_file_tmp] = 0;
-                                                               HashBinaryMode(file_tmp,MsgDigest);
-                                                       }
-                                                       else
-                                                       {
-                                                               HashTextMode(file_tmp,MsgDigest);
-                                                       }
-
-                                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                                       {
-                                                               if(quiet != 1)
-                                                               {
-                                                                       printf("%s: OK\n",file_tmp);
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               printf("%s: FAILED\n",file_tmp);
-                                                               NoMatch ++;
-                                                       }
-                                               }
-                                       }
-                                       if(NoMatch)
-                                       {
-                                               printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                               hashbitlen,NoMatch,Computed);
-                                       }
-                                       if(NotProper)
-                                       {
-                                               printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                                       }
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,file_name);
-                               }
-                               index_files++;
-
-                       }
-
-                       if(number_files  == 0)
-                       {
-                               char longstring[1000];
-                               char file_name[30];
-                               char MsgDigest_tmp[hashbitlen/2];
-                               int Computed = 0, NotProper = 0, NoMatch = 0 , line = 0;
-                               while((fgets(longstring,1000,stdin))!=NULL)
-                               {
-                                       Computed++;
-                                       line ++;
-                                       decomposeHashLine(longstring,MsgDigest_tmp,file_name);
-                                       if(!isProper(MsgDigest_tmp))
-                                       {
-                                               if(status != 1 && warn == 1)
-                                               {
-                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_name,line,hashbitlen);
-                                               }
-                                               NotProper ++;
-                                               NoMatch ++;
-                                               continue;
-                                       }
-                                       if(file_name[0] == '*')
-                                       {
-                                               int index_file_tmp = 0;
-                                               for( ; file_name[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                               {
-                                                       file_name[index_file_tmp] = file_name[index_file_tmp + 1];
-                                               }
-                                               file_name[index_file_tmp] = 0;
-                                               HashBinaryMode(file_name,MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               HashTextMode(file_name,MsgDigest);
-                                       }
-
-                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                       {
-                                               if(quiet != 1)
-                                               {
-                                                       printf("%s: OK\n",file_name);
-                                               }
-                                       }
-                                       else
-                                       {
-                                               printf("%s: FAILED\n",file_name);
-                                               NoMatch ++;
-                                       }
-                               }
-                               if(NoMatch)
-                               {
-                                       printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                       hashbitlen,NoMatch,Computed);
-                               }
-                               if(NotProper)
-                               {
-                                       printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                               }
-
-                       }
-
-
-               }
-       }
-
-       if ((errorFound != 1) && (argc == 1 || (hashString == 1 && number_files == 0)))
-       {
-               char stri[100];
-               char longstring[1000];
-               longstring[0] = 0;
-               while((fgets(stri,100,stdin))!=NULL)
-               {
-                               strcat(longstring,stri);
-               }
-               HashStringMode(longstring,MsgDigest);
-               printf("%s -\n",MsgDigest);
-       }
-
-       return 1;
-}
+const int hashbitlen = 1024;
index 66d31f3109115fc2142e5dd796e840bcb6ae4a20..2a18caffd5e089f1e92682b8192c53ecb7bb9245 100644 (file)
@@ -1,772 +1 @@
-/* Copyright (C) 2014, 2015 Jason Self <j@jxself.org>
-
-This file is part of skeinsum.
-
-skeinsum 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.
-
-skeinsum 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 skeinsum. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <getopt.h>
-#include <malloc.h>
-#include <math.h>
-#include <glob.h>
-#include <sys/stat.h>
-#include "SHA3api_ref.h"
-
-#define hashbitlen 256
-#define MaxNmberFiles 10
-#define skeinVersion "1.3"
-
-
-char invalidOption = 0;
-
-enum
-{
-  QUIET_OPTION = 11,
-  STATUS_OPTION,
-  TAG_OPTION,
-  HELP_OPTION,
-  VERSION_OPTION
-};
-
-static struct option const long_options[] =
-{
-  { "binary", no_argument, NULL, 'b' },
-  { "check", no_argument, NULL, 'c' },
-  { "quiet", no_argument, NULL, QUIET_OPTION },
-  { "status", no_argument, NULL, STATUS_OPTION },
-  { "text", no_argument, NULL, 't' },
-  { "warn", no_argument, NULL, 'w' },
-  { "tag", no_argument, NULL, TAG_OPTION },
-  { "help", no_argument, NULL, HELP_OPTION },
-  { "version", no_argument, NULL, VERSION_OPTION },
-  { NULL, 0, NULL, 0 }
-};
-
-void printHexMsg(unsigned char *ptr, int size, char result[])
-{
-       int i = 0;
-       int j = 0;
-       char High, Low;
-       for (i = 0 ; i < size ; i ++)
-       {
-               High = ptr[i]>>4;
-               Low = ptr[i]&0x0F;
-
-               if (High >= 0xA && High <= 0xF)
-                       High += 0x37;
-               else if(High >= 0x0 && High <= 0x9)
-                       High += 0x30;
-
-               if (Low >= 0xA && Low <= 0xF)
-                       Low += 0x37;
-               else if(Low >= 0x0 && Low <= 0x9)
-                       Low += 0x30;
-
-               result[j++] = High;
-               result[j++] = Low;
-       }
-       result[i] = 0;
-}
-
-int HashTextMode(char file_name[], char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"r");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       char *hello;
-       hello = (char*) malloc (size_fp_in);
-       fgets(hello,size_fp_in,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashBinaryMode(char file_name[],char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"rb");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       unsigned char *hello;
-       hello = (unsigned char*) malloc (size_fp_in);
-       fread(hello,size_fp_in,1,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashStringMode(char Msg[],char MsgDigest[])
-{
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) Msg,sizeof(Msg),output);
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-       return 1;
-}
-
-/*
- *  return 1 : is File
- *  return 2 : is Directory
- *  return -1 : Something else.
- */
-int isFile(char argument[])
-{
-       struct stat s;
-       if( stat(argument,&s) == 0 )
-       {
-           if( s.st_mode & S_IFDIR )
-           {
-               return 2;
-           }
-           else if( s.st_mode & S_IFREG )
-           {
-               return 1;
-           }
-       }
-       else
-               return -1;
-       return 0;
-}
-
-int isProper(char MsgDigest[])
-{
-       if ((strlen(MsgDigest) - hashbitlen/4) != 0)
-               return 0;
-       int index = 0;
-       char c = 0;
-       for(index = 0; index < strlen(MsgDigest);index++)
-       {
-               c = MsgDigest[index];
-               if(!(( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'F')))
-                       return 0;
-       }
-
-       return 1;
-}
-
-
-int decomposeHashLine(char hash[], char MsgDigest_tmp[], char file_tmp[])
-{
-       char c = 0;
-       int i = 0 , j =0;
-       int isTagFile = 0;
-       char alg[20];
-       char tmp[1000];
-       while(((c = hash[i])!=' ')&&((c = hash[i])!='_'))
-       {
-               tmp[i] = hash[i];
-               i++;
-       }
-       tmp[i] = 0;
-
-       sprintf(alg,"skein%d",hashbitlen);
-       if(!strcmp(alg,tmp))
-       {
-               isTagFile = 1;
-       }
-
-       if(isTagFile == 0)
-       {
-               strcpy(MsgDigest_tmp,tmp);
-               i++;
-               while((c = hash[i])!= '\n')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-       }
-       else if((hash[i]=='_')&&(hash[i+1]=='v'))
-       {
-               i = i + 2;
-               j = 0;
-               char version[5];
-               while((c = hash[i])!=' ')
-               {
-                       version[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               version[i] = 0;
-               float vers = 0, skeinVers = 0;
-               sscanf(version,"%f",&vers);
-               sscanf(skeinVersion,"%f",&skeinVers);
-
-               j = 0;
-               i = i + 2;
-               while((c = hash[i])!=')')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-
-               i = i + 4;
-               j = 0;
-               while((c = hash[i])!='\n')
-               {
-                       MsgDigest_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               MsgDigest_tmp[j] = 0;
-
-               if(skeinVers < vers)
-               {//version newer than mine
-                       return (-1);
-               }
-               else if (skeinVers > vers)
-               {//going to use older version than mine
-                       return (0) ;
-               }
-               else
-               { //versions match
-                       return (1);
-               }
-       }
-       return 1;
-
-}
-
-
-
-int main(int argc, char** argv)
-{
-       char MsgDigest[hashbitlen/2];
-       char **list_files = (char**) malloc(MaxNmberFiles* sizeof(char*));
-       int number_files = 0;
-       int binary = -1,
-                check = -1,
-                quiet = -1,
-                warn = -1,
-                status = -1,
-                help = -1,
-                version = -1,
-                tag = -1,
-                hashString = -1,
-                badParam = -1;
-
-       int errorFound = 0;
-       int opt = 0;
-/*****************************************************************************************
- ************************************* GETTING DATA ***********************************
- *****************************************************************************************/
-  while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
-  {
-         switch (opt)
-         {
-                       case 'b' :
-                       {
-                               binary = 1;
-                               break;
-                       }
-                       case 't' :
-                       {
-                               binary = 0;
-                               break;
-                       }
-                       case 'c' :
-                       {
-                               check = 1;
-                               break;
-                       }
-                       case QUIET_OPTION :
-                       {
-                               quiet = 1;
-                               break;
-                       }
-                       case 'w' :
-                       {
-                               warn = 1;
-                               break;
-                       }
-                       case STATUS_OPTION :
-                       {
-                               status = 1;
-                               break;
-                       }
-                       case HELP_OPTION :
-                       {
-                               help = 1;
-                               break;
-                       }
-                       case VERSION_OPTION :
-                       {
-                               version = 1;
-                               break;
-                       }
-                       case TAG_OPTION :
-                       {
-                               tag = 1;
-                               break;
-                       }
-                       case 0 :
-                       {
-                               hashString = 1;
-                               break;
-                       }
-                       default :
-                       {
-                               badParam = 1;
-                               break;
-                       }
-         }
-       }
-
-  if(badParam == 1)
-       {
-               printf("Try `skein%dsum --help' for more information.\n",hashbitlen);
-               exit(1);
-       }
-
-  for (; optind < argc; ++optind)
-  {
-               switch (opt)
-               {
-                       case -1:
-                       {// no options found, test if there is a file and hash it
-                               if(isFile(argv[optind]) == 1)
-                               {
-                                       char *file_name = malloc(sizeof(argv[optind]));
-                                       file_name = argv[optind];
-                                       list_files[number_files] = (char*) malloc (sizeof(file_name));
-                                       list_files[number_files] = file_name;
-                                       number_files ++;
-                               }
-                               else if (isFile(argv[optind]) == 2)
-                               {
-                                       printf("skein%dsum: %s Is a directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               break;
-                       }
-               }
-       }
-/*****************************************************************************************
- ************************************* PROCESSING DATA ***********************************
- *****************************************************************************************/
-       if(argc > 1 && version == 1)
-       {
-               printf("skein256sum 1.0\n");
-               printf("License GPLv3+: GNU GPL version 3 or later\n");
-               printf("<http://gnu.org/licenses/gpl.html>\n");
-               printf("This is free software: you are free to change and redistribute it.\n");
-               printf("There is NO WARRANTY, to the extent permitted by law.\n");
-               exit(1);
-       }
-       if(argc > 1 && help == 1)
-       {
-
-               printf("Usage: skein%dsum [OPTION]... [FILE]...\n",hashbitlen);
-               printf("Print or check skein (%d-bit) checksums.\n",hashbitlen);
-               printf("With no FILE, or when FILE is -, read standard input.\n");
-               printf("\n");
-               printf("-b, --binary         read in binary mode\n");
-               printf("-c, --check          read skein sums from the FILEs and check them\n");
-               printf("--tag            create a BSD-style checksum\n");
-               printf("-t, --text           read in text mode (default)\n");
-               printf("\n");
-               printf("The following three options are useful only when verifying checksums:\n");
-               printf("--quiet          don't print OK for each successfully verified file\n");
-               printf("--status         don't output anything, status code shows success\n");
-               printf("-w, --warn           warn about improperly formatted checksum lines\n");
-               printf("\n");
-               printf("--strict         with --check, exit non-zero for any invalid input\n");
-               printf("--help     display this help and exit\n");
-               printf("--version  output version information and exit\n");
-               printf("\n");
-               printf("The sums are computed as described in version 1.3 of the Skein\n");
-               printf("specification. When checking, the input should be a former output of\n");
-               printf("this program. The default mode is to print a line with checksum, a\n");
-               printf("character indicating input mode ('*' for binary, space for text), and\n");
-               printf("name for each FILE.\n");
-               exit(1);
-       }
-
-       if(argc > 1 && binary == 1)
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(hashString == 1)
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,list_files[index_files]);
-                                       index_files++;
-                                       continue;
-                               }
-                               if(HashBinaryMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("*%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s *-\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == 0) // Text Mode
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s -\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == -1)
-       {
-               if(check == -1)
-               {// hashing stdin entries
-                       if(quiet == 1 || status == 1 || warn == 1)
-                       {
-                               if(quiet == 1)
-                                       printf("skein%dsum: the --quiet option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(status ==1)
-                                       printf("skein%dsum: the --status option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(warn == 1)
-                                       printf("skein%dsum: the --warn option is meaningful only when verifying checksums\n",hashbitlen);
-
-                               printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                               exit(1);
-                       }
-                       if(number_files > 0)
-                       {// hashing files
-                               int index_files = 0;
-                               while(index_files < number_files)
-                               {
-                                       if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                                       {
-                                               if(tag == 1)
-                                               {
-                                                       printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                               }
-                                               else
-                                               {
-                                                       printf("%s ",MsgDigest);
-                                                       printf("%s\n",list_files[index_files]);
-                                               }
-                                       }
-                                       index_files++;
-                               }
-                       }
-                       else if(errorFound != 1)
-                       { // hasing strings read from  stdin
-                               char stri[100];
-                               char longstring[1000];
-                               longstring[0] = 0;
-                               while((fgets(stri,100,stdin))!=NULL)
-                               {
-                                       strcat(longstring,stri);
-                               }
-                               HashStringMode(longstring,MsgDigest);
-                               if(tag == 1)
-                               {
-                                       printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                               }
-                               else
-                               {
-                                       printf("%s -\n",MsgDigest);
-                               }
-                       }
-               }
-               else if(check == 1)
-               {
-                       if(tag == 1)
-                       {
-                               printf("skein%dsum: the --tag option is meaningless when verifying checksums\n",hashbitlen);
-                               printf("Try 'skein%dsum --help' for more information\n",hashbitlen);
-                               exit(1);
-                       }
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               FILE *fp;
-                               char hash[500], file_name[100], file_tmp[100], MsgDigest_tmp[hashbitlen/2];
-                               int NoMatch = 0, NotProper = 0, Computed = 0;
-                               strcpy(file_name,list_files[index_files]);
-                               //show everything
-                               int line = 0;
-                               fp = fopen(file_name,"r");
-                               if(fp!=NULL)
-                               {
-                                       while(fgets(hash,500,fp)!=NULL)
-                                       {
-                                               line ++;
-                                               Computed++;
-                                               unsigned int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp);
-                                               if(hashVersion == -1)
-                                               {
-                                                       printf("skein%d: %s is using newer version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should update your algorithm\n");
-                                                       continue;
-                                               }
-                                               else if( hashVersion == 0)
-                                               {
-                                                       printf("skein%d: %s is using an older version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should use the older algorithm\n");
-                                                       continue;
-                                               }
-                                               else
-                                               {
-                                                       if(!isProper(MsgDigest_tmp))
-                                                       {
-                                                               if(status != 1 && warn == 1)
-                                                               {
-                                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_tmp,line,hashbitlen);
-                                                               }
-                                                               NotProper ++;
-                                                               NoMatch ++;
-                                                               continue;
-                                                       }
-                                                       if(file_tmp[0] == '*')
-                                                       {
-                                                               int index_file_tmp = 0;
-                                                               for( ; file_tmp[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                                               {
-                                                                       file_tmp[index_file_tmp] = file_tmp[index_file_tmp + 1];
-                                                               }
-                                                               file_tmp[index_file_tmp] = 0;
-                                                               HashBinaryMode(file_tmp,MsgDigest);
-                                                       }
-                                                       else
-                                                       {
-                                                               HashTextMode(file_tmp,MsgDigest);
-                                                       }
-
-                                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                                       {
-                                                               if(quiet != 1)
-                                                               {
-                                                                       printf("%s: OK\n",file_tmp);
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               printf("%s: FAILED\n",file_tmp);
-                                                               NoMatch ++;
-                                                       }
-                                               }
-                                       }
-                                       if(NoMatch)
-                                       {
-                                               printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                               hashbitlen,NoMatch,Computed);
-                                       }
-                                       if(NotProper)
-                                       {
-                                               printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                                       }
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,file_name);
-                               }
-                               index_files++;
-
-                       }
-
-                       if(number_files  == 0)
-                       {
-                               char longstring[1000];
-                               char file_name[30];
-                               char MsgDigest_tmp[hashbitlen/2];
-                               int Computed = 0, NotProper = 0, NoMatch = 0 , line = 0;
-                               while((fgets(longstring,1000,stdin))!=NULL)
-                               {
-                                       Computed++;
-                                       line ++;
-                                       decomposeHashLine(longstring,MsgDigest_tmp,file_name);
-                                       if(!isProper(MsgDigest_tmp))
-                                       {
-                                               if(status != 1 && warn == 1)
-                                               {
-                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_name,line,hashbitlen);
-                                               }
-                                               NotProper ++;
-                                               NoMatch ++;
-                                               continue;
-                                       }
-                                       if(file_name[0] == '*')
-                                       {
-                                               int index_file_tmp = 0;
-                                               for( ; file_name[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                               {
-                                                       file_name[index_file_tmp] = file_name[index_file_tmp + 1];
-                                               }
-                                               file_name[index_file_tmp] = 0;
-                                               HashBinaryMode(file_name,MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               HashTextMode(file_name,MsgDigest);
-                                       }
-
-                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                       {
-                                               if(quiet != 1)
-                                               {
-                                                       printf("%s: OK\n",file_name);
-                                               }
-                                       }
-                                       else
-                                       {
-                                               printf("%s: FAILED\n",file_name);
-                                               NoMatch ++;
-                                       }
-                               }
-                               if(NoMatch)
-                               {
-                                       printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                       hashbitlen,NoMatch,Computed);
-                               }
-                               if(NotProper)
-                               {
-                                       printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                               }
-
-                       }
-
-
-               }
-       }
-
-       if ((errorFound != 1) && (argc == 1 || (hashString == 1 && number_files == 0)))
-       {
-               char stri[100];
-               char longstring[1000];
-               longstring[0] = 0;
-               while((fgets(stri,100,stdin))!=NULL)
-               {
-                               strcat(longstring,stri);
-               }
-               HashStringMode(longstring,MsgDigest);
-               printf("%s -\n",MsgDigest);
-       }
-
-       return 1;
-}
+const int hashbitlen = 256;
index 97f84c3a8beecba454f0c7ed693c893b7fc781b7..dcd977ada14b97e4ced2ad9ad9786bc5fbf00790 100644 (file)
@@ -1,772 +1 @@
-/* Copyright (C) 2014, 2015 Jason Self <j@jxself.org>
-
-This file is part of skeinsum.
-
-skeinsum 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.
-
-skeinsum 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 skeinsum. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <getopt.h>
-#include <malloc.h>
-#include <math.h>
-#include <glob.h>
-#include <sys/stat.h>
-#include "SHA3api_ref.h"
-
-#define hashbitlen 512
-#define MaxNmberFiles 10
-#define skeinVersion "1.3"
-
-
-char invalidOption = 0;
-
-enum
-{
-  QUIET_OPTION = 11,
-  STATUS_OPTION,
-  TAG_OPTION,
-  HELP_OPTION,
-  VERSION_OPTION
-};
-
-static struct option const long_options[] =
-{
-  { "binary", no_argument, NULL, 'b' },
-  { "check", no_argument, NULL, 'c' },
-  { "quiet", no_argument, NULL, QUIET_OPTION },
-  { "status", no_argument, NULL, STATUS_OPTION },
-  { "text", no_argument, NULL, 't' },
-  { "warn", no_argument, NULL, 'w' },
-  { "tag", no_argument, NULL, TAG_OPTION },
-  { "help", no_argument, NULL, HELP_OPTION },
-  { "version", no_argument, NULL, VERSION_OPTION },
-  { NULL, 0, NULL, 0 }
-};
-
-void printHexMsg(unsigned char *ptr, int size, char result[])
-{
-       int i = 0;
-       int j = 0;
-       char High, Low;
-       for (i = 0 ; i < size ; i ++)
-       {
-               High = ptr[i]>>4;
-               Low = ptr[i]&0x0F;
-
-               if (High >= 0xA && High <= 0xF)
-                       High += 0x37;
-               else if(High >= 0x0 && High <= 0x9)
-                       High += 0x30;
-
-               if (Low >= 0xA && Low <= 0xF)
-                       Low += 0x37;
-               else if(Low >= 0x0 && Low <= 0x9)
-                       Low += 0x30;
-
-               result[j++] = High;
-               result[j++] = Low;
-       }
-       result[i] = 0;
-}
-
-int HashTextMode(char file_name[], char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"r");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       char *hello;
-       hello = (char*) malloc (size_fp_in);
-       fgets(hello,size_fp_in,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashBinaryMode(char file_name[],char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"rb");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       unsigned char *hello;
-       hello = (unsigned char*) malloc (size_fp_in);
-       fread(hello,size_fp_in,1,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashStringMode(char Msg[],char MsgDigest[])
-{
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) Msg,sizeof(Msg),output);
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-       return 1;
-}
-
-/*
- *  return 1 : is File
- *  return 2 : is Directory
- *  return -1 : Something else.
- */
-int isFile(char argument[])
-{
-       struct stat s;
-       if( stat(argument,&s) == 0 )
-       {
-           if( s.st_mode & S_IFDIR )
-           {
-               return 2;
-           }
-           else if( s.st_mode & S_IFREG )
-           {
-               return 1;
-           }
-       }
-       else
-               return -1;
-       return 0;
-}
-
-int isProper(char MsgDigest[])
-{
-       if ((strlen(MsgDigest) - hashbitlen/4) != 0)
-               return 0;
-       int index = 0;
-       char c = 0;
-       for(index = 0; index < strlen(MsgDigest);index++)
-       {
-               c = MsgDigest[index];
-               if(!(( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'F')))
-                       return 0;
-       }
-
-       return 1;
-}
-
-
-int decomposeHashLine(char hash[], char MsgDigest_tmp[], char file_tmp[])
-{
-       char c = 0;
-       int i = 0 , j =0;
-       int isTagFile = 0;
-       char alg[20];
-       char tmp[1000];
-       while(((c = hash[i])!=' ')&&((c = hash[i])!='_'))
-       {
-               tmp[i] = hash[i];
-               i++;
-       }
-       tmp[i] = 0;
-
-       sprintf(alg,"skein%d",hashbitlen);
-       if(!strcmp(alg,tmp))
-       {
-               isTagFile = 1;
-       }
-
-       if(isTagFile == 0)
-       {
-               strcpy(MsgDigest_tmp,tmp);
-               i++;
-               while((c = hash[i])!= '\n')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-       }
-       else if((hash[i]=='_')&&(hash[i+1]=='v'))
-       {
-               i = i + 2;
-               j = 0;
-               char version[5];
-               while((c = hash[i])!=' ')
-               {
-                       version[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               version[i] = 0;
-               float vers = 0, skeinVers = 0;
-               sscanf(version,"%f",&vers);
-               sscanf(skeinVersion,"%f",&skeinVers);
-
-               j = 0;
-               i = i + 2;
-               while((c = hash[i])!=')')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-
-               i = i + 4;
-               j = 0;
-               while((c = hash[i])!='\n')
-               {
-                       MsgDigest_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               MsgDigest_tmp[j] = 0;
-
-               if(skeinVers < vers)
-               {//version newer than mine
-                       return (-1);
-               }
-               else if (skeinVers > vers)
-               {//going to use older version than mine
-                       return (0) ;
-               }
-               else
-               { //versions match
-                       return (1);
-               }
-       }
-       return 1;
-
-}
-
-
-
-int main(int argc, char** argv)
-{
-       char MsgDigest[hashbitlen/2];
-       char **list_files = (char**) malloc(MaxNmberFiles* sizeof(char*));
-       int number_files = 0;
-       int binary = -1,
-                check = -1,
-                quiet = -1,
-                warn = -1,
-                status = -1,
-                help = -1,
-                version = -1,
-                tag = -1,
-                hashString = -1,
-                badParam = -1;
-
-       int errorFound = 0;
-       int opt = 0;
-/*****************************************************************************************
- ************************************* GETTING DATA ***********************************
- *****************************************************************************************/
-  while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
-  {
-         switch (opt)
-         {
-                       case 'b' :
-                       {
-                               binary = 1;
-                               break;
-                       }
-                       case 't' :
-                       {
-                               binary = 0;
-                               break;
-                       }
-                       case 'c' :
-                       {
-                               check = 1;
-                               break;
-                       }
-                       case QUIET_OPTION :
-                       {
-                               quiet = 1;
-                               break;
-                       }
-                       case 'w' :
-                       {
-                               warn = 1;
-                               break;
-                       }
-                       case STATUS_OPTION :
-                       {
-                               status = 1;
-                               break;
-                       }
-                       case HELP_OPTION :
-                       {
-                               help = 1;
-                               break;
-                       }
-                       case VERSION_OPTION :
-                       {
-                               version = 1;
-                               break;
-                       }
-                       case TAG_OPTION :
-                       {
-                               tag = 1;
-                               break;
-                       }
-                       case 0 :
-                       {
-                               hashString = 1;
-                               break;
-                       }
-                       default :
-                       {
-                               badParam = 1;
-                               break;
-                       }
-         }
-       }
-
-  if(badParam == 1)
-       {
-               printf("Try `skein%dsum --help' for more information.\n",hashbitlen);
-               exit(1);
-       }
-
-  for (; optind < argc; ++optind)
-  {
-               switch (opt)
-               {
-                       case -1:
-                       {// no options found, test if there is a file and hash it
-                               if(isFile(argv[optind]) == 1)
-                               {
-                                       char *file_name = malloc(sizeof(argv[optind]));
-                                       file_name = argv[optind];
-                                       list_files[number_files] = (char*) malloc (sizeof(file_name));
-                                       list_files[number_files] = file_name;
-                                       number_files ++;
-                               }
-                               else if (isFile(argv[optind]) == 2)
-                               {
-                                       printf("skein%dsum: %s Is a directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               break;
-                       }
-               }
-       }
-/*****************************************************************************************
- ************************************* PROCESSING DATA ***********************************
- *****************************************************************************************/
-       if(argc > 1 && version == 1)
-       {
-               printf("skein512sum 1.0\n");
-               printf("License GPLv3+: GNU GPL version 3 or later\n");
-               printf("<http://gnu.org/licenses/gpl.html>\n");
-               printf("This is free software: you are free to change and redistribute it.\n");
-               printf("There is NO WARRANTY, to the extent permitted by law.\n");
-               exit(1);
-       }
-       if(argc > 1 && help == 1)
-       {
-
-               printf("Usage: skein%dsum [OPTION]... [FILE]...\n",hashbitlen);
-               printf("Print or check skein (%d-bit) checksums.\n",hashbitlen);
-               printf("With no FILE, or when FILE is -, read standard input.\n");
-               printf("\n");
-               printf("-b, --binary         read in binary mode\n");
-               printf("-c, --check          read skein sums from the FILEs and check them\n");
-               printf("--tag            create a BSD-style checksum\n");
-               printf("-t, --text           read in text mode (default)\n");
-               printf("\n");
-               printf("The following three options are useful only when verifying checksums:\n");
-               printf("--quiet          don't print OK for each successfully verified file\n");
-               printf("--status         don't output anything, status code shows success\n");
-               printf("-w, --warn           warn about improperly formatted checksum lines\n");
-               printf("\n");
-               printf("--strict         with --check, exit non-zero for any invalid input\n");
-               printf("--help     display this help and exit\n");
-               printf("--version  output version information and exit\n");
-               printf("\n");
-               printf("The sums are computed as described in version 1.3 of the Skein\n");
-               printf("specification. When checking, the input should be a former output of\n");
-               printf("this program. The default mode is to print a line with checksum, a\n");
-               printf("character indicating input mode ('*' for binary, space for text), and\n");
-               printf("name for each FILE.\n");
-               exit(1);
-       }
-
-       if(argc > 1 && binary == 1)
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(hashString == 1)
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,list_files[index_files]);
-                                       index_files++;
-                                       continue;
-                               }
-                               if(HashBinaryMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("*%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s *-\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == 0) // Text Mode
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s -\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == -1)
-       {
-               if(check == -1)
-               {// hashing stdin entries
-                       if(quiet == 1 || status == 1 || warn == 1)
-                       {
-                               if(quiet == 1)
-                                       printf("skein%dsum: the --quiet option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(status ==1)
-                                       printf("skein%dsum: the --status option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(warn == 1)
-                                       printf("skein%dsum: the --warn option is meaningful only when verifying checksums\n",hashbitlen);
-
-                               printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                               exit(1);
-                       }
-                       if(number_files > 0)
-                       {// hashing files
-                               int index_files = 0;
-                               while(index_files < number_files)
-                               {
-                                       if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                                       {
-                                               if(tag == 1)
-                                               {
-                                                       printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                               }
-                                               else
-                                               {
-                                                       printf("%s ",MsgDigest);
-                                                       printf("%s\n",list_files[index_files]);
-                                               }
-                                       }
-                                       index_files++;
-                               }
-                       }
-                       else if(errorFound != 1)
-                       { // hasing strings read from  stdin
-                               char stri[100];
-                               char longstring[1000];
-                               longstring[0] = 0;
-                               while((fgets(stri,100,stdin))!=NULL)
-                               {
-                                       strcat(longstring,stri);
-                               }
-                               HashStringMode(longstring,MsgDigest);
-                               if(tag == 1)
-                               {
-                                       printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                               }
-                               else
-                               {
-                                       printf("%s -\n",MsgDigest);
-                               }
-                       }
-               }
-               else if(check == 1)
-               {
-                       if(tag == 1)
-                       {
-                               printf("skein%dsum: the --tag option is meaningless when verifying checksums\n",hashbitlen);
-                               printf("Try 'skein%dsum --help' for more information\n",hashbitlen);
-                               exit(1);
-                       }
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               FILE *fp;
-                               char hash[500], file_name[100], file_tmp[100], MsgDigest_tmp[hashbitlen/2];
-                               int NoMatch = 0, NotProper = 0, Computed = 0;
-                               strcpy(file_name,list_files[index_files]);
-                               //show everything
-                               int line = 0;
-                               fp = fopen(file_name,"r");
-                               if(fp!=NULL)
-                               {
-                                       while(fgets(hash,500,fp)!=NULL)
-                                       {
-                                               line ++;
-                                               Computed++;
-                                               unsigned int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp);
-                                               if(hashVersion == -1)
-                                               {
-                                                       printf("skein%d: %s is using newer version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should update your algorithm\n");
-                                                       continue;
-                                               }
-                                               else if( hashVersion == 0)
-                                               {
-                                                       printf("skein%d: %s is using an older version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should use the older algorithm\n");
-                                                       continue;
-                                               }
-                                               else
-                                               {
-                                                       if(!isProper(MsgDigest_tmp))
-                                                       {
-                                                               if(status != 1 && warn == 1)
-                                                               {
-                                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_tmp,line,hashbitlen);
-                                                               }
-                                                               NotProper ++;
-                                                               NoMatch ++;
-                                                               continue;
-                                                       }
-                                                       if(file_tmp[0] == '*')
-                                                       {
-                                                               int index_file_tmp = 0;
-                                                               for( ; file_tmp[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                                               {
-                                                                       file_tmp[index_file_tmp] = file_tmp[index_file_tmp + 1];
-                                                               }
-                                                               file_tmp[index_file_tmp] = 0;
-                                                               HashBinaryMode(file_tmp,MsgDigest);
-                                                       }
-                                                       else
-                                                       {
-                                                               HashTextMode(file_tmp,MsgDigest);
-                                                       }
-
-                                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                                       {
-                                                               if(quiet != 1)
-                                                               {
-                                                                       printf("%s: OK\n",file_tmp);
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               printf("%s: FAILED\n",file_tmp);
-                                                               NoMatch ++;
-                                                       }
-                                               }
-                                       }
-                                       if(NoMatch)
-                                       {
-                                               printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                               hashbitlen,NoMatch,Computed);
-                                       }
-                                       if(NotProper)
-                                       {
-                                               printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                                       }
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,file_name);
-                               }
-                               index_files++;
-
-                       }
-
-                       if(number_files  == 0)
-                       {
-                               char longstring[1000];
-                               char file_name[30];
-                               char MsgDigest_tmp[hashbitlen/2];
-                               int Computed = 0, NotProper = 0, NoMatch = 0 , line = 0;
-                               while((fgets(longstring,1000,stdin))!=NULL)
-                               {
-                                       Computed++;
-                                       line ++;
-                                       decomposeHashLine(longstring,MsgDigest_tmp,file_name);
-                                       if(!isProper(MsgDigest_tmp))
-                                       {
-                                               if(status != 1 && warn == 1)
-                                               {
-                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_name,line,hashbitlen);
-                                               }
-                                               NotProper ++;
-                                               NoMatch ++;
-                                               continue;
-                                       }
-                                       if(file_name[0] == '*')
-                                       {
-                                               int index_file_tmp = 0;
-                                               for( ; file_name[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                               {
-                                                       file_name[index_file_tmp] = file_name[index_file_tmp + 1];
-                                               }
-                                               file_name[index_file_tmp] = 0;
-                                               HashBinaryMode(file_name,MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               HashTextMode(file_name,MsgDigest);
-                                       }
-
-                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                       {
-                                               if(quiet != 1)
-                                               {
-                                                       printf("%s: OK\n",file_name);
-                                               }
-                                       }
-                                       else
-                                       {
-                                               printf("%s: FAILED\n",file_name);
-                                               NoMatch ++;
-                                       }
-                               }
-                               if(NoMatch)
-                               {
-                                       printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                       hashbitlen,NoMatch,Computed);
-                               }
-                               if(NotProper)
-                               {
-                                       printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                               }
-
-                       }
-
-
-               }
-       }
-
-       if ((errorFound != 1) && (argc == 1 || (hashString == 1 && number_files == 0)))
-       {
-               char stri[100];
-               char longstring[1000];
-               longstring[0] = 0;
-               while((fgets(stri,100,stdin))!=NULL)
-               {
-                               strcat(longstring,stri);
-               }
-               HashStringMode(longstring,MsgDigest);
-               printf("%s -\n",MsgDigest);
-       }
-
-       return 1;
-}
+const int hashbitlen = 512;
diff --git a/skein_cli.c b/skein_cli.c
new file mode 100644 (file)
index 0000000..bbe820c
--- /dev/null
@@ -0,0 +1,743 @@
+/* Copyright (C) 2014 2015 Jason Self <j@jxself.org>
+
+This file is part of skeinsum.
+
+skeinsum 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.
+
+skeinsum 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 skeinsum. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <getopt.h>
+#include <malloc.h>
+#include <math.h>
+#include <glob.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "SHA3api_ref.h"
+
+extern const int hashbitlen;
+
+#define MaxNmberFiles 10
+#define skeinVersion "1.3"
+const size_t input_minbufsize = 32 * 1024;
+const size_t input_maxbufsize = 32 * 1024 * 1024;
+
+
+char invalidOption = 0;
+
+enum
+{
+  QUIET_OPTION = 11,
+  STATUS_OPTION,
+  TAG_OPTION,
+  HELP_OPTION,
+  VERSION_OPTION
+};
+
+static struct option const long_options[] =
+{
+  { "binary", no_argument, NULL, 'b' },
+  { "check", no_argument, NULL, 'c' },
+  { "quiet", no_argument, NULL, QUIET_OPTION },
+  { "status", no_argument, NULL, STATUS_OPTION },
+  { "text", no_argument, NULL, 't' },
+  { "warn", no_argument, NULL, 'w' },
+  { "tag", no_argument, NULL, TAG_OPTION },
+  { "help", no_argument, NULL, HELP_OPTION },
+  { "version", no_argument, NULL, VERSION_OPTION },
+  { NULL, 0, NULL, 0 }
+};
+
+void printHexMsg(unsigned char *ptr, int size, char result[])
+{
+       int i = 0;
+       int j = 0;
+       char High, Low;
+       for (i = 0 ; i < size ; i ++)
+       {
+               High = ptr[i]>>4;
+               Low = ptr[i]&0x0F;
+
+               if (High >= 0xA && High <= 0xF)
+                       High += 0x37;
+               else if(High >= 0x0 && High <= 0x9)
+                       High += 0x30;
+
+               if (Low >= 0xA && Low <= 0xF)
+                       Low += 0x37;
+               else if(Low >= 0x0 && Low <= 0x9)
+                       Low += 0x30;
+
+               result[j++] = High;
+               result[j++] = Low;
+       }
+       result[i] = 0;
+}
+
+int HashWithMode(char file_name[], char MsgDigest[], char mode)
+{
+       /* Try to get file info */
+       struct stat st;
+       if (stat(file_name, &st) < 0) {
+               printf("skein%dsum: %s: STAT FAILED: %s\n", hashbitlen, file_name, strerror(errno));
+               return -1;
+       }
+
+       /* Get filesize */
+       size_t fsize = st.st_size;
+       if (fsize != st.st_size) {
+               printf("skein%dsum: %s: SIZE WARNING: filesize %llu is too big for reading into memory!\n",
+                       hashbitlen, file_name, (long long unsigned)st.st_size);
+       }
+
+       /* Open file */
+       FILE *fp_in = fopen(file_name, (mode == 't' ? "r" : "rb") );
+       if (!fp_in) {
+               printf("skein%dsum: %s: OPEN FAILED: %s\n", hashbitlen, file_name, strerror(errno));
+               return -1;
+       }
+
+       /* Allocate buffer */
+       size_t bufsize = fsize + 1;
+       if (bufsize < input_minbufsize)
+               bufsize = input_minbufsize;
+
+       char *readbuf = malloc (bufsize);
+       if (!readbuf && bufsize > input_maxbufsize) {  /* ..Try to get contents by smaller portions */
+               bufsize = input_maxbufsize;
+               readbuf = malloc (bufsize);
+       }
+
+       if (!readbuf) {
+               printf("skein%dsum: %s: MEM FAILED: %s\n", hashbitlen, file_name, strerror(errno));
+               fclose(fp_in);
+               return -1;
+       }
+
+       /* Read contents */
+       size_t readpos = 0, readed, total_readed = 0;
+
+       while (1) {
+               size_t maxread = bufsize - readpos;
+               readed = fread(readbuf, 1, maxread, fp_in);
+               if (readed > 0 && readed <= maxread)
+                       total_readed += readed;
+               if (readed != maxread)
+                       break;
+               if (getenv("SKEIN_DEBUG"))
+                       printf("DEBUG: bufsize=%u (0x%x), readpos=%u (0x%x), maxread=%u (0x%x), total=%u (0x%x)\n",
+                               bufsize, bufsize, readpos, readpos, maxread, maxread, total_readed, total_readed);
+               char *newbuf = NULL;
+               if (bufsize * 2 > bufsize)  /* ..check overflow */
+                       newbuf = realloc(readbuf, bufsize * 2);
+               if (!newbuf) {
+                       printf("skein%dsum: %s: MEM WARNING: %u bytes only readed from %llu\n",
+                               hashbitlen, file_name, total_readed, (long long unsigned)st.st_size);
+                       break;
+               }
+               readbuf = newbuf;
+               readpos += readed;
+               bufsize *= 2;
+       }
+
+       if (total_readed < st.st_size && total_readed < bufsize) {
+               printf("skein%dsum: %s: READ WARNING: filesize=%llu, readed=%u, %s\n",
+                       hashbitlen, file_name, (long long unsigned)st.st_size, total_readed, strerror(errno));
+       }
+
+       fclose(fp_in);
+
+       unsigned char output[hashbitlen/4];
+       Hash(hashbitlen, (unsigned char*) readbuf, total_readed, output);
+
+       free(readbuf);
+
+       printHexMsg(output,hashbitlen/4,MsgDigest);
+
+       return 1;
+}
+
+int HashTextMode(char file_name[], char MsgDigest[])
+{
+       return HashWithMode(file_name, MsgDigest, 't');
+}
+
+int HashBinaryMode(char file_name[], char MsgDigest[])
+{
+       return HashWithMode(file_name, MsgDigest, 'b');
+}
+
+int HashStringMode(char Msg[],char MsgDigest[])
+{
+       unsigned char output[hashbitlen/4];
+       Hash(hashbitlen,(unsigned char*) Msg,sizeof(Msg),output);
+       printHexMsg(output,hashbitlen/4,MsgDigest);
+       return 1;
+}
+
+int isProper(char MsgDigest[])
+{
+       if ((strlen(MsgDigest) - hashbitlen/4) != 0)
+               return 0;
+       int index = 0;
+       char c = 0;
+       for(index = 0; index < strlen(MsgDigest);index++)
+       {
+               c = MsgDigest[index];
+               if(!(( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'F')))
+                       return 0;
+       }
+
+       return 1;
+}
+
+
+int decomposeHashLine(char hash[], char MsgDigest_tmp[], char file_tmp[])
+{
+       char c = 0;
+       int i = 0 , j =0;
+       int isTagFile = 0;
+       char alg[20];
+       char tmp[1000];
+       while(((c = hash[i])!=' ')&&((c = hash[i])!='_'))
+       {
+               tmp[i] = hash[i];
+               i++;
+       }
+       tmp[i] = 0;
+
+       sprintf(alg,"skein%d",hashbitlen);
+       if(!strcmp(alg,tmp))
+       {
+               isTagFile = 1;
+       }
+
+       if(isTagFile == 0)
+       {
+               strcpy(MsgDigest_tmp,tmp);
+               i++;
+               while((c = hash[i])!= '\n')
+               {
+                       file_tmp[j] = hash[i];
+                       i++;
+                       j++;
+               }
+               file_tmp[j] = 0;
+       }
+       else if((hash[i]=='_')&&(hash[i+1]=='v'))
+       {
+               i = i + 2;
+               j = 0;
+               char version[5];
+               while((c = hash[i])!=' ')
+               {
+                       version[j] = hash[i];
+                       i++;
+                       j++;
+               }
+               version[i] = 0;
+               float vers = 0, skeinVers = 0;
+               sscanf(version,"%f",&vers);
+               sscanf(skeinVersion,"%f",&skeinVers);
+
+               j = 0;
+               i = i + 2;
+               while((c = hash[i])!=')')
+               {
+                       file_tmp[j] = hash[i];
+                       i++;
+                       j++;
+               }
+               file_tmp[j] = 0;
+
+               i = i + 4;
+               j = 0;
+               while((c = hash[i])!='\n')
+               {
+                       MsgDigest_tmp[j] = hash[i];
+                       i++;
+                       j++;
+               }
+               MsgDigest_tmp[j] = 0;
+
+               if(skeinVers < vers)
+               {//version newer than mine
+                       return (-1);
+               }
+               else if (skeinVers > vers)
+               {//going to use older version than mine
+                       return (0) ;
+               }
+               else
+               { //versions match
+                       return (1);
+               }
+       }
+       return 1;
+
+}
+
+void print_version(void)
+{
+       printf("skein%dsum 1.0\n", hashbitlen);
+       printf("License GPLv3+: GNU GPL version 3 or later\n");
+       printf("<http://gnu.org/licenses/gpl.html>\n");
+       printf("This is free software: you are free to change and redistribute it.\n");
+       printf("There is NO WARRANTY, to the extent permitted by law.\n");
+       exit(1);
+}
+
+void print_usage(void)
+{
+       printf("Usage: skein%dsum [OPTION]... [FILE]...\n",hashbitlen);
+       printf("Print or check skein (%d-bit) checksums.\n",hashbitlen);
+       printf("With no FILE, or when FILE is -, read standard input.\n");
+       printf("\n");
+       printf("-b, --binary         read in binary mode\n");
+       printf("-c, --check          read skein sums from the FILEs and check them\n");
+       printf("--tag            create a BSD-style checksum\n");
+       printf("-t, --text           read in text mode (default)\n");
+       printf("\n");
+       printf("The following three options are useful only when verifying checksums:\n");
+       printf("--quiet          don't print OK for each successfully verified file\n");
+       printf("--status         don't output anything, status code shows success\n");
+       printf("-w, --warn           warn about improperly formatted checksum lines\n");
+       printf("\n");
+       printf("--strict         with --check, exit non-zero for any invalid input\n");
+       printf("--help     display this help and exit\n");
+       printf("--version  output version information and exit\n");
+       printf("\n");
+       printf("The sums are computed as described in version 1.3 of the Skein\n");
+       printf("specification. When checking, the input should be a former output of\n");
+       printf("this program. The default mode is to print a line with checksum, a\n");
+       printf("character indicating input mode ('*' for binary, space for text), and\n");
+       printf("name for each FILE.\n");
+       exit(1);
+}
+
+
+
+int main(int argc, char** argv)
+{
+       char MsgDigest[hashbitlen/2];
+       char *list_files[MaxNmberFiles];
+       int number_files = 0;
+       int binary = -1,
+                check = -1,
+                quiet = -1,
+                warn = -1,
+                status = -1,
+                tag = -1,
+                hashString = -1;
+
+       int errorFound = 0;
+       int opt = 0;
+/*****************************************************************************************
+ ************************************* GETTING DATA ***********************************
+ *****************************************************************************************/
+       while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
+       {
+               switch (opt) {
+                       case 0              : hashString = 1;  break;
+                       case 'b'            : binary     = 1;  break;
+                       case 't'            : binary     = 0;  break;
+                       case 'c'            : check      = 1;  break;
+                       case 'w'            : warn       = 1;  break;
+                       case QUIET_OPTION   : quiet      = 1;  break;
+                       case STATUS_OPTION  : status     = 1;  break;
+                       case TAG_OPTION     : tag        = 1;  break;
+                       
+                       case HELP_OPTION    : print_usage();   /* ..never returns */
+                       case VERSION_OPTION : print_version(); /* ..never returns */
+
+                       default:
+                               printf("Try `skein%dsum --help' for more information.\n",hashbitlen);
+                               exit(1);
+               }
+       }
+
+       for (; optind < argc; ++optind)
+       {
+               struct stat s;
+               if (stat(argv[optind], &s) < 0)
+               {
+                       printf("skein%dsum: %s: no such file or directory\n", hashbitlen, argv[optind]);
+                       errorFound = 1;
+               }
+               else if (s.st_mode & (S_IFREG|S_IFBLK))  /* ..regular file or block device? */
+               {
+                       if (number_files < MaxNmberFiles) {
+                               list_files[number_files++] = argv[optind];
+                       } else {
+                               printf("skein%dsum: %s: ignore because filelist is too long\n",
+                                       hashbitlen, argv[optind]);
+                       }
+               }
+               else if (s.st_mode & S_IFDIR)
+               {
+                       printf("skein%dsum: %s: is a directory\n",hashbitlen,argv[optind]);
+                       errorFound = 1;
+               }
+               else
+               {
+                       printf("skein%dsum: %s: wrong filetype 0x%Xu\n",
+                               hashbitlen, argv[optind], s.st_mode);
+                               errorFound = 1;
+               }
+       }
+
+/*****************************************************************************************
+ ************************************* PROCESSING DATA ***********************************
+ *****************************************************************************************/
+       if(argc > 1 && binary == 1)
+       {
+               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
+               {
+                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
+                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
+                       exit(0);
+               }
+               if(number_files > 0)
+               {
+                       int index_files = 0;
+                       while(index_files < number_files)
+                       {
+                               if(hashString == 1)
+                               {
+                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,list_files[index_files]);
+                                       index_files++;
+                                       continue;
+                               }
+                               if(HashBinaryMode(list_files[index_files],MsgDigest)!=-1)
+                               {
+                                       if(tag == 1)
+                                       {
+                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
+                                       }
+                                       else
+                                       {
+                                               printf("%s ",MsgDigest);
+                                               printf("*%s\n",list_files[index_files]);
+                                       }
+                               }
+                               index_files++;
+                       }
+               }
+               else if(errorFound != 1)
+               { // read stdin for strings
+                       char stri[100];
+                       char longstring[1000];
+                       longstring[0] = 0;
+                       while((fgets(stri,100,stdin))!=NULL)
+                       {
+                               strcat(longstring,stri);
+                       }
+                       HashStringMode(longstring,MsgDigest);
+                       if(tag == 1)
+                       {
+                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
+                       }
+                       else
+                       {
+                               printf("%s *-\n",MsgDigest);
+                       }
+               }
+       }
+
+       else if (argc > 1 && binary == 0) // Text Mode
+       {
+               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
+               {
+                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
+                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
+                       exit(0);
+               }
+               if(number_files > 0)
+               {
+                       int index_files = 0;
+                       while(index_files < number_files)
+                       {
+                               if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
+                               {
+                                       if(tag == 1)
+                                       {
+                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
+                                       }
+                                       else
+                                       {
+                                               printf("%s ",MsgDigest);
+                                               printf("%s\n",list_files[index_files]);
+                                       }
+                               }
+                               index_files++;
+                       }
+               }
+               else if(errorFound != 1)
+               { // read stdin for strings
+                       char stri[100];
+                       char longstring[1000];
+                       longstring[0] = 0;
+                       while((fgets(stri,100,stdin))!=NULL)
+                       {
+                               strcat(longstring,stri);
+                       }
+                       HashStringMode(longstring,MsgDigest);
+                       if(tag == 1)
+                       {
+                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
+                       }
+                       else
+                       {
+                               printf("%s -\n",MsgDigest);
+                       }
+               }
+       }
+
+       else if (argc > 1 && binary == -1)
+       {
+               if(check == -1)
+               {// hashing stdin entries
+                       if(quiet == 1 || status == 1 || warn == 1)
+                       {
+                               if(quiet == 1)
+                                       printf("skein%dsum: the --quiet option is meaningful only when verifying checksums\n",hashbitlen);
+                               if(status ==1)
+                                       printf("skein%dsum: the --status option is meaningful only when verifying checksums\n",hashbitlen);
+                               if(warn == 1)
+                                       printf("skein%dsum: the --warn option is meaningful only when verifying checksums\n",hashbitlen);
+
+                               printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
+                               exit(1);
+                       }
+                       if(number_files > 0)
+                       {// hashing files
+                               int index_files = 0;
+                               while(index_files < number_files)
+                               {
+                                       if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
+                                       {
+                                               if(tag == 1)
+                                               {
+                                                       printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
+                                               }
+                                               else
+                                               {
+                                                       printf("%s ",MsgDigest);
+                                                       printf("%s\n",list_files[index_files]);
+                                               }
+                                       }
+                                       index_files++;
+                               }
+                       }
+                       else if(errorFound != 1)
+                       { // hasing strings read from  stdin
+                               char stri[100];
+                               char longstring[1000];   /* TODO!!! Fix buffer overflow!!! */
+                               longstring[0] = 0;
+                               while((fgets(stri,100,stdin))!=NULL)
+                               {
+                                       strcat(longstring,stri);
+                               }
+                               HashStringMode(longstring,MsgDigest);
+                               if(tag == 1)
+                               {
+                                       printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
+                               }
+                               else
+                               {
+                                       printf("%s -\n",MsgDigest);
+                               }
+                       }
+               }
+               else if(check == 1)
+               {
+                       if(tag == 1)
+                       {
+                               printf("skein%dsum: the --tag option is meaningless when verifying checksums\n",hashbitlen);
+                               printf("Try 'skein%dsum --help' for more information\n",hashbitlen);
+                               exit(1);
+                       }
+                       int index_files = 0;
+                       while(index_files < number_files)
+                       {
+                               FILE *fp;
+                               char hash[500], file_name[100], file_tmp[100], MsgDigest_tmp[hashbitlen/2];
+                               int NoMatch = 0, NotProper = 0, Computed = 0;
+                               strcpy(file_name,list_files[index_files]);
+                               //show everything
+                               int line = 0;
+                               fp = fopen(file_name,"r");
+                               if(fp!=NULL)
+                               {
+                                       while(fgets(hash,500,fp)!=NULL)
+                                       {
+                                               line ++;
+                                               Computed++;
+                                               unsigned int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp);
+                                               if(hashVersion == -1)
+                                               {
+                                                       printf("skein%d: %s is using newer version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
+                                                       printf("You should update your algorithm\n");
+                                                       continue;
+                                               }
+                                               else if( hashVersion == 0)
+                                               {
+                                                       printf("skein%d: %s is using an older version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
+                                                       printf("You should use the older algorithm\n");
+                                                       continue;
+                                               }
+                                               else
+                                               {
+                                                       if(!isProper(MsgDigest_tmp))
+                                                       {
+                                                               if(status != 1 && warn == 1)
+                                                               {
+                                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_tmp,line,hashbitlen);
+                                                               }
+                                                               NotProper ++;
+                                                               NoMatch ++;
+                                                               continue;
+                                                       }
+                                                       if(file_tmp[0] == '*')
+                                                       {
+                                                               int index_file_tmp = 0;
+                                                               for( ; file_tmp[index_file_tmp+1]!=0 ; index_file_tmp++)
+                                                               {
+                                                                       file_tmp[index_file_tmp] = file_tmp[index_file_tmp + 1];
+                                                               }
+                                                               file_tmp[index_file_tmp] = 0;
+                                                               HashBinaryMode(file_tmp,MsgDigest);
+                                                       }
+                                                       else
+                                                       {
+                                                               HashTextMode(file_tmp,MsgDigest);
+                                                       }
+
+                                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
+                                                       {
+                                                               if(quiet != 1)
+                                                               {
+                                                                       printf("%s: OK\n",file_tmp);
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               printf("%s: FAILED\n",file_tmp);
+                                                               NoMatch ++;
+                                                       }
+                                               }
+                                       }
+                                       if(NoMatch)
+                                       {
+                                               printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
+                                                               hashbitlen,NoMatch,Computed);
+                                       }
+                                       if(NotProper)
+                                       {
+                                               printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
+                                       }
+                               }
+                               else
+                               {
+                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,file_name);
+                               }
+                               index_files++;
+
+                       }
+
+                       if(number_files  == 0)
+                       {
+                               char longstring[1000];
+                               char file_name[30];
+                               char MsgDigest_tmp[hashbitlen/2];
+                               int Computed = 0, NotProper = 0, NoMatch = 0 , line = 0;
+                               while((fgets(longstring,1000,stdin))!=NULL)
+                               {
+                                       Computed++;
+                                       line ++;
+                                       decomposeHashLine(longstring,MsgDigest_tmp,file_name);
+                                       if(!isProper(MsgDigest_tmp))
+                                       {
+                                               if(status != 1 && warn == 1)
+                                               {
+                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_name,line,hashbitlen);
+                                               }
+                                               NotProper ++;
+                                               NoMatch ++;
+                                               continue;
+                                       }
+                                       if(file_name[0] == '*')
+                                       {
+                                               int index_file_tmp = 0;
+                                               for( ; file_name[index_file_tmp+1]!=0 ; index_file_tmp++)
+                                               {
+                                                       file_name[index_file_tmp] = file_name[index_file_tmp + 1];
+                                               }
+                                               file_name[index_file_tmp] = 0;
+                                               HashBinaryMode(file_name,MsgDigest);
+                                       }
+                                       else
+                                       {
+                                               HashTextMode(file_name,MsgDigest);
+                                       }
+
+                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
+                                       {
+                                               if(quiet != 1)
+                                               {
+                                                       printf("%s: OK\n",file_name);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               printf("%s: FAILED\n",file_name);
+                                               NoMatch ++;
+                                       }
+                               }
+                               if(NoMatch)
+                               {
+                                       printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
+                                                       hashbitlen,NoMatch,Computed);
+                               }
+                               if(NotProper)
+                               {
+                                       printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
+                               }
+
+                       }
+
+
+               }
+       }
+
+       if ((errorFound != 1) && (argc == 1 || (hashString == 1 && number_files == 0)))
+       {
+               char stri[100];
+               char longstring[1000];
+               longstring[0] = 0;
+               while((fgets(stri,100,stdin))!=NULL)
+               {
+                               strcat(longstring,stri);
+               }
+               HashStringMode(longstring,MsgDigest);
+               printf("%s -\n",MsgDigest);
+       }
+
+       return 1;
+}