#!/bin/sh

#### Define Variables ####
debug=0
verbose=0

srcdir=`dirname "$0"`
tempfoo=`basename "$0"`
tempfile1=`mktemp .${tempfoo}.XXXXXX` || exit 1
tempfile2=`mktemp .${tempfoo}.XXXXXX` || exit 1

Prefix=/usr/local
ClamavPrefix=/usr/local
UsingClamd=0
ClamdRestartCommand='[qw(/etc/rc.d/init.d/clamd restart)]'
UsingFreshclam=0
FreshclamRestartCommand='[qw(/etc/rc.d/init.d/freshclam restart)]'
ClamavDownloadFrom=http://jaist.dl.sourceforge.net/sourceforge/clamav
DownloadFrom=http://osdn.dl.sourceforge.jp/clamav-update
AdminGroup=root


#### Check Source Directory ####
if [ -f "$srcdir/clamav-update.pl" -a -x "$srcdir/clamav-update.pl" -a -f "$srcdir/clamav-update-update.conf" -a -f "$srcdir/template/clamav-update.conf" ]; then
	true
else
	cat <<EOF 1>&2
This directory ($srcdir) is not clamav-update directory. Or This directory is broken.

Download again the archive file and try.
EOF
	exit 2
fi


#### Define Functions ####
usage () {
	cat <<EOF
Usage: $srcdir/install.sh [OPTION ...]

Known values for OPTION are:
    --prefix=DIR
        Change clamav-update prefix.
        Don't use / as DIR. It must be a absolute path.
        default: $Prefix
    --clamav-prefix=DIR
        Change ClamAV prefix. It must be a absolute path.
        default: $ClamavPrefix
    --clamd
        Declare that you are using clamd.
    --clamd-restart=COMMAND
        Change clamd restart command.
        default: $ClamdRestartCommand
    --freshclam
        Declare that you are using freshclam as a daemon.
    --freshclam-restart=COMMAND
        Change freshclam as a daemon restart command.
        default: $FreshclamRestartCommand
    --clamav-download-from=URL
    	Change base URL of ClamAV source archive file.
    	default: $ClamavDownloadFrom
    	Following URLs are avairable
            http://jaist.dl.sourceforge.net/sourceforge/clamav
                Asia: Ishikawa, Japan
            http://nchc.dl.sourceforge.net/sourceforge/clamav
                Asia: Tainan, Taiwan
            http://optusnet.dl.sourceforge.net/sourceforge/clamav
                Australia: Sydney, Australia
            http://surfnet.dl.sourceforge.net/sourceforge/clamav
                Europe: Amsterdam, The Netherlands
            http://belnet.dl.sourceforge.net/sourceforge/clamav
                Europe: Brussels, Belgium
            http://heanet.dl.sourceforge.net/sourceforge/clamav
                Europe: Dublin, Ireland
            http://mesh.dl.sourceforge.net/sourceforge/clamav
                Europe: Duesseldorf, Germany
            http://kent.dl.sourceforge.net/sourceforge/clamav
                Europe: Kent, UK
            http://switch.dl.sourceforge.net/sourceforge/clamav
                Europe: Lausanne, Switzerland
            http://ovh.dl.sourceforge.net/sourceforge/clamav
                Europe: Paris, France
            http://superb-east.dl.sourceforge.net/sourceforge/clamav
                North America: McLean, Virginia
            http://umn.dl.sourceforge.net/sourceforge/clamav
                North America: Minneapolis, MN
            http://easynews.dl.sourceforge.net/sourceforge/clamav
                North America: Phoenix, AZ
            http://superb-west.dl.sourceforge.net/sourceforge/clamav
                North America: Seattle, Washington
            http://ufpr.dl.sourceforge.net/sourceforge/clamav
                South America: Curitiba, Brazil
    --download-from=URL
    	Change base URL of clamav-update archive file.
    	default: $DownloadFrom
    	Following URLs are avairable
            'http://osdn.dl.sourceforge.jp/clamav-update'
                Tokyo Japan: OSDN Japan
            'http://keihanna.dl.sourceforge.jp/clamav-update'
                Keihanna Japan: Kansai Science City Internet Community
            'http://qgpop.dl.sourceforge.jp/clamav-update'
                Fukuoka Japan: Kyushu GigaPOP Project
    --admin-group=NAME
        Change administrator UNIX group.
        default: root
    --verbose
        Run as verbose mode.
        In verbose mode, this script displays what executed.
    --help
        Display this help and exit
    --version
        Output clamav-update version information and exit
EOF

	exit $1
}

