#! /bin/sh

#
# archives-find                                                 (jh,12.06.2004)
#

#
#   archives-find: find files by filename or by md5sum in a file archives
#   Copyright (C) 2003-2004  Jochen Hepp <jochen.hepp@gmx.de>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

script="${0##*/}"
date="12.06.2004"
version="0.0.3"

rcfile="$HOME/.${script}rc"
rc="~/.${script}rc"



# --------- usage ---------

print_usage () {
	cat <<-EOF
Usage: $script [-n|-f|-g] NAME ...

       NAME              filename or part of filename to find in archives
       -n  --name        search file by name
       -f  --file        search file by md5sum of an existing file
       -g  --generate    generate new md5sum list of directory NAME
       -V  --version     display version number
       -h  --help        display this help and exit
EOF
}



# --------- version ---------

print_version () {
	cat <<-EOF
		$script $version

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

		Written by Jochen Hepp <jochen.hepp@gmx.de>.
EOF
}



# --------- search ---------

search () { # pattern   global: rc
	local pattern="$1"
	local line

	# input format: path_to_list|path_to_dir

	# sed input format: RELATIVE_PATH_TO_LIST.md5sum:MD5SUM  PATH_TO_FILE

	while read line; do
		if [ -f "$line" ]; then
			grep -Hi "$pattern" "$line" | \
			sed "s!^${line%/*}/!!"
		elif [ -d "$line" ]; then
			grep -Hri "$pattern" "$line" | \
			sed "s!^${line%/}/!!"
		else
			echo "$script: $rc: $line: no such file or directory" >&2
		fi
	done | \
	sed 's/\.md5sum:/:/; s/:[0-9a-fA-F][0-9a-fA-F]*/:/; s%:.*/%: %'
}



# --------- main ---------

# main {
	byname=
	byhash=
	count=0
	generate=
	file=
	pattern=

	while [ $# -gt 0 ] && [ "${1#-}" != "$1" ]; do
		case "$1" in
			--version|-V)
				print_version
				exit 0
				;;
			--help|-h)
				print_usage
				exit 0
				;;
			--name|-n)
				byname=yes
				count="$(($count+1))"
				;;
			--file|-f)
				byhash=yes
				count="$(($count+1))"
				;;
			--generate|-g)
				generate=yes
				count="$(($count+1))"
				;;
			*)
				echo "$script: unrecognized option \`$1'" >&2
				echo "$script: Try \`$script --help' for more information." >&2
				exit 1
				;;
		esac
		shift
	done

	if [ "$count" -gt 1 ]; then
		echo "$script: You may not specify more than one \`-nfg' option" >&2
		echo "Try \`$script --help' for more information." >&2
		exit 1
	fi

	if [ $# -le 0 ]; then
		print_usage >&2
		exit 1
	fi

	if [ "$generate" ]; then	
		while [ $# -gt 0 ]; do
			( cd "$1" && find . -type f -print0 | xargs --null md5sum )
			shift
		done
	else
		if [ ! -f "$rcfile" ]; then
			echo "$script: $rc: no such file" >&2
			exit 1
		fi
		if ! grep -c -v -e '^$' -e '^#' "$rcfile" >/dev/null; then
			echo "$script: $rc: no file or directory entries found" >&2
			exit 1
		fi

		while [ $# -gt 0 ]; do
			file="$1"

			if [ "$byhash" -o \( ! "$byname" -a -r "$file" \) ]; then
				if [ ! -r "$file" ]; then
					echo "$script: $file: no such file" >&2
					exit 1
				fi
				pattern="^`md5sum \"$file\" | sed -n '1 { s/ .*$//; p; }'`"
			else
				pattern="`echo \"$file\" | sed 's%^^%/%'`"
			fi

			grep -v -e '^$' -e '^#' "$rcfile" | \
			search "$pattern"

			shift
		done
	fi

	exit 0
# }


# --- end ---

