conffiles/
dictfiles/
quotefiles/
src/
#!/bin/sh

#	Purpose: This script should make simplier the compiling of GAEN
# sources, avoiding user to search the right parametters for GCC compiler.
# There are a finite number of parameters/problems which could cause
# compiling crashes, all of them (we hope) being tested below.

#	Usage: easy.compile [SourceFile.c] [ -o ] [ OutputFile ]
#	If the "-o" parameter is not present then the arguments will be
# parsed in the following order: SourceFile OutputFile. If it is present,
# then the OutputFile will be taken from the next argument.

#       Any of those parameters may not be present, as you can see below:
#	$ easy.compile
#	$ easy.compile -o gaend
#	$ easy.compile MyOwnSourceFile.c
#	$ easy.compile -o MyOutputFile MyOwnSourceFile.c
#	$ easy.compile MyOwnSourceFile.c MyOutputFile
#	$ easy.compile --help

# Some modifications are made by Sabin Corneliu Buraga <busaco@infoiasi.ro>:
#	- messages' colours changed
#	- all temporary "a.out" files are written in "/tmp", 
# 	  instead of current directory 
#	- minor corrections to internal script comments/remarks
#	- the "--help" parameter added to show the syntax of this script
#	- using of "strip --strip-all" instead of "strip" without parameters

 
Version="1.3.1 final (internal version 1.1.1), 05 May 2002"
echo;
echo "              >>>GAEN Easy Compile Concept script<<<"
echo;
echo ">>>Version "${Version}".";
echo ">>>Author: Victor Tarhon-Onu <mituc@ac.tuiasi.ro>";
echo "           (modified by Sabin-Corneliu Buraga <busaco@infoiasi.ro>)";     
echo;