clamavPhaseSpecifier () {
	if [ $UsingClamd -eq 0 ]; then
		if [ $UsingFreshclam -eq 0 ]; then
			if [ "$ClamavPrefix" == '/usr/local/clamXav' ]; then
				#### !clamd & !freshclam & ClamXav ####
				cat <<EOF
#\$Setting{phase}->{specifier} = \&PhaseSpecifier4ClamAV4ClamXav;
#   If you want to customize phase specification, use following instead of
#   above.
#\$Setting{phase}->{specifier} = sub {
#   # use build-in specifier
#   PhaseSpecifier4ClamAV4ClamXav();
#
#   # If you use clamd, uncomment following lines.
#   #push @{\$Phase{install}->{method}}, (
#   #    $ClamdRestartCommand,
#   #);
#
#   # If you use freshclam as a daemon, uncomment following lines.
#   #push @{\$Phase{install}->{method}}, (
#   #    [qw(chown root /usr/local/clamXav/bin/freshclam)],
#   #    [qw(chmod u-s /usr/local/clamXav/bin/freshclam)],
#   #    $FreshclamRestartCommand,
#   #);
#
#   # other customization
#
#   # return success
#   1;
#};
EOF
			elif [ "$ClamavPrefix" == '/usr/local' ]; then
				#### !clamd & !freshclam & normal ClamAV ####
				cat <<EOF
\$Setting{phase}->{specifier} = \&PhaseSpecifier4General;
#   If you want to customize phase specification, use following instead of
#   above.
#\$Setting{phase}->{specifier} = sub {
#   # use build-in specifier
#   PhaseSpecifier4General();
#
#   # If you use clamd, uncomment following lines.
#   #push @{\$Phase{install}->{method}}, (
#   #    [qw(/etc/rc.d/init.d/clamd restart)],
#   #);
#
#   # If you use freshclam as a daemon, uncomment following lines.
#   #push @{\$Phase{install}->{method}}, (
#   #    [qw(/etc/rc.d/init.d/freshclam restart)],
#   #);
#
#   # other customization
#
#   # return success
#   1;
#};
EOF
			else
				#### !clamd & !freshclam & ClamAV with prefix ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    # If you use clamd, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(/etc/rc.d/init.d/clamd restart)],
    #);

    # If you use freshclam as a daemon, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(/etc/rc.d/init.d/freshclam restart)],
    #);

    # other customization
    \$Phase{build}->{method} = [
        ['./configure', "--prefix=$ClamavPrefix"],
        [qw(make)],
    ];

    # return success
    1;
};
EOF
			fi
		else
			if [ "$ClamavPrefix" == '/usr/local/clamXav' ]; then
				#### !clamd & freshclam & ClamXav ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4ClamAV4ClamXav();

    # If you use clamd, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    $ClamdRestartCommand,
    #);

    push @{\$Phase{install}->{method}}, (
        [qw(chown root /usr/local/clamXav/bin/freshclam)],
        [qw(chmod u-s /usr/local/clamXav/bin/freshclam)],
        $FreshclamRestartCommand,
    );

    # other customization

    # return success
    1;
};
EOF
			elif [ "$ClamavPrefix" == '/usr/local' ]; then
				#### !clamd & freshclam & normal ClamAV ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    # If you use clamd, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(/etc/rc.d/init.d/clamd restart)],
    #);

    push @{\$Phase{install}->{method}}, (
        $FreshclamRestartCommand,
    );

    # other customization

    # return success
    1;
};
EOF
			else
				#### !clamd & freshclam & ClamAV with prefix ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    # If you use clamd, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(/etc/rc.d/init.d/clamd restart)],
    #);

    push @{\$Phase{install}->{method}}, (
        $FreshclamRestartCommand,
    );

    # other customization
    \$Phase{build}->{method} = [
        ['./configure', "--prefix=$ClamavPrefix"],
        [qw(make)],
    ];

    # return success
    1;
};
EOF
			fi
		fi
	else
		if [ $UsingFreshclam -eq 0 ]; then
			if [ "$ClamavPrefix" == '/usr/local/clamXav' ]; then
				#### clamd & !freshclam & ClamXav ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4ClamAV4ClamXav();

    push @{\$Phase{install}->{method}}, (
        $ClamdRestartCommand,
    );

    # If you use freshclam as a daemon, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(chown root /usr/local/clamXav/bin/freshclam)],
    #    [qw(chmod u-s /usr/local/clamXav/bin/freshclam)],
    #    $FreshclamRestartCommand,
    #);

    # other customization

    # return success
    1;
};
EOF
			elif [ "$ClamavPrefix" == '/usr/local' ]; then
				#### clamd & !freshclam & normal ClamAV ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    push @{\$Phase{install}->{method}}, (
        $ClamdRestartCommand,
    );

    # If you use freshclam as a daemon, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(/etc/rc.d/init.d/freshclam restart)],
    #);

    # other customization

    # return success
    1;
};
EOF
			else
				#### clamd & !freshclam & ClamAV with prefix ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    push @{\$Phase{install}->{method}}, (
        $ClamdRestartCommand,
    );

    # If you use freshclam as a daemon, uncomment following lines.
    #push @{\$Phase{install}->{method}}, (
    #    [qw(/etc/rc.d/init.d/freshclam restart)],
    #);

    # other customization
    \$Phase{build}->{method} = [
        ['./configure', "--prefix=$ClamavPrefix"],
        [qw(make)],
    ];

    # return success
    1;
};
EOF
			fi
		else
			if [ "$ClamavPrefix" == '/usr/local/clamXav' ]; then
				#### clamd & freshclam & ClamXav ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4ClamAV4ClamXav();

    push @{\$Phase{install}->{method}}, (
        $ClamdRestartCommand,
    );

    push @{\$Phase{install}->{method}}, (
        [qw(chown root /usr/local/clamXav/bin/freshclam)],
        [qw(chmod u-s /usr/local/clamXav/bin/freshclam)],
        $FreshclamRestartCommand,
    );

    # other customization

    # return success
    1;
};
EOF
			elif [ "$ClamavPrefix" == '/usr/local' ]; then
				#### clamd & freshclam & normal ClamAV ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    push @{\$Phase{install}->{method}}, (
        $ClamdRestartCommand,
    );

    push @{\$Phase{install}->{method}}, (
        $FreshclamRestartCommand,
    );

    # other customization

    # return success
    1;
};
EOF
			else
				#### clamd & freshclam & ClamAV with prefix ####
				cat <<EOF
