#!/bin/ksh -u
# Ensure that the PHP browscap is up to date from Gary Joel Keith's web site.
# See:
#	https://browsers.garykeith.com/downloads
# Author: Alain D D Williams  <addw@phcomp.co.uk> of Parliament Hill Computers, http://www.phcomp.co.uk.
# Copyright (C) the Author 2006, 2011, 2012, all rights reserved.
# SCCS: @(#)UpdateBrowsCap	1.17 06/20/12 16:42:13
# This program is released under the GPL, see: http://www.gnu.org/copyleft/gpl.html

# This script should be run once a week from cron.

PROGNAME=${0##*/}

# Where to get the date_last_updated and database files:
GaryKeithSite=http://browsers.garykeith.com
VersionCheckerURL=https://browsers.garykeith.com/versions/version-date.asp
BrowscapURL=$GaryKeithSite/stream.asp?PHP_BrowsCapINI


# Print a usage message
function Usage {
	(( $# > 0 )) && echo "$PROGNAME: $*" >&2 && ec=2 || ec=0

	sed -e 's/^^//' <<-!
	Ensure that the PHP browscap is up to date from Gary Joel Keith's web site.
	See: $GaryKeithSite
	Usage: $PROGNAME [-opts]
	-b file	Browsecap is file - ie not obtained from php
	-d	Do not restart the web server (default is to restart it)
	--force	Force a new download, even if it does not appear to have changed
	-k --insecure
	^	Turn off curl's verification of the HTTPS server certificate.
	-v	Verbose - normally this script does not generate any output.
	-x --help
	^	eXplain, Help message
	Version: 1.17 06/20/12, latest from: http://www.phcomp.co.uk/Packages/UpdateBrowsCap.html
	To test use options: -d -v -b $PWD/browscap.ini
	!
	exit $ec
}

# If in verbose mode echo a message, otherwise be silent
function Note {
	[[ $Verbose = y ]] && echo "$1"
	return 0
}

# Complain (1st argument) to stderr and exit a failure
# Prepend the message with the program name.
function Die {
	echo "$PROGNAME: $1" >&2
	exit 2
}

CurlInsecure=
CurlSilent=--silent
Verbose=n
RestartWebServer=y
force=n

# Long Options, value: 0 - no argument, 1 - required argument, 2 - optional argument
typeset -A LongOpts=([help]=0 [force]=0 [insecure]=0)
ShortOpts=:b:dkvx

# Parse options, recognise --options
while	[[ $# -ge $OPTIND ]] && eval opt=\$$OPTIND || break
	[[ $opt == - ]] && shift && break
	if [[ $opt == --?* ]]
	then	opt=${opt#--}
		shift

		# Argument to option ?
		[[ $opt == *=* ]] && OPTARG=${opt#*=} && opt=${opt%=$OPTARG} && hasArg=1 || typeset OPTARG= hasArg=0

		# Check if known option and if it has an argument if it must:
		if [[ -z ${LongOpts[$opt]:-} ]]
		then	OPTARG=$opt && opt='?'
		else	[[ $hasArg = 0 && ${LongOpts[$opt]} = 1 ]] && OPTARG=$opt && opt=:
			[[ $hasArg = 1 && ${LongOpts[$opt]} = 0 ]] && OPTARG=$opt && opt=::
		fi
		true # for the while

	else	getopts $ShortOpts opt
	fi
do	case "$opt" in
	b)	BrowscapFile=$OPTARG ;;
	d)	RestartWebServer=n ;;
	force)	force=y ;;
	k|insecure)
		CurlInsecure=--insecure ;;
	v)	CurlSilent=
		Verbose=y
		;;
	x|help)	Usage
		exit;;
	::)	Usage "Unexpected argument to option '$OPTARG'" ;;
	:)	Usage "Missing argument to option '$OPTARG'" ;;
	\?)	Usage "Unknown option '$OPTARG'" ;;
	*)	Usage "Internal program error, unrecognised argument '$opt'" ;;
	esac
done
shift $((OPTIND - 1))



# Where we put these on this machine, create:
# browscap.ini -- you need a line in your php.ini like: browscap = /var/lib/php/browscap.ini
# LastUpdated -- the date that Gary last updated Browscap

# Try to determine where this file is:
[[ -z ${BrowscapFile:-} ]] &&
	BrowscapFile=$( php -r 'print ini_get("browscap");' )
[[ -z ${BrowscapFile:-} ]] &&
	Die "Cannot find where the browscap file goes - aborting!"
Note "The browscap file is $BrowscapFile"

BrowscapDir=$( dirname $BrowscapFile )

[[ ! -w $BrowscapDir ]] &&
	Die "Cannot write to the browscap directory ($BrowscapDir) - aborting!"

cd /tmp || exit

trap "rm -f BrowscapUpdate$$ BrowscapNew$$" EXIT

Note "Get the date that browscap was last updated from $VersionCheckerURL"
curl $CurlInsecure $CurlSilent $VersionCheckerURL > BrowscapUpdate$$ ||
	Die "Attempt to get version $VersionCheckerURL failed: $?"

# Quick syntax check on what we got back, it changed once & I didn't notice,
# look for something like ''Fri, '' at the start of line:
grep -q '^[A-Z][a-z][a-z], ' BrowscapUpdate$$ ||
	Die "What I got from $VersionCheckerURL looks strange: $(<BrowscapUpdate$$)"

# If the same date as the last one already downloaded, nothing to do.
# Ignore dates if forcing:
[[ $force = n && -f $BrowscapDir/LastUpdated ]] && cmp -s BrowscapUpdate$$ $BrowscapDir/LastUpdated &&
	Note "Browscap has not been updated, last at: $(<$BrowscapDir/LastUpdated)" &&
	exit

# Download browscap:
Note "Download the browscap from $BrowscapURL"
curl $CurlInsecure $CurlSilent $BrowscapURL > BrowscapNew$$ ||
	Die "Attempt to get browscap $BrowscapURL failed: $?"

# check that the file is complete, there seems to be a \r at line end:
egrep -q '^\[\*\].?$' BrowscapNew$$ || Die "The Browscap file appears to be incomplete"

# OK, we seem to have it, update everything and restart apache
mv BrowscapNew$$ $BrowscapFile.new || Die "Move BrowscapNew$$ to $BrowscapFile.new failed"
chmod 644 $BrowscapFile.new
mv $BrowscapFile.new $BrowscapFile || Die "Move $BrowscapFile.new to $BrowscapFile failed"
mv BrowscapUpdate$$ $BrowscapDir/LastUpdated

if [[ $RestartWebServer = y ]]
then	# Restart the web server:
	if [[ -x /etc/init.d/httpd ]]
	then	/etc/init.d/httpd restart
	else	if [[ -x /etc/init.d/apache ]]
		then	Note "Restarting the web server"
			/etc/init.d/apache restart
		else	Die "I don't know how to restart your web server"
		fi
	fi
else	Note "Not restarting the web server"
fi

# end
