#!/bin/sh
# Katalog by Maciej Korze <maciekk@linux.sky.pl>
# KATalogSearCH - look for expression in bases
# $Id: katsch,v 1.4 2002/06/28 19:18:58 eaquer Exp $
#
#    Copyright (C) 2001,2002  Maciej Korze
#
#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
# Default settings
data="/usr/share/katalog"
BOLD="\033[1;37m"
NORMAL="\033[0m"
verbose="off"
debug="off"
reverse="off"
desc_expr=""
case_sensitive="off"
compressed="on"

egrep_args="-i"

# Load settings
for i in /etc/katalogrc /usr/local/etc/katalogrc .katalogrc katalogrc $HOME/.katalogrc ; do         
	if [ -e $i ] ; then
		. $i
	fi
done

verbose() {
	if [ "$verbose" = "on" ] ; then
		echo $@
	fi
}

# Compressed file CAT
ccat() {
	type="`file $1 | cut -d ' ' -f 2`"
	case $type
	in
		gzip)
			cat $1 | gunzip
			;;
		bzip2)
			cat $1 | bunzip2
			;;
	esac
}

version() {
	echo "Katalog 1.8b"
}

usage() {
cat << EOF
Usage: katsch [-k dir] [-h] [-d] [-v] [-V] [-r] [-D string] [-i] [-o|-O] expression
	-k dir          'dir' is a dircetory with bases,
	-h		this help,
	-d		turn debug mode on,
	-v		verbose mode,
	-V		display version number,
	-r		display bases names as
				'file_name (Description of base)',
	-D string	search only in bases whose descriptions matches
				'string',
	-i		case sensitive search,
        -o              search also in contents of compressed files,
        -O              don't search in contents of compressed files,
	expression	regular expression to search for in bases.
EOF
}

find_filter() {
	sed 's/^.\///' | egrep -v '(^ *$|^./$|^.$)' | sort
}

check_arg() {
        if [ "$2" != "on" -a "$2" != "off" ] ; then
                echo "$1 - bad value: $2."
                exit 1
        fi
}

is_empty() {
        if [ -z "$2" ] ; then
                echo "Argument for $1 needed, see 'katadd -h'."
                exit 1
        fi
}

check_arg verbose "$verbose"
check_arg debug "$debug"
check_arg reverse "$reverse"
check_arg compressed "$compressed"
check_arg case_sensitive "$case_sensitive"

while [ "$#" -gt 0 ] ; do
	case $1 in
		-k)
			is_empty "-k" "$2"
			data="$2"
			shift 2
			;;
		-h)
			usage
			exit 0
			;;
		-d)
			debug=on
			shift
			;;
		-v)
			verbose=on
			shift
			;;
		-V)
			version
			exit 0
			;;
		-r)
			reverse=on
			shift
			;;
		-D)
			is_empty "-D" "$2"
			desc_expr="$2"
			shift 2
			;;
		-i)
			case_sensitive="on"
			shift
			;;
                -o)
                        compressed=on
                        shift
                        ;;
                -O)
                        compressed=off
                        shift
                        ;;
		*)
			if [ "x$expression" = "x" ] ; then
				expression="$1"
				shift
				continue
			fi
			usage
			exit 0
			;;
	esac
done

if [ "$debug" = "on" ] ; then
	verbose "Turning debug on."
	set -x
fi

if [ "x$desc_expr" != "x" ] ; then
	verbose "Search only in bases whose descriptions matches '$desc_expr'."
fi

if [ "$case_sensitive" = "on" ] ; then
	verbose "Case sensitive search."
	egrep_args=""
fi

if [ "x$expression" = "x" ] ; then
	verbose "Expression not given."
	usage
	exit 1
fi

if [ "$reverse" = "on" ] ; then
	verbose "Reverse mode is on."
fi

if [ "$compressed" = "on" ] ; then
	verbose "Searching in compressed files contents enabled."
fi

verbose "Expression is '$expression'."

if [ ! -d "$data" ]
then
	echo "Data dir '$data' doesn't exist!"
	exit 1
fi

verbose "Data dir is '$data'."

cd "$data"

if [ -z "`find ./ | find_filter`" ]
then
	echo "You don't have any databases in $data!"
	exit 1
fi

all_bases="`find ./ ! -name '*.dsc' | find_filter`"

if [ "x$desc_expr" = "x" ] ; then
	search_in="$all_bases"
	verbose "Searching in all bases."
else
	for i in $all_bases ; do
		if [ "x`cat $i.dsc | egrep $egrep_args -- "$desc_expr"`" != "x" ] ; then
			search_in="$search_in $i"
		fi
	done
	if [ "x$search_in" = "x" ] ; then
		echo "No bases to search in."
		exit 1
	fi
	verbose "Searching in bases: $search_in."
fi

verbose "Searching..."

for base in $search_in
do
	if [ "$compressed" = "on" ] ; then
		inbase="`ccat $base | egrep $egrep_args -- $expression`"
	else
		inbase="`ccat $base | egrep $egrep_args -- $expression | egrep -v '#'`"
	fi

	if [ -n "$inbase" ]; then
	desc="`cat $data/$base.dsc`"
	if [ "$reverse" = "on" ] ; then
		echo -e "${BOLD}$base${NORMAL} ($desc):"
	else
		echo -e "${BOLD}${desc}${NORMAL}:"
	fi
	echo "$inbase" | sed 's/^/  /'
	anything_found=yes
	fi
done

if [ "$anything_found" != "yes" ]
then
	verbose "Nothing found."
	exit 1
fi