\$Setting{phase}->{specifier} = sub {
    # use build-in specifier
    PhaseSpecifier4General();

    push @{\$Phase{install}->{method}}, (
        $ClamdRestartCommand,
    );

    push @{\$Phase{install}->{method}}, (
        $FreshclamRestartCommand,
    );

    # other customization
    \$Phase{build}->{method} = [
        ['./configure', "--prefix=$ClamavPrefix"],
        [qw(make)],
    ];

    # return success
    1;
};
EOF
			fi
		fi
	fi
}

normalizeDir () {
	cat <<EOF | head -1 | sed 's/^ //;s/\/\/*/\//g;s/\/$//'
 $1
EOF
}


#### Arguments Processing ####
while test $# -gt 0; do
	case "$1" in
	-*=*)
		optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
		;;
	*)
		optarg=
		;;
	esac

	case "$1" in
	--prefix=*)
		Prefix="$optarg"
		;;
	--clamav-prefix=*)
		ClamavPrefix="$optarg"
		;;
	--clamd)
		UsingClamd=1
		;;
	--clamd-restart=*)
		ClamdRestartCommand="$optarg"
		;;
	--freshclam)
		UsingFreshclam=1
		;;
	--freshclam-restart=*)
		FreshclamRestartCommand="$optarg"
		;;
	--clamav-download-from=*)
		ClamavDownloadFrom="$optarg"
		;;
	--download-from=*)
		DownloadFrom="$optarg"
		;;
	--admin-group=*)
		AdminGroup="$optarg"
		;;
	--verbose)
		verbose=1
		;;
	--help)
		usage 0
		;;
	--version)
		$srcdir/clamav-update.pl --version
		exit 0
		;;
	*)
		cat <<EOF >&2
Unknown option: $1

EOF
		usage 1
		;;
	esac

	shift
done

