#!/bin/sh
#
# This script chooses the 32-bit or 64-bit plugin wrapper to use basing on the plugin ELF type.
# Based on an idea of My Opera Community members Chewi and kokoko3k.

detectbinarytype()
{
	prose=`file $fileflags "$1" | sed 's/.*://'`

	# Binary type
	case "$prose" in
		*ELF' '*)
			type=ELF
			;;
		*)
			return 1
			;;
	esac

	# ei_class
	case "$prose" in
		*' 32-bit '*)
			type=$type:32
			;;
		*' 64-bit '*)
			type=$type:64
			;;
		*)
			return 1
			;;
	esac

	# ei_data
	case "$prose" in
		*' LSB '*)
			type=$type:LSB
			;;
		*' MSB '*)
			type=$type:MSB
			;;
		*)
			return 1
			;;
	esac

	# e_machine
	case "$prose" in
		*' '80?86*|*x86-64*|*amd64*|*AMD64*)
			type=$type:x86
			;;
		*PowerPC*|*PPC*|*ppc*)
			type=$type:ppc
			;;
		*SPARC*|*sparc*)
			type=$type:sparc
			;;
		*)
			return 1
			;;
	esac

	# ei_osabi
	case "$prose" in
		*'(SYSV)'*)
			type=$type:SYSV
			;;
		*'(NetBSD)'*)
			type=$type:NetBSD
			;;
		*'(GNU/Linux)'*)
			type=$type:GNU/Linux
			;;
		*'(Solaris)'*)
			type=$type:Solaris
			;;
		*'(FreeBSD)'*)
			type=$type:FreeBSD
			;;
		*'(OpenBSD)'*)
			type=$type:FreeBSD
			;;
		*)
			type=$type:
			;;
	esac
	
	# .note.ABI-tag
	case "$prose" in
		*' for GNU/Linux '*)
			type=$type:GNU/Linux
			;;
		*' for GNU/Solaris '*)
			type=$type:GNU/Solaris
			;;
		*)
			case `uname` in
				SunOS)
					# On Solaris, file(1) won't parse .note.ABI-tag
					type=$type:`detectbinaryabi "$1"`
					;;
				Linux)
					# On Linux, assume that binaries without .note.ABI-tag are for Linux
					type=$type:GNU/Linux
					;;
				*)
					type=$type:
					;;
			esac
			;;
	esac
	
	echo $type
}

detectbinaryabi()
{
	note=`elfdump -nl -N .note.ABI-tag "$1" | sed -n '1,/^GNU$/d;/^.*desc\[0\][^0-9a-f]*\([0-9a-f ].*\)$/s//\1/p'`
	case "$note" in
		'00 00 00 00'*)
			abi=GNU/Linux
			;;
		'00 00 00 02'*)
			abi=GNU/Solaris
			;;
		*)
			return 1
			;;
	esac

	echo $abi
}

if [ `uname` = SunOS ]
then
	fileflags=-h
else
	fileflags=-bL
fi

plugin=""
for arg
do
	case "$arg" in
		*/*)
			plugin="$arg"
			;;
	esac
done

case "$0" in
	*/*)
		wrapperpath="${0%/*}/"
		;;
	*)
		wrapperpath=""
		;;
esac

wrapper=''
if [ -n "$plugin" ]
then
	if [ -r "$plugin" ]
	then
		plugintype=`detectbinarytype "$plugin"`
		if [ -n "$plugintype" ]
		then
			for candidate in "${wrapperpath}"operapluginwrapper-*
			do
				if [ -x "$candidate" -a .`detectbinarytype "$candidate"`. = .${plugintype}. ]
				then
					wrapper="$candidate"
					break
				fi
			done
			if [ -z "$wrapper" ]
			then
				echo "WARNING: $plugin: unsupported library type" >&2
				wrapper="${wrapperpath}"operapluginwrapper-native
			fi
		else
			echo "WARNING: $plugin: library type cannot be detected" >&2
			wrapper="${wrapperpath}"operapluginwrapper-native
		fi
	else
		echo "WARNING: $plugin: file does not exist or is unreadable" >&2
		wrapper="${wrapperpath}"operapluginwrapper-native
	fi
else
	wrapper="${wrapperpath}"operapluginwrapper-native
fi

exec "$wrapper" "$@"