if [ $# -eq 1 ]; then
  if [ "$1" = "--help" ]; then
    echo;
    echo "Usage: easy.compile [SourceFile.c] [ -o ] [ OutputFile ]"
    echo;
    exit 2;
  fi
fi

# No cores...
ulimit -c 0;

# Setting up PATH if we are running on nasty configurated systems.
PATH=/usr/bin:/bin:/usr/local/bin:/usr/ucb

# Selecting the best tools for viewing processes and showing text...

# It seems like 'ps' does not have universal options. We'll use
# "-ef" or "-awxu" parameters, depending on ps's requirements.

if [ "`ps -elf 2>&1 1>/dev/null`" = "" ]; then
  PS_ARGS="-elf";
else
  PS_ARGS="-auxw"
fi;

# Some broken echo's may require this...
SYSV3=""

ECHO_ENUM=`whereis ps | cut -d " " -f 2-`;
for i in $ECHO_ENUM; do
  if [ "`echo -n`" = "" ]; then
    break;
  fi;
done;

# Does out echo support -e option...?
if [ "`echo -e`" = "" ]; then
  ECHO="echo -e";
else
  ECHO="echo";
fi;

# Initialising default parameters...
LIBS="";
FLAGS="";
DEFAULT_SOURCE_FILE="src/gaen.c";
DEFAULT_OUTPUT_FILE="gaend";
SOURCE_FILE="";
DEFAULT_BASE_FILE="gaen.c";
OUTPUT_FILE="";

# ... and some internal constants and functions.

UNIQUE="$RANDOM";
GAENCompillingScript="/tmp/"$UNIQUE"GAENCompillingScript";
LockFile="/tmp/"$UNIQUE"GAENLockFile";
ErrFile="/tmp/"$UNIQUE"GAENErrFile";
UserName=`whoami`;

# Terminating signals handler function.
make_clean()
{
	# Killing the gcc compiling the source file.
	for PID in `ps "$PS_ARGS" | grep "$UserName" | grep -v "${0}" | grep -v grep | grep "${BASE_FILE}" | awk {'print $4'}`; do
		kill -15 "${PID}" 2>/dev/null 1>/dev/null;
	done;

	# ...and the cc1's too. cc1 does not have an argument who's name
	# is alike with the source's name... So we'll kill'em all :)
	for PID in `ps "$PS_ARGS" | grep "$UserName" | grep -v "${0}" | grep -v grep | grep cc1 | awk '{print $4}'`; do
                kill -15 "${PID}" 2>/dev/null 1>/dev/null;
        done;

	# Remove all temporarily created files.
	rm -f "${GAENCompillingScript}" "${LockFile}" "${ErrFile}" \
	      /tmp/gcctest.c /tmp/crypt.c /tmp/socket.c \
	      /tmp/nsl.c /tmp/opt.c /tmp/a.out 2>/dev/null 1>/dev/null;
	echo "";
	exit;
}

# This will delete all files made during tests and compiling activity.
trap make_clean 0 1 2 3 15;

# Parsing command line arguments - if any...

FoundOptFlag=0;
for Param in "${@}"; do	
	if [ "${Param}" = "-o" ]; then
		FoundOptFlag=1;
	    else
		if [ "${FoundOptFlag}" = "1" ]; then
			OUTPUT_FILE="${Param}";
			FoundOptFlag=0;
		    else
			if [ "${SOURCE_FILE}" = "" ]; then
				SOURCE_FILE="${Param}";
			    else
				OUTPUT_FILE="${Param}";
			fi;
		fi;
		
	fi;
done;

# If some params where not found then we'll initialise them default values.
if [ "${SOURCE_FILE}" = "" ]; then 
  SOURCE_FILE="${DEFAULT_SOURCE_FILE}";
  BASE_FILE="${DEFAULT_BASE_FILE}";
else
  BASE_FILE=`basename "${SOURCE_FILE}"`;
fi;

# Determine the relative filename of the sourcefile - useful in make_clean();
if [ "${OUTPUT_FILE}" = "" ]; then 
  OUTPUT_FILE="${DEFAULT_OUTPUT_FILE}";
fi;

# Anyway, if there is no source file, it makes no sense to make the rest
# of the test.
if [ ! -f "${SOURCE_FILE}" ]; then
	echo ">>>Fatal error: Cannot open source file \""${SOURCE_FILE}"\" \
for GAEN server." >&2;
	exit 1;
fi;

# We'll do it the same way if gcc is a jerk or just does not exist.
$ECHO ">>>Checking if gcc compiler exists and works... "\\c;
echo "main(){}" > /tmp/gcctest.c;

GCC="";

GCC_ENUM=`whereis gcc | cut -d " " -f 2-; whereis cc | cut -d " " -f 2-`;

for i in $GCC_ENUM; do
  if [ "`echo $i | grep obsolete`" != "" -o \
			"`echo $i | grep old`" != "" ]; then
    continue;
  fi;
  ERR=`$i /tmp/gcctest.c -o/tmp/a.out 2>&1 1>/dev/null`;
  if [ "$ERR" = "" ]; then
    GCC="$i";
    echo "done."
    break;
  fi;
done;

if [ "$GCC" = "" ]; then
  echo "failed.";
  echo ">>>Fatal error: It seems like gcc doesn't work ! <:-(";
  exit 1;
fi;

# The crypt() functions (and other similar functions) are not
# included in libc (or glibc), but in a library named 'libcrypt' which
# contains all the stuff concerning the crypt() functions.
# This happens for glibc packages newer than 5.3, we think.
$ECHO ">>>Searching for crypt() function in crypt library... "\\c;

cat > /tmp/crypt.c <<EOF
#include <unistd.h> 
main (void) /* test file created by GAEN easy compile script */
{
  crypt (NULL, NULL);
  return 0;
}
EOF

ERR=`$GCC /tmp/crypt.c -lcrypt -o/tmp/a.out 2>&1 1>/dev/null | grep "crypt"`;
if [ "${ERR}" = "" ]; then
	LIBS="-lcrypt";
	echo "found.";
    else
	echo "not found.";
fi;


# For some versions of GNU GCC - those coming with Solaris, some of the 
# functions concerning the networking part are all included in a stand-alone
# library named 'libsocket'.
$ECHO ">>>Searching for BSD socket functions in socket library... "\\c;

cat > /tmp/socket.c <<EOF
#include <sys/socket.h>
main (void) /* test file created by GAEN easy compile script */
{
  return socket (AF_INET, SOCK_STREAM, 0);
}
EOF

ERR=`$GCC /tmp/socket.c -lsocket -o/tmp/a.out 2>&1 1>/dev/null | grep "socket"`;
if [ "${ERR}" = "" ]; then
	LIBS="-lsocket "${LIBS}"";
	echo "found.";
    else
	echo "not found.";
fi;


# ...and the rest of them (e.g. DNS manipulation routines) in 'libnsl'.
$ECHO ">>>Searching for other socket/DNS functions in nsl library... "\\c;

cat > /tmp/nsl.c <<EOF
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
main (void) /* test file created by GAEN easy compile script */
{
  return socket (AF_INET, SOCK_STREAM, 0);
}
EOF

ERR=`$GCC /tmp/nsl.c -lnsl -o/tmp/a.out 2>&1 1>/dev/null`;
if [ "${ERR}" = "" ]; then
	LIBS="-lnsl "${LIBS}"";
	echo "found.";
    else
	echo "not found.";
fi;


# Older/particular versions of GCC don't know how to optimize code when 
# we demand it or just usually... Maybe newer versions of GCC having this
# problem but we just didn't heared about any...
$ECHO ">>>Checking if gcc can generate optimized code... "\\c;

cat >/tmp/opt.c <<EOF
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
main (void) /* test file created by GAEN easy compile script */
{
  (void) fprintf(stderr, "We really have to write something here?:)\n");
  socket (AF_INET, SOCK_STREAM, 0);
  crypt (NULL, NULL);
  return 0;
}
EOF

ERR=`$GCC /tmp/opt.c $LIBS -O -o/tmp/a.out 2>&1`;
if [ "$ERR" = "" ]; then
	FLAGS="-O";
	echo "ok.";
	CAN_OPTIMIZE="1";
    else
	echo "cannot.";
fi;

# We obtained the smallest, the fastest and the most stable code we've got 
# under various versions of Linux compiling with "-O2" ("-O3" option 
# makes the ELF bigger). We suppose (hope) that's common to most of UNIX/GCC
# versions. We're thinking about OS's libraries... but at least GCC generates
# the code, not the OS. So, this should be common to most of GCC versions.
if [ "$CAN_OPTIMIZE" = "1" ]; then
	$ECHO ">>>Forcing gcc to a higher optimization level... "\\c;
	ERR=`$GCC /tmp/opt.c $LIBS -O2 -o/tmp/a.out 2>&1 1>/dev/null | grep "O"`;
	if [ "${ERR}" = "" ]; then
		FLAGS=""${FLAGS}"2";
		echo "success.";
    	    else
		echo "cannot.";
	fi;
fi;

# We just want to be sure the file does not exist. It may happen to exist
# sometimes... if you interrupted this script before it finishes its work.
# In this case, if the name of the lock file is the same or nor depends on
# the way the OS generates random numbers (via shell)... or if it really
# does this... Anyway, it's more safe if we removed it before.
rm -f "${LockFile}" 2>/dev/null 1>/dev/null;

# Here it will be generated a script based on the information already 
# obtained. The idea is to run it in a subshell, so it'll be easier to
# supervise.

cat >"${GAENCompillingScript}" <<EOF
#!/bin/sh
$GCC $SOURCE_FILE -o $OUTPUT_FILE $FLAGS $LIBS $NO_SUPPORT 2>>$ErrFile\\
      && strip --strip-all $OUTPUT_FILE 2>>$ErrFile
touch $LockFile 2>>$ErrFile
EOF

$ECHO ">>>Compiling GAEN server \""${OUTPUT_FILE}"\" from file \""${SOURCE_FILE}"\"..."\\c;

# Running the script in background...
. ${GAENCompillingScript} &

# Some poor visual effects using the lock file...
Time="-1";
dash="";
printf "%s" "";
while [ ! -f "${LockFile}" ]; do
	Time=`expr $Time + 1`;
	dash=`expr $Time % 4`;
	case "$dash" in
	  "0")
		printf "%s\b" "-";
		;;
	  "1")
		printf "%s\b" "\\";
		;;
	  "2")
		printf "%s\b" "|";
		;;
	  "3")
		printf "%s\b" "/";
		;;
	esac;
	sleep 1;
done;

# Showing some info about the compiling time and about any errors...
# which may be occured.
if [ -s "${ErrFile}" ]; then
	$ECHO \\b"failed.";
	echo ">>>Done in "$Time" seconds with the following error(s):";
        echo "********************************************************";
	less "${ErrFile}" 1>&2;
	echo "********************************************************";
    else
	$ECHO \\b"done.";
	echo ">>>Done in "$Time" seconds with success.";
fi;
$ECHO \\b"";

# Chatting is beautiful !:) That's COOL !!!:)))