if [ $debug -gt 0 ]; then
	verbose=1
fi

if [ $verbose -gt 0 ]; then
	cat <<EOF
---- Variables ----
preifx: $Prefix
clamavPrefix: $ClamavPrefix
UsingClamd: $UsingClamd
ClamdRestartCommand: $ClamdRestartCommand
UsingFreshclam: $UsingFreshclam
FreshclamRestartCommand: $FreshclamRestartCommand
ClamavDownloadFrom: $ClamavDownloadFrom
DownloadFrom: $DownloadFrom
AdminGroup: $AdminGroup

EOF
fi


#### Paramaters Check ####
if expr "$Prefix" : '/.*' > /dev/null; then
	Prefix=`normalizeDir "$Prefix"`
else
	echo "Use absolute path for --prefix option: $Prefix" 1>&2
	exit 3
fi
if [ "$Prefix" == '' ]; then
	echo "Don't use --prefix=/" 1>&2
	exit 3
elif [ \! -d "$Prefix/" ]; then
	echo "No such directory: $Prefix/" 1>&2
	exit 3
elif [ \! \( -d "$Prefix/bin" -a -d "$Prefix/etc" \) ]; then
	echo "No bin/ or etc/ under $Prefix/" 1>&2
	exit 3
fi

if expr "$ClamavPrefix" : '/.*' > /dev/null; then
	ClamavPrefix=`normalizeDir "$Prefix"`
else
	echo "Use absolute path for --clamav-prefix option: $ClamavPrefix" 1>&2
	exit 3
fi
if [ \! -d "$ClamavPrefix/" ]; then
	echo "No such directory: $ClamavPrefix/" 1>&2
	exit 3
elif [ \! \( -d "$ClamavPrefix/bin" -a -d "$ClamavPrefix/etc" \) ]; then
	echo "No bin/ or etc/ under $ClamavPrefix/" 1>&2
	exit 3
fi

regClamavPrefix=`echo "$ClamavPrefix" | sed 's/\//\\\\\//g'`
regPrefix=`echo "$Prefix" | sed 's/\//\\\\\//g'`
regClamavDownloadFrom=`echo "$ClamavDownloadFrom" | sed 's/\//\\\\\//g'`
regDownloadFrom=`echo "$DownloadFrom" | sed 's/\//\\\\\//g'`
qtPrefix=`echo "$Prefix" | sed "s/'/\\\\\'/g"`

if [ $debug -gt 0 ]; then
	cat <<EOF
regClamavPrefix: $regClamavPrefix
regPrefix: $regPrefix
regClamavDownloadFrom: $regClamavDownloadFrom
regDownloadFrom: $regDownloadFrom
qtPrefix: $qtPrefix

EOF
fi


#### Install ####
if [ $verbose -gt 0 ]; then
	echo '---- Execute ----'
fi
rm -f "$tempfile1" "$tempfile2"

#--- Install /etc/clamav-update-update.conf ---#
if [ "$Prefix" != '/usr/local/clamXav' ]; then
	if [ $Prefix == '/' -o $Prefix == '/usr' ]; then
		echo "\$Setting{environment}->{PATH} = '/bin:/sbin:/usr/bin:/usr/sbin';" >> "$tempfile1"
	else
		echo "\$Setting{environment}->{PATH} = '/bin:/sbin:/usr/bin:/usr/sbin:$qtPrefix/bin';" >> "$tempfile1"
	fi
	if [ "$Prefix" == '/usr/local' ]; then
		echo "\$Setting{phase}->{specifier} = \&PhaseSpecifier4ClamavUpdate;" >> "$tempfile1"
	else
		cat <<EOF >> "$tempfile1"
\$Setting{phase}->{specifier} = sub {
	PhaseSpecifier4ClamAV4ClamXav();

	\$Phase{install}->{method} = [
		[qw(install -bp -o root -g root -m 0755 clamav-update.pl),
			'$qtPrefix/bin/clamav-update.pl'
		)],
		[qw(install -bp -o root -g root -m 0664 clamav-update-update.conf),
			'$qtPrefix/etc/clamav-update-update.conf'
		)],
	];

	1;
};
EOF
	fi
fi
if [ "$DownloadFrom" != 'http://osdn.dl.sourceforge.jp/clamav-update' ]; then
	echo "\$Setting{option}->{src} = '$DownloadFrom';" >> "$tempfile1"
