ichatserverdbctl   [plain text]


#!/bin/sh
#
# ichatserverctl - tool for controlling iChat Server database process
#
# Apple Computer (c) 2006 - All rights reserved.
#

__jd2_etc_dir="/private/etc/jabberd"
__jd2_var_dir="/private/var/jabberd"
__jd2_pid_dir="/private/var/run/jabberd"
__jd2_tmp_dir="/private/var/jabberd/tmp"
__jd2_db_engine=sqlite
__db_log_dir="${__db_base_dir}/log"
__db_pid_dir="${__db_base_dir}/pid"
__db_cnf_dir="${__db_base_dir}/conf"
__db_data_dir="${__db_base_dir}/data"
__db_sock_dir="${__db_base_dir}/sock"
__db_log_f="${__db_log_dir}/mysql_jabberd.log"
__db_pid_f="${__db_pid_dir}/mysql.pid"
__db_cnf_f="${__db_cnf_dir}/my.cnf"
__db_sock_f="${__db_sock_dir}/mysql.sock"
__db_user=jabber
__db_addr=localhost
__db_port=3308

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_log_debug - write debug-level message to log file
# sub_log_info - write info-level message to log file
# sub_log_error - write error-level message to log file
# arguments: ${1} message to be displayed
# returns: --
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_log_debug()
{
	if ( test ${__g_debug} -eq 1 ); then
		logger ichatserverctl: [DEBUG] ${1}
	fi
}

sub_log_info()
{
	logger ichatserverctl: [INFO] ${1}
}

sub_log_error()
{
	logger ichatserverctl: [ERROR] ${1}
}

# select jabberd auth and storage module selections, set db location
case "x-${__jd2_db_engine}" in
	"x-sqlite")
		__db_base_dir="${__jd2_var_dir}/sqlite"
		__jd2_db_auth_module="sqlite"
		__jd2_db_storage_module="sqlite"
		;;
#	"x-mysql")
#		__db_base_dir="${__jd2_var_dir}/mysql"
#		__jd2_db_auth_module="mysql"
#		__jd2_db_storage_module="mysql"
#		;;
	*)
	sub_log_error "Invalid/missing database selection!"
	exit 1
esac

__g_mysql_pref_running="${__jd2_tmp_dir}/mysql_test_running"
__g_mysql_pref_installed="${__jd2_tmp_dir}/mysql_test_installed"
__g_jd2_db_running="${__jd2_tmp_dir}/ichatserverdbctl_running"

