#!/bin/sh

#
# Some content functions
#
getSysctlConfContent(){
GBS=$1
BYTES="$(( $GBS * 1073741824 ))"
contentTemp="\n\
# PREORACLE\n\
#\n\
# Oracle 11g\n\
#\n\
kernel.sem = 250 32000 100 128\n\
kernel.shmall = 2097152\n\
kernel.shmmni = 4096\n\
# Replace kernel.shmmax with the half of your memory in bytes\n\
# if lower than 4Go minus 1\n\
# 1073741824 is 1 GigaBytes\n\
kernel.shmmax=BYTES\n\
\n\
# Try sysctl -a | grep ip_local_port_range to get real values\n\
net.ipv4.ip_local_port_range = 9000  65500\n\
\n\
net.core.rmem_default = 262144\n\
net.core.rmem_max = 4194304\n\
net.core.wmem_default = 262144\n\
net.core.wmem_max = 1048576\n\
\n\
# Max value allowed, should be set to avoid IO errors\n\
fs.aio-max-nr = 1048576\n\
# 512 * PROCESSES\n\
fs.file-max = 6815744\n\ 
\n\
# To allow dba to allocate hugetlbfs pages\n\
# 1001 is your oinstall group, id. grep oinstall /etc/group will give this value\n\
vm.hugetlb_shm_group = 1001\n"
echo "$contentTemp" | sed s#"BYTES"#"$BYTES"#g
}

getLimitsContent(){
contentTemp="\n\
# PREORACLE\n\
# Oracle\n\
oracle           soft    nproc   2047\n\
oracle           hard    nproc   16384\n\
oracle           soft    nofile  1024\n\
oracle           hard    nofile  65536\n\
oracle           soft    stack   10240\n"
echo "$contentTemp"
}

getProfileContent(){
contentTemp="\n\
# PREORACLE\n\
if [ \$USER = "oracle" ]; then\n\
        if [ \$SHELL = \"/bin/ksh\" ]; then\n\
              ulimit -p 16384\n\
              ulimit -n 65536\n\
        else\n\
              ulimit -u 16384 -n 65536\n\
        fi\n\
fi\n"
echo "$contentTemp"
}

getBashRcContent(){
contentTemp="\n\
# PREORACLE\n\
umask 022\n\
\n\
# Oracle paths\n\
export ORACLE_HOME=/opt/oracle/app/oracle/product/12.1.0/dbhome_1\n\
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:\$ORACLE_HOME/lib\n\
export PATH=\$PATH:\$ORACLE_HOME/bin\n\
export ORACLE_SID=orcl\n"
echo "$contentTemp"
}

gotBootScriptContent(){
contentTemp="\n\
#\!/bin/sh\n\
# PREORACLE\n\
\n\
source \$HOME/.bashrc\n\
dbshut \$ORACLE_HOME\n\
dbstart \$ORACLE_HOME\n\
\n\
#echo \"password for system is oracle\"\n\
#sqlplus system@orcl\n"
echo "$contentTemp"
}

checkAddition(){
cat $1 | grep "PREORACLE" > /dev/null 2>&1 && echo "$1 is already patched" && return 1
return 0
}

#
# Some std functions
#
installPackage(){
RESP=1
echo -n "Installing $1.."
apt-get install -y $1 >/dev/null 2>&1 && RESP=0
if [ $RESP -eq 0 ]; then
	echo "OK"
else
	echo "FAILED"
fi
}

chkRootAccess(){
[ `whoami` != "root" ] && echo "Son or girlie, you need to be root." && exit 1
}

# Syntax:
# ask(quest | default | variable to set
ask(){
echo -n "$1: [$2] "; read val
if [ -z "$val" ]; then
read $3 <<EOF
$2
EOF
else
read $3 <<EOF
$val
EOF
fi
eval gotit=\$$3
}