fi

if [ -f "$tempfile1" ]; then
	echo '1;' >> "$tempfile1"

	if [ \! -d /etc ]; then
		echo "No such directory: /etc" 1>&2
		rm "$tempfile1"
		exit 4
	fi

	if [ $verbose -gt 0 ]; then
		echo "install -bp -o root -g \"$AdminGroup\" -m 0664 \"$tempfile1\" \"/etc/clamav-update-update.conf\""
	fi
	if [ $debug -gt 0 ]; then
		view "$tempfile1"
	else
		install -bp -o root -g "$AdminGroup" -m 0664 "$tempfile1" "/etc/clamav-update-update.conf"
	fi
	rm "$tempfile1"
fi

#--- Install clamav-update.pl ---#
if [ $verbose -gt 0 ]; then
	echo "install -bp -o root -g \"$AdminGroup\" -m 0755 \"$srcdir/clamav-update.pl\" \"$Prefix/bin/clamav-update.pl\""
fi
if [ $debug -eq 0 ]; then
	install -bp -o root -g "$AdminGroup" -m 0755 "$srcdir/clamav-update.pl" "$Prefix/bin/clamav-update.pl"
fi

#--- Install clamav-update.conf ---#
cat "$srcdir/template/clamav-update.conf" \
| (
	if [ "$ClamavPrefix" == '/usr/local/clamXav' ]; then
		sed "s/%Path%/#\$Setting{environment}->{PATH} = '\/bin:\/sbin:\/usr\/bin:\/usr\/sbin:\/usr\/local\/clamXav\/bin';/g"
	elif [ "$ClamavPrefix" == '/' -o "$ClamavPrefix" == '/usr' ]; then
		sed "s/%Path%/\$Setting{environment}->{PATH} = '\/bin:\/sbin:\/usr\/bin:\/usr\/sbin';/g"
	else
		sed "s/%Path%/\$Setting{environment}->{PATH} = '\/bin:\/sbin:\/usr\/bin:\/usr\/sbin:$regClamavPrefix\/bin';/g"
	fi
) \
| (
	if [ "$ClamavDownloadFrom" == 'http://jaist.dl.sourceforge.net/sourceforge/clamav' ]; then
		sed "s/%DownloadFrom%/#\$Setting{option}->{src} = 'http:\/\/jaist.dl.sourceforge.net\/sourceforge\/clamav';/g"
	else
		sed "s/%DownloadFrom%/\$Setting{option}->{src} = '$regClamavDownloadFrom';/g"
	fi
) \
> "$tempfile1"

while fgrep '%PhaseSpecfier%' "$tempfile1" > /dev/null 2>&1; do
	cat "$tempfile1" \
	| awk -F '%PhaseSpecfier%' '1 < NF { if ($1 != "") { print $1; } exit; } { print $0; }' \
	> "$tempfile2"

	clamavPhaseSpecifier >> "$tempfile2"

	cat "$tempfile1" \
	| awk -F '%PhaseSpecfier%' 'BEGIN { out = 0; } out == 0 && 1 < NF { $0 = $2; for (i = 3; i < NF; i++) { $0 = sprintf("%s%%PhaseSpecfier%%%s", $0, $i); } out = 1; } out == 1' \
	>> "$tempfile2"

	mv "$tempfile2" "$tempfile1"
done

if [ $verbose -gt 0 ]; then
	echo "install -bp -o root -g \"$AdminGroup\" -m 0664 \"$tempfile1\" \"$Prefix/etc/clamav-update.conf\""
fi
if [ $debug -gt 0 ]; then
	view "$tempfile1"
else
	install -bp -o root -g "$AdminGroup" -m 0664 "$tempfile1" "$Prefix/etc/clamav-update.conf"
fi
rm "$tempfile1"

#--- Install clamav-update-update.conf ---#
if [ $verbose -gt 0 ]; then
	echo "install -bp -o root -g \"$AdminGroup\" -m 0664 \"$srcdir/clamav-update-update.conf\" \"$Prefix/etc/clamav-update-update.conf\""
fi
if [ $debug -eq 0 ]; then
	install -bp -o root -g "$AdminGroup" -m 0664 "$srcdir/clamav-update-update.conf" "$Prefix/etc/clamav-update-update.conf"
fi
