#!/bin/bash
#
# Summary: Calculate MD5 checksums in current directory (and down).
#
# Usage: md5walk [-r] [-c]
#
# When used with the -r option, this script descends the directory tree from
# the current directory, computing (or checking) an MD5 checksum for every
# file in each directory along the way.  The checksums are saved in each
# directory in the file:
#
#   md5-checksums.txt
#
# When used with the -c option, the script creates the checksum files.
# When used without the -c option, the script validates the checksums.
#
# TODO: Should be rewritten and compiled in Python.

# Files
TMP_DIRS=$HOME/.dirlist
TMP_FILES=$HOME/.filelist
TMP_NULL=$HOME/.null
CHECKFILE=md5-checksums.txt

# Usage summary
SCRIPT=`basename $0`
usage="Usage: $SCRIPT [-r] [-c] \n
\040 -r\040 Recursive: Walk all directories (else check current directory only) \n
\040 -c\040 Create new checksum files (else check existing md5-checksum.txt files)"

# Scan for options
mode="check"
recursive="no"
while getopts cr? option; do
    case $option in
    r)
        recursive="yes"
        ;;
    c)
        mode="create"
        ;;
    \?)
        echo -e $usage 1>&2
        STATUS=1
        exit
        ;;
    esac
done
shift `expr $OPTIND - 1`

# Handle recursion
if [ "$recursive" == "yes" ] ; then
    find . -type d > $TMP_DIRS
else
    echo "." > $TMP_DIRS
fi

# For each directory (including current):
numdirs=$(wc $TMP_DIRS | awk '{print $1}')
for dline in `seq $numdirs` ; do

    # Go to directory
    dir=$(tail -n +$dline $TMP_DIRS | head -n 1)
    cd "$dir"
    echo "Folder:" $PWD

    # If creating checksum file:
    if [ "$mode" == "create" ] ; then

        # Look for regular files
        find . -maxdepth 1 -type f > $TMP_FILES
        numfiles=$(wc $TMP_FILES | awk '{print $1}')

        # If no regular files, back out and continue
        if [ "$numfiles" == "0" ] ; then 
            cd - > $TMP_NULL 2>&1
            continue
        fi

        # Create new checkfile
        rm -f $CHECKFILE
        touch $CHECKFILE

        # For each regular file in the directory:
        for fline in `seq $numfiles` ; do

            # Get filename
            file=$(tail -n +$fline $TMP_FILES | head -n 1)

            # Skip uninteresting files
            if [ "$file" == "./$CHECKFILE" ]       ; then continue; fi
            if [ "$file" == "./Thumbs.db" ]        ; then continue; fi
            if [ "$file" == "./ZbThumbnail.info" ] ; then continue; fi

            # Echo filename
            #echo "File: $dir"/"$file" 

            # Compute md5 checksum
            md5sum "$file" | tee --append $CHECKFILE

        done

    # Else verifying:
    else

        # If checkfile exists
        if [ -f $CHECKFILE ] ; then

            # Verify md5 checksum
            md5sum -c $CHECKFILE 
        fi
    fi

    # Return to starting directory
    cd - > $TMP_NULL 2>&1

done

