#!/bin/bash
#
# Simple shell script to update GeoIP database files
#
# Project    : ipv6calc/GeoIP
# File       : GeoIP-update.sh
# Version    : $Id: f0492a7760ddedee88211ea8b212c8cd844e9d42 $
# Copyright  : 2012-2019 by Peter Bieringer <pb (at) bieringer.de>
# License    : GNU GPL version 2

GEOIP_DAT_DIR_DEFAULT="/usr/share/GeoIP"
[ -z "$GEOIP_DAT_DIR" ] && GEOIP_DAT_DIR="$GEOIP_DAT_DIR_DEFAULT"

GEOIP_DAT_URL_BASE="http://geolite.maxmind.com/download/geoip/database/"
GEOIP_DAT_FILES="GeoLiteCountry/GeoIP.dat.gz GeoIPv6.dat.gz GeoLiteCity.dat.gz GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz asnum/GeoIPASNum.dat.gz asnum/GeoIPASNumv6.dat.gz GeoLite2-City.tar.gz GeoLite2-Country.tar.gz GeoLite2-ASN.tar.gz"

help() {
	cat <<END
Usage: $(basename "$0") [-D <dir>] [-v] [-s] [-L] [-G]
	-s		skip download
	-D <dir>	database directory (optional)
	-v		verbose
	-L		legacy download mode (by default download only MaxMindDB version)
	-G		use 'geoipupdate' to download databases

	database directory: $GEOIP_DAT_DIR (default: $GEOIP_DAT_DIR_DEFAULT)

	it honors externally defined environment value: GEOIP_DAT_DIR

 this script will download data from geolite.maxmind.com (GeoIP)
 into given/set database directory

 GEOIP_DAT_URL_BASE=$GEOIP_DAT_URL_BASE
 GEOIP_DAT_FILES=$GEOIP_DAT_FILES

 in case of 'geoipupdate' mode is used, adjust /etc/GeoIP.conf:
   EditionIDs GeoLite2-Country GeoLite2-City GeoLite2-ASN
   (in case a valid license key exists, add key and extend EditionIDs related)
   see also https://dev.maxmind.com/geoip/geoipupdate/
END
}

while getopts "sGLD:vh\?" opt; do
	case $opt in
	    s)
		skip_download=1
		;;
	    D)
		GEOIP_DAT_DIR=$OPTARG
		;;
	    v)
		verbose=1
		;;
	    L)
		legacy=1
		;;
	    G)
		geoipupdate=1
		;;
	    *)
		help
		exit 1
		;;
	esac
done


if [ ! -d "$GEOIP_DAT_DIR" ]; then
	echo "ERROR : missing directory: $GEOIP_DAT_DIR"
	exit 1
fi

if [ ! -w "$GEOIP_DAT_DIR" ]; then
	echo "ERROR : missing write permissions on directory: $GEOIP_DAT_DIR"
	exit 1
fi

if [ ! -t 0 ]; then
	options_wget="-q"
fi


if [ "$geoipupdate" != "1" ]; then

# Download and unpack files
for file in $GEOIP_DAT_FILES; do
	case $file in
	    *.dat.gz)
		if [ "$legacy" != "1" ]; then
			echo "NOTICE: legacy mode not enabled, skip download of: $file"
		fi
		continue
		;;
	esac

	file_basename="`basename "$file"`"
	file_basename_decomp="`basename "$file" .gz`"
	file_dest="$GEOIP_DAT_DIR/$file_basename"

	if [ "$skip_download" != "1" ]; then
		echo "INFO  : try to download file: $file ($file_dest)"
		wget $options_wget -O "$file_dest" "$GEOIP_DAT_URL_BASE$file"
		if [ $? -ne 0 ]; then
			echo "ERROR : download of file not successful: $file ($file_dest)"
			continue
		fi
		echo "INFO  : download of file successful: $file ($file_dest)"
	fi

	case $file in
	    *.dat.gz)
		gunzip -f "$file_dest"
		if [ $? -ne 0 ]; then
			echo "ERROR : unzip of file not successful: $file_dest"
			continue
		fi
		echo "INFO  : unzip of file successful: $file_dest"
		;;
	    *.tar.gz)
		file_extract=${file/.tar.gz/.mmdb}
		file_extract_full=$(tar tzf "$file_dest" | grep "$file_extract$")
		echo "INFO  : extract from $file_dest: $file_extract_full"
		tar xzf "$file_dest" --strip-components 1 -C "$GEOIP_DAT_DIR" "$file_extract_full"
		if [ $? -ne 0 ]; then
			echo "ERROR : tar extract of file not successful: $file_dest"
			continue
		fi

		echo "INFO  : remove downloaded file: $file_dest"
		rm -f "$file_dest"
		;;
	esac

	# check for softlinks
	case "$file_basename_decomp" in
	    GeoLiteCity.dat)
		softlinkdst="GeoIPCity.dat" 
		;;
	    GeoLiteCityv6.dat)
		softlinkdst="GeoIPCityv6.dat" 
		;;
	    *)
		softlinkdst="" 
        esac

	if [ -n "$softlinkdst" -a ! -e "$GEOIP_DAT_DIR/$softlinkdst" ]; then
		echo "NOTICE: softlink missing, create: $softlinkdst"
		ln -s "$file_basename_decomp" "$GEOIP_DAT_DIR/$softlinkdst"
	fi
done

else	# end of wget based download
	geoipupdate_bin=$(which geoipupdate)

	if [ -z "$geoipupdate_bin" ]; then
		echo "ERROR : missing binary 'geoipupdate' not found, can't continue"
		exit 1
	fi

	geoipupdate ${verbose:+-v} -d $GEOIP_DAT_DIR
	if [ $? -ne 0 ]; then
		echo "ERROR : 'geoipupdate' stopped with error"
		exit 1
	fi
	echo "INFO  : 'geoipupdate' was successful"
fi # end of using geoipupdate