##
# This function will just
# return 1 if we don't
# get 'y' or 'n'
# Syntax:
# checkyesno(arg y/n) ret(0/1)
checkyesno(){
  if [ $# -ne 1 ]; then
     return 1
  fi
  case "$1" in
    "y") return 0 ;;
    "n")  return 0 ;;
    *) echo "${voice} A looping complaint - y or n will do!"
    return 1 ;
  esac
}

##
# And one to just ask
# for a yes or no with
# a default value
# Syntax:
# askYesNo(arg1 quest|arg2 default answer|arg3 variable to set) ret(0/1)
askYesNo(){
echo -n "$1: [$2] "; read val
if [ -z "$val" ]; then
read $3 <<EOF
$2
EOF
else
read $3 <<EOF
$val
EOF
fi
eval gotit=\$$3
checkyesno $gotit || return 1
return 0
}

##
# Wrapper for askYesNo - returns
# 0 for 'y' to given quest, 1 for
# 'n'
yesToDoIt(){
	quest="$@"
	pass=1
	while [ $pass -eq 1 ]; do
	        askYesNo "${quest}" y go && pass=0
	done
	if [ "$go" = "y" ]; then
		return 0
	else
		return 1
	fi
}

#
# Patcher for the oracle installation make file
#
patchMakeFile(){
makeFile=$1
cp $makeFile $makeFile\.orig
cat $makeFile |\
	sed s#"LINK=\$(LDCCOM)"#"LINK=\$(LDCCOM) --Wl,--no-as-needed"#g |\
	sed s#"LINKTTLIBS=\$(LLIBCLNTSH) \$(ORACLETTLIBS) \$(LINKLDLIBS)"#"LINKTTLIBS=\$(LLIBCLNTSH) \$(ORACLETTLIBS) \$(LINKLDLIBS) -lons"#g |\
	sed s#"LINK=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS) \$(COMPSOBJS)"#"LINK=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS) \$(COMPSOBJS) --Wl,--no-as-needed"#g |\
	sed s#"LINK32=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS32) \$(COMPSOBJS)"#"LINK32=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS32) \$(COMPSOBJS) --Wl,--no-as-needed"#g |\
	sed s#"\$(LLIBTHREAD) \$(LLIBCLNTSH) \$(LINKLDLIBS)"#"\$(LLIBTHREAD) \$(LLIBCLNTSH) \$(LINKLDLIBS) -lnnz12"#g |\
	sed s#"$'\t'\$(HSALIB_SUBSET2)"#"$'\t'\$(HSALIB_SUBSET2) -lagtsh"#g > /tmp/apa
mv /tmp/apa $makeFile
cat $makeFile | sed s#"=\$(LINK) \$(OPT)"#"=\$(LINK) \$(OPT) --Wl,–-no-as-needed"#g > /tmp/apa && mv /tmp/apa $makeFile
rm -rf $ORACLE_HOME/lib/stubs/*
ln -s $ORACLE_HOME/lib/libclntshcore.so.12.1 /usr/lib/
echo "# PREORACLE" >> $makeFile
chown oracle:oinstall $makeFile
}

patchWrapping(){
export ORACLE_HOME=/opt/oracle/app/oracle/product/12.1.0/dbhome_1
if [ -f $ORACLE_HOME/rdbms/lib/env_rdbms.mk ]; then
	DOADD=1
	echo "Patching \$ORACLE_HOME/rdbms/lib/env_rdbms.mk.."
	checkAddition $ORACLE_HOME/rdbms/lib/env_rdbms.mk >/dev/null 2>&1 && DOADD=0
	if [ $DOADD -eq 0 ]; then
		DOPATH=1
		yesToDoIt "You wanna patch your oracle installation make file" && DOPATCH=0
		if [ $DOPATCH -eq 0 ]; then
			patchMakeFile $ORACLE_HOME/rdbms/lib/env_rdbms.mk
			echo		
		fi
	else
		echo "Oracle makefile is already patched. Pressing retry in the installer should work fine now."	
	fi
else
	echo "Oracle make file $ORACLE_HOME/rdbms/lib/env_rdbms.mk is not here yet, which is fine unless you've ran the installer.."
fi
}

#
# Main ----------------------
#
[ $# -gt 1 ] && echo "Zero or one arg please!" && exit 1
if [ $# -eq 1 ]; then
	if [ "$1" = "-p" ]; then
		chkRootAccess
		patchWrapping
		exit 0
	else
		echo "Unknown arg : use -p for patching the oracle installation make file" && exit 1
	fi
fi
chkRootAccess

ask "How many GBs of memory can Oracle access" 1 howManyGb
echo $howManyGb | egrep "[^0-9]" >/dev/null 2>&1 && echo "Man, that's bad input.." && exit 1

echo
echo "Starting pre-oracle installation!"
echo

# user stuff
echo -n "1. Adding users and groups.."
if [ ! -d /opt/oracle ]; then
	groupadd oinstall
	groupadd dba
	mkdir -p /opt/oracle
	useradd -g oinstall -G dba  -d /opt/oracle -s /bin/bash oracle
	echo "You will now be asked to add the password for oracle"
	passwd oracle
	chown -R oracle:oinstall /opt/oracle
	echo "ok"
else
	echo "they are already here"
fi
echo

# additions to /etc/sysctl.conf
DOADD=1
echo -n "2. Patched /etc/sysctl.conf.."
checkAddition /etc/sysctl.conf && DOADD=0
if [ $DOADD -eq 0 ]; then
	echo -n "/etc/sysctl.conf additions.."
	content="`getSysctlConfContent $howManyGb`"
	echo "$content" >> /etc/sysctl.conf
	sysctl -p >/dev/null 2>&1
	echo "ok"
fi
echo

# additions to /etc/security/limits.conf
DOADD=1
echo -n "3. Patched /etc/security/limits.conf.."
checkAddition /etc/security/limits.conf && DOADD=0
if [ $DOADD -eq 0 ]; then
	echo -n "/etc/security/limits.conf additions.."
	content="`getLimitsContent`"
	echo "$content" >> /etc/security/limits.conf
	echo "ok"
fi
echo

# additions to /etc/profile
DOADD=1
echo -n "4. Patched /etc/profile.."
checkAddition /etc/profile && DOADD=0
if [ $DOADD -eq 0 ]; then
	echo -n "/etc/profile additions.."
	content="`getProfileContent`"
	echo "$content" >> /etc/profile
	echo "ok"
fi
echo

# upgrading
echo "5. Upgrading system if applicable."
echo "apt-get update" && apt-get update >/dev/null 2>&1
echo "apt-get dist-upgrade" && apt-get dist-upgrade -y >/dev/null 2>&1
echo "ok"
echo

# install packages
echo "6. Installing first batch of packages.."
installPackage "alien"
installPackage "autoconf"
installPackage "automake"
installPackage "autotools-dev"
installPackage "binutils"
installPackage "bzip2"
installPackage "doxygen"
installPackage "elfutils"
installPackage "expat"
installPackage "gawk"
installPackage "gcc"
installPackage "gcc-multilib"
installPackage "g++-multilib"
echo

## and more..
echo "7. Installing second batch of packages.."
installPackage "ksh"
installPackage "less"
installPackage "lib32z1"
installPackage "libaio1"
installPackage "libaio-dev"
installPackage "libc6-dev"
installPackage "libc6-dev-i386"
installPackage "libc6-i386"
installPackage "libelf-dev"
installPackage "libltdl-dev"
installPackage "libmotif4"
installPackage "libodbcinstq4-1 libodbcinstq4-1:i386"
installPackage "libpth-dev"
installPackage "libpthread-stubs0-dev"
installPackage "libstdc++5"
installPackage "lsb-cxx"
installPackage "make"
installPackage "openssh-server"
installPackage "pdksh"
installPackage "rlwrap"
installPackage "rpm"
installPackage "sysstat"
installPackage "unixodbc"
installPackage "unixodbc-dev"
installPackage "unzip"
installPackage "x11-utils"
installPackage "zlibc"
installPackage "lib32z1-dev"
echo

# Preventing problems
echo "8. Preventing path issues.."
if [ ! -f /usr/lib32/libstdc++.so.5 ]; then
	echo -n "preventing path issues..."
	ln -s /usr/lib/x86_64-linux-gnu /usr/lib64
	ln -sf /bin/bash /bin/sh
	[ ! -f /bin/awk ] && ln -s /usr/bin/awk /bin/awk
	[ ! -f /bin/rpm ] && ln -s /usr/bin/rpm /bin/rpm 
	[ ! -f /bin/basename ] && ln -s /usr/bin/basename /bin/basename 
	if [ ! -f /lib64/libgcc_s.so.1 ]; then	
		cd /lib64
		ln -s /lib/x86_64-linux-gnu/libgcc_s.so.1 .
		mkdir /tmp/libstdc++5
		cd /tmp/libstdc++5
		wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.3/libstdc++5_3.3.6-17ubuntu1_amd64.deb
		wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.3/libstdc++5_3.3.6-17ubuntu1_i386.deb
		dpkg --force-architecture -i libstdc++5_3.3.6-17ubuntu1_i386.deb
		mv /usr/lib/libstdc++.so.5* /usr/lib32/
		dpkg -i libstdc++5_3.3.6-17ubuntu1_amd64.deb
		echo "OK"
	fi
else
	echo "Path preventions are already done"
fi
echo

# fixes from https://gemsofprogramming.wordpress.com/2013/09/19/installing-oracle-12c-on-ubuntu-12-04-64-bit-a-hard-journey-but-its-worth-it/
echo "9. Preventing oracle libs not linked yet issues"
if [ ! -d /usr/lib/lib64 ]; then
	echo -n "other fixes..."
	ln -s /usr/lib /usr/lib/lib64
	ln -s /usr/lib/x86_64-linux-gnu/libc_nonshared.a /usr/lib64
	echo "OK"
else
	echo "Other fixes are already done"
fi
echo

# GCC 4.4 is required
echo "9. GCC 4.4"
if [ ! -f /usr/bin/gcc-4.4 ]; then
	echo -n "gcc 4.4..."
	cd /usr/bin
	wasLinked="`ls -l /usr/bin/gcc`"
	installPackage "gcc-4.4"
	echo "$wasLinked" > gcc_was_linked.txt
	rm /usr/bin/gcc
	ln -s gcc-4.4 gcc
	echo "OK"
else
	echo "gcc 4.4 is already here"
fi
echo

# Oracle home stuff
echo "10. Oracle HOME stuff"
if [ ! -f /opt/oracle/.bashrc ]; then
	echo -n "oracle home stuff..."
	content="`getBashRcContent`"
	echo "$content" > /opt/oracle/.bashrc
	chown oracle:oinstall /opt/oracle/.bashrc
	ln -s /opt/oracle/.bashrc /opt/oracle/.bash_profile
	chown oracle:oinstall /opt/oracle/.bash_profile
	echo "OK"
else
	echo "oracle home stuff is are already done"
fi
echo

# boot script
echo "11. oracle boot script"
if [ ! -f /etc/init.d/startOracle ]; then
	echo -n "boot script..."
	content="`gotBootScriptContent`"
	echo "$content" > /opt/oracle/restartOracle.sh
	chown oracle:oinstall /opt/oracle/restartOracle.sh
	chmod 700 /opt/oracle/restartOracle.sh
	echo "su - oracle -c /opt/oracle/restartOracle.sh" > /etc/init.d/startOracle 
	chmod 700 /etc/init.d/startOracle
	ln -s /etc/init.d/startOracle /etc/rc2.d/S99oracle
	echo "OK"
else
	echo "oracle boot script is already in place"
fi
echo

# final instructions
echo
echo "**************************************************"
echo
echo "Final instructions..."
echo
echo "Reboot if you have not done so!"
echo
echo "1. fetch the two zip-files that are oracle from oracle, move them to /tmp, extract them"
echo "2. change user to oracle, source .bashrc, go to /tmp/database"
echo "3. run xhost+ in some another terminal window"
echo "4. source \$HOME/.bashrc"
echo "5. go into the unzipped dir and run ./runInstaller"
echo "6. There will be trouble. Backup your original make file"
echo
echo "cp \$ORACLE_HOME/rdbms/lib/env_rdbms.mk \$ORACLE_HOME/rdbms/lib/env_rdbms.mk.orig"
echo
echo "7. Either manually perform below changes or let the make-file-patcher-script do it for you"
echo
echo "155c155"
echo "\< LINK=\$(LDCCOM) --Wl,--no-as-needed"
echo "---"
echo "\> LINK=\$(LDCCOM)"
echo
echo "176c176"
echo "\< LINKTTLIBS=\$(LLIBCLNTSH) \$(ORACLETTLIBS) \$(LINKLDLIBS) -lons"
echo "---"
echo "\> LINKTTLIBS=\$(LLIBCLNTSH) \$(ORACLETTLIBS) \$(LINKLDLIBS)"
echo
echo "279c279"
echo "LINK=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS) \$(COMPSOBJS) --Wl,--no-as-needed"
echo "---"
echo "LINK=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS) \$(COMPSOBJS)"
echo
echo "280c280"
echo "LINK32=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS32) \$(COMPSOBJS) --Wl,--no-as-needed"
echo "---"
echo "LINK32=\$(FORT_CMD) \$(PURECMDS) \$(ORALD) \$(LDFLAGS32) \$(COMPSOBJS)"
echo
echo "3006c3006"
echo "\< 	\$(HSALIB_SUBSET2) -lagtsh"
echo "---"
echo "\> 	\$(HSALIB_SUBSET2)"
echo
echo "3042c3042"
echo "\<         \$(LLIBTHREAD) \$(LLIBCLNTSH) \$(LINKLDLIBS) -lnnz12"
echo "---"
echo "\> 	\$(LLIBTHREAD) \$(LLIBCLNTSH) \$(LINKLDLIBS)"
echo
echo "and then run"
echo
echo "cat \$ORACLE_HOME/rdbms/lib/env_rdbms.mk | sed s#\"=\$(LINK) \$(OPT)\"#\"=\$(LINK) \$(OPT) --Wl,–-no-as-needed\"#g > /tmp/apa && mv /tmp/apa \$ORACLE_HOME/rdbms/lib/env_rdbms.mk"
echo
echo "and do (as oracle)"
echo
echo "rm -rf $ORACLE_HOME/lib/stubs/*"
echo
echo "then do (as root)"
echo
echo "export ORACLE_HOME=/opt/oracle/app/oracle/product/12.1.0/dbhome_1"
echo "ln -s \$ORACLE_HOME/lib/libclntshcore.so.12.1 /usr/lib/"
echo
echo "and... the installer should manage."
echo

#
# If the make file is here, you can choose to patch it with this script.
# It is tested and there will be a backup too.
#
patchWrapping

echo
echo "After a while the installer will ask you to run a script as root"
echo
echo "then open a root shell and execute /opt/oracle/app/oraInventory/orainstRoot.sh"
echo "and then /opt/oracle/app/oracle/product/12.1.0/dbhome_1/root.sh"
echo
echo "After it has finished, open /etc/oratab and change the startup row to"
echo "orcl:/opt/oracle/Oracle11gee/product/11.2.0/dbhome_1:Y"
echo
if [ ! -f /usr/bin/gcc_was_linked.txt ]; then
	echo "You might wanna switch back to your modern GCC in /usr/bin :"
	cat /usr/bin/gcc_was_linked.txt
fi
echo
echo "You are done."
echo

exit 0