__g_wait_reps=10
__g_wait_secs=3

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# SQLite database functions
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_sqlite_make_dirs()
{
    sub_log_debug "sub_sqlite_make_dirs() called"

    sub_log_info "Creating SQLite directories for jabberd..."
    sub_log_debug "...sqlite_make_dirs: base = ${__db_base_dir}"
    if ( test ${__g_test} -eq 0 ); then
        mkdir -p 770 "${__db_base_dir}";
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_sqlite_is_db_installed()
{
    sub_log_debug "sub_sqlite_is_db_installed() called"

    __g_installed=0

    sub_log_debug "...sqlite_is_db_installed: check for installed data in ${__db_base_dir}"
    if ( test ${__g_test} -eq 0 ); then
        if ( test -e "${__db_base_dir}" ); then
            if ( test -e "${__db_base_dir}/jabberd2.db" ); then
                __g_installed=1;
            fi;
        fi;
    else
        if ( test -e "${__g_test_db_installed}" ); then
            __g_installed=1;
        fi;
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_sqlite_install_data()
{   
    sub_log_debug "sub_sqlite_install_data() called"
    
    # sqlite3 jabberd2.db <  db-setup.sqlite
    if ( test ${__g_test} -eq 0 ); then
        sub_log_info "Creating SQLite database setup for jabberd..."
        if ( test ${__g_test} -eq 0 ); then
            sub_log_debug "...sqlite_install_data: reading from setup: ${__jd2_var_dir}/db-setup.sqlite"
            /usr/bin/sqlite3 "${__db_base_dir}/jabberd2.db" < "${__jd2_var_dir}/db-setup.sqlite"
            chown -R jabber:jabber "${__db_base_dir}";
			chmod 660 "${__db_base_dir}/jabberd2.db"
        fi;
    else
        echo "1" > "${__g_test_db_installed}";
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# MySQL database functions
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_mysql_make_dirs()
{
    sub_log_debug "sub_mysql_make_dirs() called"

    sub_log_info "Creating MySQL directories for jabberd..."
    sub_log_debug "...mysql_make_dirs: base = ${__db_base_dir}"
    if ( test ${__g_test} -eq 0 ); then
		mkdir -p -m 770 "${__db_log_dir}"
		mkdir -p -m 770 "${__db_pid_dir}"
		mkdir -p -m 770 "${__db_data_dir}"
		mkdir -p -m 770 "${__db_sock_dir}"
		mkdir -p -m 770 "${__db_cnf_dir}"
    fi
}

sub_mysql_init_db()
{
    sub_log_debug "sub_mysql_init_db() called"

    sub_log_info "Installing base MySQL data..."
    if ( test ${__g_test} -eq 0 ); then
		sub_log_debug "...mysql_init_db: installing ${__db_cnf_f}"
		cp -f /usr/share/mysql/my-huge.cnf "${__db_cnf_f}"
		/usr/bin/mysql_install_db --datadir="${__db_data_dir}"
		chown -R jabber:jabber "${__jd2_var_dir}"
    else
		echo "1" > "${__g_mysql_pref_installed}"
    fi

	sub_mysql_is_running
    if ( test ${__g_pid} -eq 0 ); then
		sub_log_info "Starting MySQL process..."
		sub_mysql_launch
		sub_wait_db_started
		sub_mysql_is_running
		if ( test ${__g_pid} -eq 0 ); then
			sub_log_debug "...mysql_init_db: mysqld startup failed -- aborting"
			return
		fi
    fi

    if ( test ${__g_pid} -ne 0 ); then
		sub_log_info "Creating MySQL database setup for jabberd..."
		if ( test ${__g_test} -eq 0 ); then
			sub_log_debug "...mysql_init_db: --socket=${__db_sock_f}"
			sub_log_debug "...mysql_init_db: reading from setup: ${__jd2_var_dir}/db-setup.mysql"
			/usr/bin/mysql --socket "${__db_sock_f}" < "${__jd2_var_dir}/db-setup.mysql"
		fi
    fi

}

sub_mysql_is_db_installed()
{
    sub_log_debug "sub_mysql_is_db_installed() called"

    __g_installed=0

    sub_log_debug "...mysql_is_db_installed: check for installed data in ${__db_data_dir}"
    if ( test ${__g_test} -eq 0 ); then
		if ( test -e "${__db_data_dir}" ); then
			__g_installed=1
		fi
    else
		if ( test -e "${__g_mysql_pref_installed}" ); then
			__g_installed=1
		fi
    fi
}

# DEBUG: replace sed, mysql, & rm commands which reveal db password in process table
sub_mysql_set_host_and_password()
{
    sub_log_debug "sub_mysql_set_host_and_password() called"

	### Remove once security bugs are fixed:
	sub_log_error "DEBUG: sub_mysql_set_host_and_password() contains security bugs and should not be used, exiting"
	exit 1
	###

    sub_log_info "Initializing MySQL host and password..."

    __jd2_host=`hostname`
    sub_log_info "Setting host name for jabberd: ${__jd2_host}"
    sub_log_debug "...mysql_set_host_and_password: etc dir = ${__jd2_etc_dir}"
    sub_log_debug "...mysql_set_host_and_password: var dir = ${__jd2_var_dir}"
    if ( test ${__g_test} -eq 0 ); then
		sub_log_debug "...mysql_set_host_and_password: setting host: ${__jd2_etc_dir}/c2s.xml"
		mv "${__jd2_etc_dir}/c2s.xml" "${__jd2_etc_dir}/c2s.xml.bak"
		cp "${__jd2_etc_dir}/c2s.xml.bak" "${__jd2_etc_dir}/c2s.xml"
		sed "s/\@HOSTNAME\@/${__jd2_host}/" < "${__jd2_etc_dir}/c2s.xml" > "${__jd2_etc_dir}/c2s~.xml"
		cp "${__jd2_etc_dir}/c2s~.xml" "${__jd2_etc_dir}/c2s.xml"
		sub_log_debug "...mysql_set_host_and_password: setting host: ${__jd2_etc_dir}/sm.xml"
		mv "${__jd2_etc_dir}/sm.xml" "${__jd2_etc_dir}/sm.xml.bak"
		cp "${__jd2_etc_dir}/sm.xml.bak" "${__jd2_etc_dir}/sm.xml"
		sed "s/\@HOSTNAME\@/${__jd2_host}/" < "${__jd2_etc_dir}/sm.xml" > "${__jd2_etc_dir}/sm~.xml"
		cp "${__jd2_etc_dir}/sm~.xml" "${__jd2_etc_dir}/sm.xml"
    fi

    sub_log_info "Setting host name for mu-conference: ${__jd2_host}"
    if ( test ${__g_test} -eq 0 ); then
		sub_log_debug "...mysql_set_host_and_password: setting mu-conference host: ${__jd2_etc_dir}/muc-jcr.xml"
		mv "${__jd2_etc_dir}/muc-jcr.xml" "${__jd2_etc_dir}/muc-jcr.xml.bak"
		cp "${__jd2_etc_dir}/muc-jcr.xml.bak" "${__jd2_etc_dir}/muc-jcr.xml"
		sed "s/\@HOSTNAME\@/${__jd2_host}/" < "${__jd2_etc_dir}/muc-jcr.xml" > "${__jd2_etc_dir}/muc-jcr~.xml"
		cp "${__jd2_etc_dir}/muc-jcr~.xml" "${__jd2_etc_dir}/muc-jcr.xml"
		sub_log_debug "...mysql_set_host_and_password: creating mu-conference spool folder: /var/spool/conference.${__jd2_host}"
		mkdir -p "/var/spool/conference.${__jd2_host}"
		chown _jabber:_jabber "/var/spool/conference.${__jd2_host}"
    fi
    
    cd "${__jd2_tmp_dir}"
    __db_pwd=`mktemp jabberXXXXXXXXXXXXXX`
	# DEBUG: The following is a security bug:
    #rm "${__jd2_tmp_dir}/${__db_pwd}"
    sub_log_info "Setting Jabber/MySQL password"
    if ( test ${__g_test} -eq 0 ); then
		sub_log_debug "...mysql_set_host_and_password: setting password: ${__jd2_etc_dir}/c2s.xml"
	# DEBUG: The following is a security bug:
		#sed "s/\@MYSQLPASSWORD\@/${__db_pwd}/" < "${__jd2_etc_dir}/c2s.xml" > "${__jd2_etc_dir}/c2s~.xml"
		cp "${__jd2_etc_dir}/c2s~.xml" "${__jd2_etc_dir}/c2s.xml"
		rm "${__jd2_etc_dir}/c2s~.xml"
		sub_log_debug "...mysql_set_host_and_password: setting password: ${__jd2_etc_dir}/sm.xml"
	# DEBUG: The following is a security bug:
		#sed "s/\@MYSQLPASSWORD\@/${__db_pwd}/" < "${__jd2_etc_dir}/sm.xml" > "${__jd2_etc_dir}/sm~.xml"
		cp "${__jd2_etc_dir}/sm~.xml" "${__jd2_etc_dir}/sm.xml"
		rm "${__jd2_etc_dir}/sm~.xml"
    fi
    
    sub_log_info "Updating MySQL database for jabberd user and password..."
    if ( test ${__g_test} -eq 0 ); then
        sub_log_debug "...mysql_set_host_and_password: --socket=${__db_sock_f}"
        sub_log_debug "...mysql_set_host_and_password: user==${__db_user}"
        sub_log_debug "...mysql_set_host_and_password"
#		/usr/bin/mysql --socket="${__db_sock_f}" \
#		   --exec='insert into user values ("localhost", "${__db_user}", password(), "Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","","","","","0","0","0");' \
#			mysql
		# DEBUG: The following may reveal db password in process table
		#/usr/bin/mysql --socket="${__db_sock_f}" \
		 #  --exec='insert into user values ("localhost", "jabber", "", "Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","","","","","0","0","0");' \
		#	mysql
    fi
	
    sub_log_info "Reloading MySQL database..."
    if ( test ${__g_test} -eq 0 ); then
		/usr/bin/mysqladmin --socket="${__db_sock_f}" reload
    fi
    
	#sub_log_info "Fixing permissions for jabberd directories..."
    #if ( test ${__g_test} -eq 0 ); then
	#	chown -R jabber:jabber "${__jd2_var_dir}"
    #fi
}

sub_mysql_launch()
{
    sub_log_debug "sub_mysql_launch() called"

	sub_mysql_is_running
    if ( test ${__g_pid} -eq 1 ); then
        sub_log_debug "...mysql_launch: mysqld already running -- aborted"
		return
    fi

    if ( test ${__g_test} -eq 0 ); then
        sub_log_debug "...mysql_launch: --datadir=${__db_data_dir}"
		sub_log_debug "...mysql_launch: --socket=${__db_sock_f}"
        sub_log_debug "...mysql_launch: --pid-file=${__db_pid_f}"
		sub_log_debug "...mysql_launch: --init-file=${__db_cnf_f}"
		sub_log_debug "...mysql_launch: --log=${__db_log_f}"
        sub_log_debug "...mysql_launch: --bind-address=${__db_addr} --port=${__db_port} --user=${__db_user}"
        # nohup
		/usr/bin/mysqld_safe --datadir="${__db_data_dir}" --socket="${__db_sock_f}" \
			--pid-file="${__db_pid_f}" --init-file="${__db_cnf_f}" --log="${__db_log_f}" \
			--bind-address=${__db_addr} --port=${__db_port} --user="${__db_user}" &
    else
		echo "1" > "${__g_mysql_pref_running}"
    fi
}

sub_mysql_kill()
{
    sub_log_debug "sub_mysql_kill() called"

	sub_mysql_is_running
    if ( test ${__g_pid} -eq 0 ); then
        sub_log_debug "...mysql_kill: mysqld not running -- aborted"
		return
    fi

	sub_log_debug "...mysql_kill: pid = ${__g_pid}"
    if ( test ${__g_test} -eq 0 ); then
		kill -TERM ${__g_pid}
    else
		rm -rf "${__g_mysql_pref_running}"
    fi
}

sub_mysql_is_running()
{
    # If available, mysqld process id value returned in __g_pid global
    # If mysqld process not active, __g_pid returns zero.
    sub_log_debug "sub_mysql_is_running() called"

    __g_pid=0

    if ( test ${__g_test} -eq 0 ); then
        sub_log_debug "...mysql_is_running: looking for pid file ${__db_pid_f}"
		if ( test -e "${__db_pid_f}" ); then
			local __pid=`cat "${__db_pid_f}"`
			sub_log_debug "...mysql_is_running: pid = ${__pid}"
			__status=`ps awwx | grep mysqld | grep ${__pid}`
			if ( test "${__status}" != "" ); then
				sub_log_debug "...mysql_is_running: running = YES"
				__g_pid=${__pid}
			else
				sub_log_debug "...mysql_is_running: running = NO"
			fi

		fi
		else 
		if ( test -e "${__g_mysql_pref_running}" ); then
			# generate fake pid for testing based on test state
			__g_pid=1000
		fi
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_check_db_installed - verify that the jabberd database exists
# arguments: --
# returns: 
#   __g_installed  1 = installed, 0 = not installed
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_check_db_installed()
{
    sub_log_debug "sub_check_db_installed() called"

	if ( test "x-${__jd2_db_engine}" == "x-mysql" ); then
        sub_mysql_is_db_installed;
    else
        sub_sqlite_is_db_installed;
    fi

    sub_log_debug "...installed = ${__g_installed}"    
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_install_db_data - initialiaze database storage for jabberd
# arguments: --
# returns: 
#   __g_installed  1 = installed, 0 = not installed (error)
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_install_db_data()
{
    sub_log_debug "sub_install_db_data() called"

    # launch custom mysqld for jabberd
    sub_check_db_installed
    if ( test ${__g_installed} -eq 0 ); then

        sub_log_debug "...install_db_data: installing database..."
		if ( test "x-${__jd2_db_engine}" == "x-mysql" ); then
			sub_mysql_make_dirs
			sub_mysql_init_db
			sub_mysql_set_host_and_password;
		else
			sub_sqlite_make_dirs
			sub_sqlite_install_data;
		fi

		sub_log_debug "...install_db_proc: verifying installation..."
		sub_check_db_installed
	fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_create_pid_dir - create jabber pid file directory
# arguments: --
# returns: --
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_create_pid_dir()
{
    sub_log_info "Creating additional jabberd directories..."
    sub_log_debug "...create_pid_dir: pid dir = ${__jd2_pid_dir}"
    if ( test ${__g_test} -eq 0 ); then
		mkdir -p -m 755 "${__jd2_pid_dir}"
		chown jabber:jabber "${__jd2_pid_dir}"
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_check_db_proc_state - query for current database process state
# arguments: --
# returns: 
#   __g_running  1 = running, 0 = stopped
#   __g_pid      if (__g_running==1), database process id
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_check_db_proc_state()
{
    sub_log_debug "sub_check_db_proc_state() called"

    __g_running=0

	if ( test "x-${__jd2_db_engine}" == "x-mysql" ); then
		sub_mysql_is_running
		if ( test ${__g_pid} -ne 0); then
			__g_running=1;
		fi; 
	else
		# SQLite is always "running"
		__g_running=1;
	fi

    sub_log_debug "...check_db_state: running = ${__g_running}; pid = ${__g_pid}"
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_wait_db_state - wait for database process to enter desired state
# arguments: ${1} = desired state of database process
#            ${2} = number of intervals to wait for new state
#            ${3} = number of seconds per wait interval
# returns: 
#   __g_running  1 = running, 0 = stopped
#   __g_pid      if (__g_running==1), database process id
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_wait_db_state()
{
    sub_log_debug "sub_wait_db_state() called"

    __new_db_state=${1}
    __max_waits=${2}
    __wait_secs=${3}

    __num_waits=${__max_waits}
    sub_log_debug "...wait_db_state: waiting for new database process state = ${__new_db_state}"
    while ( test ${__num_waits} -gt 0 ); do
		sub_check_db_proc_state
		sub_log_debug "...wait_db_state: process state = ${__g_running}"
		if ( test ${__g_running} -eq ${__new_db_state} ); then
			break
		fi
		sub_log_debug "...wait_db_state: waiting for new state = ${__new_db_state}; sleeping ${__wait_secs} seconds..."
		__num_waits=`expr ${__num_waits} - 1`
		sleep ${__wait_secs}
    done

    if ( test ${__g_running} -ne ${__new_db_state} ); then
		sub_log_debug "...wait_db_state: === ERROR === timeout waiting for process state change; current state = ${__g_running}"
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_wait_db_started - wait for database process to start up
# arguments: --
# returns: 
#   __g_running  1 = running, 0 = stopped
#   __g_pid      if (__g_running==1), database process id
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_wait_db_started()
{
    sub_wait_db_state 1 ${__g_wait_reps} ${__g_wait_secs}
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_wait_db_stopped - wait for database process to shut down
# arguments: --
# returns: 
#   __g_running  1 = running, 0 = stopped
#   __g_pid      if (__g_running==1), database process id
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_wait_db_stopped()
{
    sub_wait_db_state 0 ${__g_wait_reps} ${__g_wait_secs}
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_start_db_proc - query for current database process state
# arguments: --
#   __g_running  1 = running, 0 = stopped
#   __g_pid      if (__g_running==1), database process id
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_start_db_proc()
{
    sub_log_debug "sub_start_db_proc() called"

    # check if process is already running
    sub_check_db_proc_state
    if ( test ${__g_running} -eq 0 ); then
		# create jabberd pid directory
		sub_create_pid_dir
		# initialize mysql database for jabberd
		sub_install_db_data
		if ( test ${__g_installed} -eq 1 ); then
			if ( test "x-${__jd2_db_engine}" == "x-mysql" ); then
				# launch custom mysqld for jabberd
				sub_mysql_launch
				sub_wait_db_started
			fi
		fi
    fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_stop_db_proc - query for current database process state
# arguments: --
# returns: --
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_stop_db_proc()
{
    sub_log_debug "sub_stop_db_proc() called"

    # launch custom mysqld for jabberd
	if ( test "x-${__jd2_db_engine}" == "x-mysql" ); then
	    sub_check_db_proc_state
		if ( test ${__g_running} -eq 1 ); then
			sub_mysql_kill
			sub_wait_db_stopped
		fi
	fi
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_show_usage - display usage message
# arguments: --
# returns: --
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_show_usage()
{
    echo ""
    echo "usage: chatserverctl subcommand"
    echo "where subcommand is one of the following: "
    echo "   help     Display help message"
    echo "   install  Initialize database for iChat Service"
    echo "   status   Display iChat Service state (running/stopped)"
    echo "   start    Start iChat Service database process"
    echo "   stop     Stop iChat Service database process"
    echo ""
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_show_help - display help message
# arguments: --
# returns: --
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_show_help()
{
    echo ""
    echo "The ichatserverdbctl tool is used to control the database"
    echo "process associated with iChat Server.  This tool is provided"
    echo "to support other iChat Server administration tools and is not "
    echo "intended for general command line use."
    
    sub_show_usage
}

#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# sub_set_command - set the current command option
# arguments: ${1} command code
# returns: --
#   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
sub_set_command()
{
    #sub_log_debug "sub_set_command() called; cmd=${1}"

    if ( test "${__g_cmd}" == "-NONE-" ); then
	__g_cmd=${1}
    else
	echo "Error - options -i, -q, -s or -x may not be used together in a single command."
	sub_show_usage
	exit 1
    fi
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# script main
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    __g_running=0
    __g_pid=0
    __g_installed=0
    __g_debug=0
    __g_test=0

    __g_cmd="-NONE-"

    # parse command line options
    while ( test "x-${1}" != "x-" ); do
	case ${1} in
	    inst*)
		sub_set_command "-INDB-"
		;;
	    stat*)
		sub_set_command "-STAT-"
		;;
	    star*)
		sub_set_command "-STRT-"
		;;
	    sto*)
		sub_set_command "-STOP-"
		;;
	    help)
		sub_show_help
		exit 0
		;;
	    -d)
		__g_debug=1
		sub_log_debug "=== debug messages enabled ==="
		;;
	    -t)
		__g_test=1
		sub_log_debug "=== test-only enabled ==="
		;;
	    *)
		echo "Error -- unknown command option: ${1}"
		sub_show_usage
		exit 1
		;;
	esac
	shift
    done

    sub_log_debug "main(): command=${__g_cmd}"
    if ( test "${__g_cmd}" == "-NONE-" ); then
	echo "Error -- no action specified"
	sub_show_usage
	exit 1
    fi

    case ${__g_cmd} in
	"-INDB-")
	    sub_install_db_data
	    sub_stop_db_proc
	    if ( test ${__g_installed} -ne 1 ); then
		exit 1
	    fi
	    ;;
	"-STAT-")
	    sub_check_db_proc_state
	    if ( test ${__g_running} -eq 1 ); then
			echo "1" > "${__g_jd2_db_running}"
	    else
			rm -f "${__g_jd2_db_running}"
	    fi
	    ;;
	"-STRT-")
	    sub_start_db_proc
	    sub_check_db_proc_state
	    if ( test ${__g_running} -ne 1 ); then
		exit 1
	    fi
	    ;;
	"-STOP-")
		if ( test "x-${__jd2_db_engine}" == "x-mysql" ); then
			sub_stop_db_proc
			sub_check_db_proc_state
			if ( test ${__g_running} -ne 0 ); then
				exit 1
			fi
		fi
	    ;;
    esac

    sub_log_debug "main(): normal exit"
    
    exit 0