#!/bin/sh 
#
# $Id: sc,v 1.6.2.2 2006/02/15 19:52:22 bogdan_iancu Exp $
#
# sc: openser control; tool for maintaining openser
#
# History:
# --------
# 2003-02-23 Thomas's start|stop commands checked in
# 2003-09-08 multidomain features: usernames can now include domain 
#              names too (jiri)
# 2003-09-15 multidomain support completed (jiri)
# 2003-10-30 more debugging output, less copy and paste in
#             the previous item
# 2005-07-28 add support for lcr module (darilion)
#
# To-DO:
# -----
# - generalization for other than mysql databases
# - front-end to updating administrative mysql password would
#   be a convenient thing to have

#===================================================================
PATH=$PATH:/usr/local/sbin


### include resource files, if any
if [ -f /etc/openser/.openserctlrc ]; then
	. /etc/openser/.openserctlrc
fi
if [ -f /usr/local/etc/openser/.openserctlrc ]; then
	. /usr/local/etc/openser/.openserctlrc
fi
if [ -f ~/.openserctlrc ]; then
	. ~/.openserctlrc
fi

### version fo this script
VERSION='1.1 - $Revision: 1.6.2.2 $'

##### ------------------------------------------------ #####
### configuration for starting/stopping ser
if [ -z "$PID_FILE" ] ; then
	PID_FILE=/var/run/openser.pid
fi
if [ -z "$SYSLOG" ] ; then
	SYSLOG=1 # 0=output to console, 1=output to syslog
fi
if [ -z "$STARTOPTIONS" ] ; then
	STARTOPTIONS= # for example -dddd
fi
if [ -z "$DIR" ] ; then
	DIR=/usr/sbin
fi
if [ -z "$SERBIN" ] ; then
	SERBIN=$DIR/openser
fi
if [ -z "$SIP_DOMAIN" ] ; then
	SIP_DOMAIN=$(nvram get sip_domain)
fi


##### ----------------------------------------------- #####
### openser's FIFO server
if [ -z "$SER_FIFO" ]; then
	SER_FIFO=/tmp/openser_fifo
fi
# period in which stats are reprinted
if [ -z "$WATCH_PERIOD" ] ; then
	WATCH_PERIOD=2
fi

##### ----------------------------------------------- #####
### SQL config
if [ -z "$SQL_DB" ] ; then
	SQL_DB=openser
fi
if [ -z "$SQL_HOST" ] ; then
	SQL_HOST=localhost
fi
if [ -z "$SQL_USER" ] ; then
	SQL_USER=openser
fi

# the read-only user for whom password may be stored here
if [ -z "$RO_USER" ] ; then
	RO_USER=openserro
fi
if [ -z "$RO_PW" ] ; then
	RO_PW=openserro
fi

##### ----------------------------------------------- #####
### binaries
if [ -z "$GENHA1" ] ; then
	GENHA1='openser_gen_ha1'
fi
if [ -z "$MYSQL" ] ; then
	MYSQL='mysql'
fi
if [ -z "$SER" ] ; then
	SER='openser'
fi
if [ -z "$LAST_LINE" ] ; then
	LAST_LINE='tail -1'
fi

##### ----------------------------------------------- #####
### path to useful tools
if [ -z "$EGREP" ] ; then
	EGREP="egrep"
fi
if [ -z "$AWK" ] ; then
	AWK="awk"
fi

##### ----------------------------------------------- #####
# ACL name verification
if [ -z "$VERIFY_ACL" ] ; then
	VERIFY_ACL=1
fi
if [ -z "$ACL_GROUPS" ] ; then
	ACL_GROUPS="local ld int voicemail free-pstn prepaid"
fi

# fifo dbg
if [ -z "$FIFO_DBG" ] ; then
	FIFO_DBG=0
fi

##### ----------------------------------------------- #####
#### SQL names

# UsrLoc Table
if [ -z "$UL_TABLE" ] ; then
	UL_TABLE=location
fi
USER_COLUMN=username
CALLID_COLUMN=callid

# subscriber table
if [ -z "$SUB_TABLE" ] ; then
	SUB_TABLE=subscriber
fi
REALM_COLUMN=domain
HA1_COLUMN=HA1
HA1B_COLUMN=HA1B
PASSWORD_COLUMN=password
RPID_COLUMN=rpid
SUBSCRIBER_COLUMN='username'
EMAIL_COLUMN=email_address
SUB_CREATED_COLUMN=datetime_created
SUB_MODIFIED_COLUMN=datetime_modified
PHP_LIB_COLUMN=phplib_id

# acl table
if [ -z "$ACL_TABLE" ] ; then
	ACL_TABLE=grp
fi
ACL_USER_COLUMN=username
ACL_DOMAIN_COLUMN=domain
ACL_GROUP_COLUMN=grp
ACL_MODIFIED_COLUMN=last_modified
ACL_DOMAIN_COLUMN=domain

# aliases table
if [ -z "$ALS_TABLE" ] ; then
	ALS_TABLE=aliases
fi
A_USER_COLUMN=username
A_CONTACT_COLUMN=contact
A_EXPIRES_COLUMN=expires
A_Q_COLUMN=q
A_CALLID_COLUMN=callid
A_CSEQ_COLUMN=cseq
A_LAST_MODIFIED_COLUMN=last_modified

# domain table
if [ -z "$DOMAIN_TABLE" ] ; then
	DOMAIN_TABLE=domain
fi

# lcr tables
if [ -z "$LCR_TABLE" ] ; then
	LCR_TABLE=lcr
fi
if [ -z "$GW_TABLE" ] ; then
	GW_TABLE=gw
fi
if [ -z "$GW_GRP_TABLE" ] ; then
	GW_GRP_TABLE=gw_grp
fi

# URI table
if [ -z "$URI_TABLE" ] ; then
	URI_TABLE=uri
fi
URIUSER_COLUMN=uri_user
MODIFIED_COLUMN=last_modified

# dbaliases table
if [ -z "$DA_TABLE" ] ; then
	DA_TABLE=dbaliases
fi
DA_USER_COLUMN=username
DA_DOMAIN_COLUMN=domain
DA_ALIAS_USER_COLUMN=alias_username
DA_ALIAS_DOMAIN_COLUMN=alias_domain

# speeddial table
if [ -z "$SD_TABLE" ] ; then
	SD_TABLE=speed_dial
fi
SD_USER_COLUMN=username
SD_DOMAIN_COLUMN=domain
SD_SD_USER_COLUMN=sd_username
SD_SD_DOMAIN_COLUMN=sd_domain
SD_NEW_URI_COLUMN=new_uri
SD_DESC_COLUMN=description

# avp table
if [ -z "$AVP_TABLE" ] ; then
	AVP_TABLE=usr_preferences
fi

AVP_UUID_COLUMN=uuid
AVP_USER_COLUMN=username
AVP_DOMAIN_COLUMN=domain
AVP_ATTRIBUTE_COLUMN=attribute
AVP_VALUE_COLUMN=value
AVP_TYPE_COLUMN=type
AVP_MODIFIED_COLUMN=modified

#===================================================================

usage_alias_db() {
	if [ "$1" = "alone" ] ; then 
		CMD=`basename $0`
		echo "$0 $VERSION"
		echo
		echo "'alias_db' command line options:"
		echo
	fi
cat <<EOF
 alias_db show <alias> .............. show alias details
 alias_db list <sip-id> ............. list aliases for uri
 alias_db add <alias> <sip-id> ...... add an alias (*)
 alias_db rm <alias> ................ remove an alias (*)
 alias_db help ...................... help message
EOF
	if [ "$1" = "alone" ] ; then 
		echo
		echo "    - <alias> must be an AoR (username@domain)"
		echo "    - <sip-id> must be an AoR (username@domain)"
		echo
	fi
}

usage_speeddial() {
	if [ "$1" = "alone" ] ; then 
		CMD=`basename $0`
		echo "$0 $VERSION"
		echo
		echo "'speeddial' command line options:"
		echo
	fi
cat <<EOF
 speeddial show <speeddial-id> ....... show speeddial details
 speeddial list <sip-id> ............. list speeddial for uri
 speeddial add <sip-id> <sd-id> <new-uri> [<desc>] ... add a speedial (*)
 speeddial rm <sip-id> <sd-id> ....... remove a speeddial (*)
 speeddial help ...................... help message
EOF
	if [ "$1" = "alone" ] ; then 
		echo
		echo "    - <speeddial-id>, <sd-id> must be an AoR (username@domain)"
		echo "    - <sip-id> must be an AoR (username@domain)"
		echo "    - <new-uri> must be a SIP AoR (sip:username@domain)"
		echo "    - <desc> a description for speeddial"
		echo
	fi
}

usage_avp() {
	if [ "$1" = "alone" ] ; then 
		CMD=`basename $0`
		echo "$0 $VERSION"
		echo
		echo "'avp' command line options:"
		echo
	fi
cat <<EOF
 avp list [-T table] [-u <sip-id|uuid>]
     [-a attribute] [-v value] [-t type] ... list AVPs
 avp add [-T table] <sip-id|uuid>
     <attribute> <type> <value> ............ add AVP (*)
 avp rm [-T table]  [-u <sip-id|uuid>]
     [-a attribute] [-v value] [-t type] ... remove AVP (*)
 avp help .................................. help message
EOF
	if [ "$1" = "alone" ] ; then 
		echo
		echo "    - -T - table name"
		echo "    - -u - SIP id or unique id"
		echo "    - -a - AVP name"
		echo "    - -v - AVP value"
		echo "    - -t - AVP name and type (0 (str:str), 1 (str:int),"
		echo "                              2 (int:str), 3 (int:int))"
		echo
		echo "    - <sip-id> must be an AoR (username@domain)"
		echo "    - <uuid> must be a string but not AoR"
		echo
	fi
}

usage() {
CMD=`basename $0`
if [ "0$VERIFY_ACL" -eq 1 ] ; then
	EXTRA_TEXT="ACL privileges are: $ACL_GROUPS"
fi
cat <<EOF
$0 $VERSION
parameter usage: 
           * subscribers *
 add <username> <password> <email> .. add a new subscriber (*)
 passwd <username> <passwd> ......... change user's password (*)
 rm <username> ...................... delete a user (*)
 mail <username> .................... send an email to a user

 alias show [<alias>] ............... show aliases
 alias rm <alias> ................... remove an alias
 alias add <alias> <uri> ............ add an aliases

 rpid add <username> <rpid> ......... add rpid for a user (*)
 rpid rm <username> ................. set rpid to NULL for a user (*)
 rpid show <username> ............... show rpid of a user
EOF

 echo
 usage_alias_db
 echo
 usage_speeddial
 echo
 usage_avp
 echo

cat <<EOF
           * access control lists *
 acl show [<username>] .............. show user membership
 acl grant <username> <group> ....... grant user membership (*)
 acl revoke <username> [<group>] .... grant user membership(s) (*)

           * usrloc *
 ul show [<username>]................ show in-RAM online users
 ul rm <username> [<contact URI>].... delete user's UsrLoc entries
 ul add <username> <uri> ............ introduce a permanent UrLoc entry
 showdb [<username>] ................ show online users flushed in DB

           * pa *
 pa pres <p_uri> <pstate>............ set pstate for a presentity
 pa loc <p_uri> <loc>................ set location for a presentity

           * domains *
 domain show ........................ show list of served domains
 domain add <domainname> ............ add a new served domain
 domain rm <domainname> ............. remove a served domain

           * lcr *
   * IP addresses must be entered in dotted quad format e.g. 1.2.3.4 *
   * <uri_scheme> and <transport> must be entered in integer or text,*
   * e.g. transport '2' is identical to transport 'tcp'.             *
   *   scheme: 1=sip, 2=sips;   transport: 1=udp, 2=tcp, 3=tls       *
   * Examples:  serctl lcr addgw_grp usa 1                           *
   *            serctl lcr addgw level3 1.2.3.4 5080 sip tcp 1       *
   *            serctl lcr addroute +1 % 1 1                         *
 lcr show ...................................... show routes, gateways and groups
 lcr reload .................................... reload lcr gateways
 lcr addgw_grp <grp_name> ...................... add gateway group, autocreate grp_id
 lcr addgw_grp <grp_name> <grp_id> ............. add gateway group with grp_id
 lcr rmgw_grp  <grp_id> ........................ delete the gw_grp
 lcr addgw <gw_name> <ip> <port> <scheme> <transport> <grp_id> ........... add a gateway
 lcr addgw <gw_name> <ip> <port> <scheme> <transport> <grp_id> <prefix> .. add a gateway with prefix
 lcr rmgw  <gw_name> ..................................................... delete a gateway
 lcr addroute <prefix> <from> <grp_id> <prio> .. add a route
 lcr rmroute  <prefix> <from> <grp_id> <prio> .. delete a route

           * control and diagnostics *
 moni ... show internal status      start .... start ser
 ps ..... show runnig processes     stop ..... stop ser
 fifo ... send raw FIFO commands    restart .. restart ser
 ping <uri> .. ping a URI (OPTIONS)
 cisco_restart <uri> .. restart a Cisco phone (NOTIFY)


   Commands labeled with (*) will prompt for a MySQL password.
   If the variable PW is set, the password will not be prompted.

     $EXTRA_TEXT
EOF
}


# determine host name, typically for use in printing UAC
# messages; we use today a simplistic but portable uname -n way --
# no domain name is displayed ; fifo_uac expands !! to host
# address only for optional header fields; uname output without
# domain is sufficient for informational header fields such as
# From
#
get_my_host() {
	uname -n
}

# calculate name and domain of current user
set_user() {

	SERUSER=`echo $1|awk -F @ '{print $1}'`
	SERDOMAIN=`echo $1|awk -F @ '{print $2}'`

	if [ -z "$SERDOMAIN" ] ; then
		SERDOMAIN="$SIP_DOMAIN"
	fi

	if [ -z "$SERDOMAIN" ] ; then
		echo "domain unknown: use usernames with domain or set default domain in SIP_DOMAIN (with 'nvram set sip_domain=YOUR_SIP_DOMAIN')"
		exit 1
	fi
}


# check the parameter if it is a valid address of record (user@domain)
check_aor() {
	echo "$1" | $EGREP "^[a-zA-Z0-9_\.]+@.*\..*" >/dev/null
	if [ $? -ne 0 ] ; then 
		echo "error: invalid AoR: $1" > /dev/stderr
		exit 1
	fi
}

# check the parameter if it is a valid address of record (user@domain)
is_aor() {
	echo "$1" | $EGREP "^[a-zA-Z0-9_\.]+@.*\..*" >/dev/null
	if [ $? -ne 0 ] ; then 
		false
	else
		true
	fi
}

# check the parameter if it is a valid SIP address of record (sip:user@domain)
check_sipaor() {
	echo "$1" | $EGREP "^sip(s)?:[a-zA-Z0-9_\.]+@.*\..*" >/dev/null
	if [ $? -ne 0 ] ; then 
		echo "error: invalid SIP AoR: $1" > /dev/stderr
		exit 1
	fi
}

# check the parameter if it is a valid SIP URI
# quite simplified now -- it captures just very basic
# errors
check_uri() {
	echo "$1" | $EGREP "^sip(s)?:([a-zA-Z0-9_]+@)?.*\..*"  > /dev/null
	if [ $? -ne 0 ] ; then 
		echo "error: invalid SIP URI: $1" > /dev/stderr
		exit 1
	fi
}

# check for alias duplicates
check_alias() {
		RES=`fifo_cmd ul_show_contact "$ALS_TABLE" "$1"`
		RET="$?"
		if [ $RET -ne 0 ] ; then
			echo "error: OpenSER/FIFO not accessible: $RET" \
				> /dev/stderr
			exit 1
		fi
		echo "$RES" | grep "^404" > /dev/null
		if [ $? -eq 0 ] ; then
			# alias does not exist yet, go ahead!
			return 0
		fi
		echo "$RES" | grep "^400" > /dev/null
		if [ $? -eq 0 ] ; then
			echo "error: 400; check if you use aliases in OpenSER" \
				> /dev/stderr
			exit 1
		fi
		echo "$RES" | grep "^200" > /dev/null
		if [ $? -eq 0 ] ; then
			echo "error: overlap with an existing alias" \
				> /dev/stderr
			exit 1
		fi
		# other errors
		echo "error: $RES" > /dev/stderr
		exit 1
}


#params: none
# output: PW
prompt_pw() {
	if [ -z "$PW" ] ; then
		savetty=`stty -g`
		printf "MySql password: " > /dev/stderr
		stty -echo
    	read PW
		stty $savetty
    	echo
	fi
}

print_status() {
	echo $1 | grep "^[1-6][0-9][0-9]" > /dev/null
	if [ "$?" -eq 0 ] ; then 
		echo $1
	else
		echo "200 OK"
	fi
}

# process output from FIFO server; if everything is ok
# skip the first "ok" line and proceed to returned 
# parameters
filter_fl()
{
#	tail +2
	
	awk 'BEGIN {line=0;IGNORECASE=1;}
		{line++}
		line==1 && /^200 ok/ { next }
		{ print }'
}


fifo_cmd()
{
	if [ "0${FIFO_DBG}" -eq 1 ] ; then
		echo "entering fifo_cmd $*"
	fi
	if [ "$#" -lt 1 ]; then
		echo "ERROR: fifo_cmd must take at least command name as parameter"
		exit 1
	fi
	name=ser_receiver_$$
	path=/tmp/$name
	if [ ! -w $SER_FIFO ]; then
		echo "Error opening openser's FIFO $SER_FIFO"
		echo "Make sure you have line fifo=$SER_FIFO in your config"
		exit 2
	fi
	mkfifo $path
	if [ $? -ne 0 ] ; then
		echo "error opening read fifo $path"
		exit 3
	fi
	chmod a+w $path

	# construct the command now
	CMD=":$1:$name\n";
	shift
	while [ -n "$1" ] ; do
		CMD="${CMD}${1}\n"
		shift
	done
	CMD="${CMD}\n"

	trap "rm -f $path; kill 0" 2

	# start reader now so that it is ready for replies
	# immediately after a request was sent out
	cat < $path | filter_fl &

	# issue FIFO request (printf taken to deal with \n)
	printf "$CMD" > $SER_FIFO

	# wait for the reader to complete
	wait
	rm $path

	if [ "0${FIFO_DBG}" -eq 1 ] ; then
		printf "FIFO command was:\n$CMD"
	fi
}


# $1 = name $2=path $3=attempt
print_stats() {

echo "[cycle #: $3; if constant make sure server lives and fifo is on]"

cat < $2 | filter_fl &
cat > $SER_FIFO <<EOF
:version:$1

EOF
wait

cat < $2 | filter_fl &
cat > $SER_FIFO << EOF
:uptime:$1

EOF
wait
echo

echo Transaction Statistics
cat < $2 | filter_fl &
cat > $SER_FIFO <<EOF
:t_stats:$1

EOF
wait
echo

echo Stateless Server Statistics
cat < $2 | filter_fl &
cat > $SER_FIFO <<EOF
:sl_stats:$1

EOF
wait
echo

echo UsrLoc Stats
cat < $2 | filter_fl &
cat > $SER_FIFO <<EOF
:ul_stats:$1

EOF
wait
}


# input: sql query, optional mysql command-line params
sql_query() {
	# if password not yet queried, query it now
	if [ -z "$PW" ] ; then
		savetty=`stty -g`
		printf "MySql password for user '$SQL_USER@$SQL_HOST': " > /dev/stderr
		stty -echo
    	read PW >&2
		stty $savetty
    	echo >&2
	fi
	$MYSQL $2 -h $SQL_HOST -u $SQL_USER "-p$PW" -e "$1 ;" $SQL_DB
}

# input: sql query, optional mysql command-line params
sql_ro_query() {
	$MYSQL $2 -h $SQL_HOST -u $RO_USER "-p$RO_PW" \
		-e "$1 ;" $SQL_DB
}


usrloc() {
	if [ "$#" -lt 2 ] ; then
		echo "usrloc: too few parameters"
		exit 1
	fi
	if [ "$1" = "alias" ] ; then
		USRLOC_TABLE="$ALS_TABLE"
		CHECK_SUB=1
	elif [ "$1" = "ul" ] ; then
		USRLOC_TABLE="$UL_TABLE"
		CHECK_SUB=0
	else
		echo "usrloc: unknown table name"
		exit 1
	fi
	shift

	case $1 in 
		show)
			if [ $# -eq 2 ] ; then
				set_user $2
				fifo_cmd ul_show_contact $USRLOC_TABLE "$SERUSER@$SERDOMAIN"
			elif [ $# -eq 1 ] ; then
				fifo_cmd ul_dump
			else
				echo "wrong number of params for usrloc show"
				usage
				exit 1
			fi
			exit $?
			;;
		add)
			if [ $# -ne 3 ] ; then
				usage
				exit 1
			fi
			shift
			check_uri "$2"
			set_user $1
				
			if [ "$?" -ne "0" ] ; then
				echo "$2 is not a valid URI"
				exit 1
			fi

			if [ "$CHECK_SUB" -ne 0 ] ; then
				is_user $1 
				if [ $? -eq 0 ] ; then
					echo overlap of alias with an existing subscriber name
					exit 1;
				fi
			fi

			check_alias "$SERUSER@$SERDOMAIN"

			# 128 means FL_PERSISTENT is on
			fifo_cmd ul_add "$USRLOC_TABLE" "$SERUSER@$SERDOMAIN" "$2" "0" "1.00" "0" "128"
			exit $?
			;;
		rm)
			if [ $# -eq 2 ] ; then
				shift
				set_user $1
				fifo_cmd ul_rm $USRLOC_TABLE "$SERUSER@$SERDOMAIN"

			elif [ $# -eq 3 ] ; then
				shift
				set_user $1
				check_uri "$2"
				if [ "$?" -ne "0" ] ; then
					echo "ul rm: $2 is not a valid SIP URI (sip:[user@]domain)"
                                exit 1
                        fi

				fifo_cmd ul_rm_contact $USRLOC_TABLE "$SERUSER@$SERDOMAIN" "$2"

			else
				echo "wrong number of params"
				usage
				exit 1
			fi
			;;

		*)
			usage
			exit 1
			;;
	esac
}

presence_agent() {
	if [ "$#" -lt 4 ] ; then
		echo "pa: too few parameters"
		# usage
		# exit 1
	fi

	shift
	case $1 in 
		loc)
			shift
			# check_uri "$1"
			if [ "$?" -ne "0" ] ; then
				echo "$1 is not a valid URI"
				exit 1
			fi

			fifo_cmd pa_location "registrar" "$1" "$2"
			exit $?
			;;
		pres)
			shift
			# check_uri "$1"
			if [ "$?" -ne "0" ] ; then
				echo "$1 is not a valid URI"
				exit 1
			fi

			fifo_cmd pa_presence "registrar" "$1" "$2"
			exit $?
			;;
		*)
			usage
			exit 1
			;;
	esac
}

rpid() {
	if [ "$#" -lt 2 ] ; then
		echo "rpid: too few parameters"
		exit 1
	fi
        shift;

	case $1 in
		show)
			if [ $# -eq 2 ] ; then
				set_user $2
				is_user $2 
				if [ $? -ne 0 ] ; then
					echo non-existent user
					exit 1;
				fi
				CLAUSE=" WHERE $SUBSCRIBER_COLUMN='$SERUSER' AND $REALM_COLUMN='$SERDOMAIN' "
			elif [ $# -ne 1 ] ; then
				usage
				exit 1
			fi
			QUERY="select $SUBSCRIBER_COLUMN, $RPID_COLUMN FROM $SUB_TABLE $CLAUSE ; "
			sql_ro_query "$QUERY"
			;;

		add|rm)
		        MODE=$1;

			if [ "$MODE" == "add" ] ; then
			    ARG_NUM=3;
			else
			    ARG_NUM=2;
			fi
			
			if [ $# -lt $ARG_NUM ] ; then
				usage
				exit 1
			fi

			prompt_pw
			set_user $2
			is_user $2 
			if [ $? -ne 0 ] ; then
				echo non-existent user
				exit 1
			fi
			shift 2

			if [ "$MODE" = "add" ] ; then
			        RPID_VAL="'$1'";
			else
			        RPID_VAL=NULL;
			fi

			QUERY="UPDATE $SUB_TABLE \
                	SET $RPID_COLUMN=$RPID_VAL \
                	WHERE $SUBSCRIBER_COLUMN='$SERUSER' AND $REALM_COLUMN='$SERDOMAIN';"
				sql_query "$QUERY"
				if [ $? -ne 0 ] ; then
					echo "SQL Error"
					exit 1
				fi

			$0 rpid show $SERUSER@$SERDOMAIN

			;;

		*)
			usage
			exit 1
			;;
	esac
}

domain() {
	case $1 in
		show)
			# QUERY="select * FROM $DOMAIN_TABLE ; "
			# sql_ro_query "$QUERY"
			fifo_cmd domain_dump
			;;
		add)
			shift
			if [ $# -ne 1 ] ; then
				echo missing domain to be added
				exit 1
			fi
			prompt_pw
       		QUERY="insert into $DOMAIN_TABLE (domain) VALUES ('$1');"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd domain_reload
			;;
		rm)
			shift
			if [ $# -ne 1 ] ; then
				echo missing domain to be removed
				exit 1
			fi
			prompt_pw
       		QUERY="delete from $DOMAIN_TABLE where domain='$1';"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd domain_reload
			;;
		*)
			usage
			exit 1
	esac
}

lcr() {
	case $1 in
		show)
			echo lcr routes
			QUERY="select * FROM $LCR_TABLE ORDER BY prefix; "
			sql_ro_query "$QUERY"
			echo lcr gateway groups
			QUERY="select * FROM $GW_GRP_TABLE ORDER BY grp_id; "
			sql_ro_query "$QUERY"
			echo lcr gateways
			#QUERY="select * FROM $GW_TABLE ORDER BY grp_id; "
			QUERY="select gw_name, CONCAT(ip_addr, ' (',
					CONCAT_WS('.',floor(ip_addr - floor(ip_addr/16777216)*16777216 - floor((ip_addr - floor(ip_addr/16777216)*16777216)/65536)*65536 - floor((ip_addr - floor(ip_addr/16777216)*16777216 - floor((ip_addr - floor(ip_addr/16777216)*16777216)/65536)*65536)/256)*256),
						floor((ip_addr - floor(ip_addr / 16777216) * 16777216 - floor((ip_addr - floor(ip_addr / 16777216) * 16777216) / 65536) * 65536) / 256),
						floor((ip_addr - floor(ip_addr / 16777216) * 16777216) / 65536),
						floor(ip_addr / 16777216) ), ') ') as ip, 
				port, uri_scheme, transport, grp_id, prefix
				FROM $GW_TABLE ORDER BY grp_id; "
			sql_ro_query "$QUERY"
			;;
		reload)
			fifo_cmd lcr_reload
			;;
		addgw_grp)
			shift
			if [ $# -lt 1 ] ; then
				echo too few paramters
				usage
				exit 1
			fi
			if [ $# -gt 1 ] ; then
				GRP_ID=$2
			else
				GRP_ID=NULL
			fi
			prompt_pw
			QUERY="insert into $GW_GRP_TABLE VALUES ($GRP_ID, '$1');"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd lcr_reload
			;;
		rmgw_grp)
			shift
			if [ $# -ne 1 ] ; then
				echo missing grp_id to be removed
				exit 1
			fi
			prompt_pw
			QUERY="delete from $GW_GRP_TABLE where grp_id=$1;"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd lcr_reload
			;;
		addroute)
			shift
			if [ $# -ne 4 ] ; then
				echo too few paramters
				usage
				exit 1
			fi
			prompt_pw
			QUERY="insert into $LCR_TABLE VALUES ('$1', '$2', $3, $4);"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd lcr_reload
			;;
		rmroute)
			shift
			if [ $# -ne 4 ] ; then
				echo too few paramters
				usage
				exit 1
			fi
			prompt_pw
			QUERY="delete from $LCR_TABLE where prefix='$1' AND from_uri='$2' AND grp_id=$3 AND priority=$4;"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd lcr_reload
			;;
		addgw)
			shift
			if [ $# -lt 6 ] ; then
				echo too few paramters
				usage
				exit 1
			fi
			if [ $# -gt 6 ] ; then
				GW_PREFIX=$7
			else
				GW_PREFIX=""
			fi
			GW_NAME=$1
			GW_PORT=$3
			GW_URI_SCHEME=$4
			if   [ $GW_URI_SCHEME = 'sip' ]; then
				GW_URI_SCHEME=1
			elif [ $GW_URI_SCHEME = 'sips' ]; then
				GW_URI_SCHEME=2
			fi
			GW_TRANSPORT=$5
			if   [ $GW_TRANSPORT = 'udp' ]; then
				GW_TRANSPORT=1
			elif [ $GW_TRANSPORT = 'tcp' ]; then
				GW_TRANSPORT=2
			elif [ $GW_TRANSPORT = 'tls' ]; then
				GW_TRANSPORT=3
			fi
			GW_GRP_ID=$6
			oldIFS=$IFS
			IFS=.
			set -- $2
			GW_IP=$(($1+$2*256+$3*65536+$4*16777216))
			IFS=$oldIFS
			prompt_pw
			QUERY="insert into $GW_TABLE VALUES ('$GW_NAME', $GW_GRP_ID, $GW_IP, $GW_PORT, $GW_URI_SCHEME, $GW_TRANSPORT, '$GW_PREFIX');"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd lcr_reload
			;;
		rmgw)
			shift
			if [ $# -ne 1 ] ; then
				echo missing gateway to be removed
				exit 1
			fi
			prompt_pw
			QUERY="delete from $GW_TABLE where gw_name='$1';"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "SQL Error"
				exit 1
			fi
			fifo_cmd lcr_reload
			;;
		*)
			usage
			exit 1
	esac
}

acl() {
	case $1 in
		show)
			if [ $# -eq 2 ] ; then
				set_user $2
				is_user $2 
				if [ $? -ne 0 ] ; then
					echo non-existent user
					exit 1;
				fi
				CLAUSE=" WHERE $ACL_USER_COLUMN='$SERUSER' AND $ACL_DOMAIN_COLUMN='$SERDOMAIN' "
			elif [ $# -ne 1 ] ; then
				usage
				exit 1
			fi
			QUERY="select * FROM $ACL_TABLE $CLAUSE ; "
			sql_ro_query "$QUERY"

			;;

		grant)
			if [ $# -lt 3 ] ; then
				usage
				exit 1
			fi
			prompt_pw
			set_user $2
			is_user $2 
			if [ $? -ne 0 ] ; then
				echo non-existent user
				exit 1
			fi
			shift 2
			while [ $# -gt 0 ] ; do

				if [ $VERIFY_ACL -eq 1 ] ; then
					found=0
					for i in $ACL_GROUPS ; do
						if [ "$1" = "$i" ] ; then
							found=1
							break
						fi
					done	
					if [ $found -eq 0 ] ; then
						echo "Invalid privilege: $1 ignored"
						shift
						continue
					fi
				fi

        		QUERY="insert into $ACL_TABLE \
                	($ACL_USER_COLUMN,$ACL_GROUP_COLUMN,$ACL_MODIFIED_COLUMN, $ACL_DOMAIN_COLUMN ) \
                	values ('$SERUSER','$1', now(), '$SERDOMAIN' );"
				sql_query "$QUERY"
				if [ $? -ne 0 ] ; then
					echo "SQL Error"
					exit 1
				fi
				shift
			done

			$0 acl show $SERUSER@$SERDOMAIN

			;;

		revoke)
			if [ $# -eq 3 ] ; then
				CLAUSE=" and $ACL_GROUP_COLUMN='$3' "
			elif [ $# -ne 2 ] ; then
				usage
				exit 1
			fi	

			set_user $2

			QUERY="delete from $ACL_TABLE where \
				$ACL_TABLE.$ACL_USER_COLUMN='$SERUSER' AND $ACL_DOMAIN_COLUMN='$SERDOMAIN' $CLAUSE"
			sql_query "$QUERY"

			$0 acl show $2

			;;

		*)
			usage
			exit 1
			;;
	esac
}

# params: user
# output: false if exists, true otherwise
is_user() {
	set_user $1
	
	QUERY="select count(*) from $SUB_TABLE \
		where $SUBSCRIBER_COLUMN='$SERUSER' and $REALM_COLUMN='$SERDOMAIN';"
	CNT=`sql_ro_query "$QUERY" | grep -v ERROR | $LAST_LINE`
	if [ "0$CNT" -eq 0 ] ; then
		false
	else
		true
	fi
}

# params: user
# output: false if exists, true otherwise
is_alias_db()
{
	set_user $1
	
	QUERY="select count(*) from $DA_TABLE \
		where $DA_ALIAS_USER_COLUMN='$SERUSER' and $DA_ALIAS_DOMAIN_COLUMN='$SERDOMAIN';"
	CNT=`sql_ro_query "$QUERY" | grep -v ERROR | $LAST_LINE`
	if [ "0$CNT" -eq 0 ] ; then
		false
	else
		true
	fi
}

# params: user, password
# output: HA1, HA1B
credentials()
{
	set_user $1

	HA1=`$GENHA1 $SERUSER $SERDOMAIN $2`
	if [ $? -ne 0 ] ; then
		echo "HA1 calculation failed"
		exit 1
	fi
	HA1B=`$GENHA1 "$SERUSER@$SERDOMAIN" $SERDOMAIN $2`
	if [ $? -ne 0 ] ; then
		echo "HA1B calculation failed"
		exit 1
	fi
}

# db-based aliases
dbaliases() {
	if [ "$#" -lt 2 ] ; then
		echo "alias_db: error - too few parameters"
		echo
		usage
		exit 1
	fi
	if [ "$1" = "alias_db" ] ; then
		shift
	else
		echo "alias_db: error - unknown command $1"
		echo
		usage
		exit 1
	fi

	case $1 in 
		list)
			if [ $# -eq 2 ] ; then
				# print aliases for user
				check_aor "$2"
				if [ "$?" -ne "0" ] ; then
					echo "alias_db: <$2> is not a valid AoR (user@domain)"
					exit 1
				fi
				
				set_user $2
				
				CLAUSE="WHERE $DA_USER_COLUMN='$SERUSER'  AND $DA_DOMAIN_COLUMN='$SERDOMAIN'"
				echo "Dumping aliases for user=<$2>"
				echo
				QUERY="SELECT $DA_ALIAS_USER_COLUMN, $DA_ALIAS_DOMAIN_COLUMN FROM $DA_TABLE $CLAUSE;"
				sql_ro_query "$QUERY" | $AWK 'BEGIN {line=0;}
											/^\+/ { next }
											{	if(line==0) print "ALIASES";
												else print line ")\t" $1 "@" $2;
												line++; }'
			elif [ $# -eq 1 ] ; then
				printf "Dumping all aliases may take long: do you want to proceed? [Y|N] "
				read answer
				if [ "$answer" = "y" -o "$answer" = "Y" ] ; then
					echo "Dumping all aliases..."
					echo
				else
					exit 1
				fi
				QUERY="SELECT $DA_ALIAS_USER_COLUMN, $DA_ALIAS_DOMAIN_COLUMN, $DA_USER_COLUMN, $DA_DOMAIN_COLUMN FROM $DA_TABLE;"
				sql_ro_query "$QUERY" | $AWK 'BEGIN {line=0;}
										/^\+/ { next }
										{	line++;
											if(line==1) print "SIP-ID               \tALIAS\n";
											else print $3 "@" $4 "\t" $1 "@" $2 }'
			else
				echo "alias_db: wrong number of params for command [list]"
				usage
				exit 1
			fi

			exit $?
			;;
		show)
			if [ $# -ne 2 ] ; then
				echo "alias_db: wrong number of params for command [show]"
				usage
				exit 1
			fi
			
			check_aor "$2"
			if [ "$?" -ne "0" ] ; then
				echo "alias_db: $2 is not a valid AoR (user@domain)"
				exit 1
			fi
			
			set_user $2
			
			CLAUSE="WHERE $DA_ALIAS_USER_COLUMN='$SERUSER' AND $DA_ALIAS_DOMAIN_COLUMN='$SERDOMAIN'"
			QUERY="SELECT $DA_USER_COLUMN, $DA_DOMAIN_COLUMN FROM $DA_TABLE $CLAUSE ; "
			TMP_UUID=`sql_ro_query "$QUERY" | $AWK 'BEGIN {line=0;} /^\+/ { next } 
												{ line++; if(line==2) print $1 "@" $2;}'`

			if [ "$TMP_UUID" = "" ] ; then
				echo "non-existent alias <$2>"
				exit 1
			fi
			
			echo "Details for alias <$2>"
			echo
			echo "SIP-ID: $TMP_UUID"
			echo
			exit $?
			;;
		add)
			if [ $# -ne 3 ] ; then
				usage
				exit 1
			fi
			shift
			check_aor "$1"
			if [ "$?" -ne "0" ] ; then
				echo "alias_db: $1 is not a valid AoR (user@domain)"
				exit 1
			fi

			check_aor "$2"
			if [ "$?" -ne "0" ] ; then
				echo "alias_db: $2 is not a valid AoR (user@domain)"
				exit 1
			fi
			
			set_user $1
			TMP_SERUSER=$SERUSER
			TMP_SERDOMAIN=$SERDOMAIN
			set_user $2
			
			QUERY="INSERT INTO $DA_TABLE \
				($DA_USER_COLUMN,$DA_DOMAIN_COLUMN,$DA_ALIAS_USER_COLUMN,$DA_ALIAS_DOMAIN_COLUMN) \
                    VALUES ('$SERUSER','$SERDOMAIN','$TMP_SERUSER','$TMP_SERDOMAIN' );"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "alias_db: SQL Error"
				exit 1
			fi
			
			exit $?
			;;
		rm)
			if [ $# -ne 2 ] ; then
				usage
				exit 1
			fi
			
			shift
			
			check_aor "$1"
			if [ "$?" -ne "0" ] ; then
				echo "alias_db: $1 is not a valid URI"
				exit 1
			fi

			set_user $1
			CLAUSE="WHERE $DA_ALIAS_USER_COLUMN='$SERUSER' AND $DA_ALIAS_DOMAIN_COLUMN='$SERDOMAIN'"
			QUERY="DELETE FROM $DA_TABLE $CLAUSE;"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "alias_db: SQL Error"
				exit 1
			fi
			
			exit $?
			;;
			
		help)
			usage_alias_db "alone"
			;;
			
		*)
			usage
			exit 1
			;;
	esac
} # end db-aliases

# speed-dial
speed_dial() {
	if [ "$#" -lt 2 ] ; then
		echo "speeddial: error - too few parameters"
		echo
		usage
		exit 1
	fi
	if [ "$1" = "speeddial" ] ; then
		shift
	else
		echo "speeddial: error - unknown command $1"
		echo
		usage
		exit 1
	fi

	case $1 in 
		list)
			if [ $# -eq 2 ] ; then
				# print speed-dials for user
				check_aor "$2"
				if [ "$?" -ne "0" ] ; then
					echo "speeddial: <$2> is not a valid AoR (user@domain)"
					exit 1
				fi
				
				set_user $2
				
				CLAUSE="WHERE $SD_USER_COLUMN='$SERUSER'  AND $SD_DOMAIN_COLUMN='$SERDOMAIN'"
				echo "Dumping speed-dials for user=<$2>"
				echo
				QUERY="SELECT $SD_SD_USER_COLUMN, $SD_SD_DOMAIN_COLUMN, $SD_NEW_URI_COLUMN, $SD_DESC_COLUMN FROM $SD_TABLE $CLAUSE;"
				sql_ro_query "$QUERY" | $AWK 'BEGIN {line=0;}
											/^\+/ { next }
											{	if(line==0) print "##   SpeedDial   \tNew-URI     \tDescription\n";
												else {
													ORS_BAK=ORS;
													ORS="";
													print line ")  " $1 "@" $2 "\t" $3 "\t\"" $4;
													for (i=5;i<=NF;++i) print FS $i;
													ORS=ORS_BAK;
													print "\"";
												}
												line++;
											}'
			elif [ $# -eq 1 ] ; then
				printf "Dumping all speed-dials may take long: do you want to proceed? [Y|N] "
				read answer
				if [ "$answer" = "y" -o "$answer" = "Y" ] ; then
					echo "Dumping all speed-dials..."
					echo
				else
					exit 1
				fi
				QUERY="SELECT $SD_SD_USER_COLUMN, $SD_SD_DOMAIN_COLUMN, $SD_USER_COLUMN, $SD_DOMAIN_COLUMN, $SD_NEW_URI_COLUMN, $SD_DESC_COLUMN FROM $SD_TABLE;"
				sql_ro_query "$QUERY" | $AWK 'BEGIN {line=0;}
										/^\+/ { next }
										{	line++;
											if(line==1) print "SIP-ID     \tSpeedDial  \tNew-URI    \tDescritpion\n";
											else {
												ORS_BAK=ORS;
												ORS="";
												print $3 "@" $4 "\t" $1 "@" $2 "\t" $5 "\t\"" $6;
												for (i=7;i<=NF;++i) print FS $i;
												ORS=ORS_BAK;
												print "\"";
											}
										}'
			else
				echo "speeddial: wrong number of params for command [list]"
				usage
				exit 1
			fi

			exit $?
			;;
		show)
			if [ $# -ne 2 ] ; then
				echo "speeddial: wrong number of params for command [show]"
				usage
				exit 1
			fi
			
			check_aor "$2"
			if [ "$?" -ne "0" ] ; then
				echo "speeddial: $2 is not a valid AoR (user@domain)"
				exit 1
			fi
			
			set_user $2
			
			CLAUSE="WHERE $SD_SD_USER_COLUMN='$SERUSER' AND $SD_SD_DOMAIN_COLUMN='$SERDOMAIN'"
			QUERY="SELECT $SD_USER_COLUMN, $SD_DOMAIN_COLUMN, $SD_NEW_URI_COLUMN, $SD_DESC_COLUMN FROM $SD_TABLE $CLAUSE ; "
			echo "Details for speeddial <$2>"
			sql_ro_query "$QUERY" | $AWK 'BEGIN {line=0;} /^\+/ { next } 
												{ 
												  if(line==0) print "##  SIP-ID    \tNew-URI   \tDescritpion\n";
												  else {
													  ORS_BAK=ORS;
													  ORS="";
													  print line ") " $1 "@" $2 "\t" $3 "\t\"" $4;
													  for (i=5;i<=NF;++i) print FS $i;
													  ORS=ORS_BAK;
													  print "\"";
												  }
												  line++;
												}'

			exit $?
			;;
		add)
			if [ $# -ne 4 ] ; then
				if [ $# -ne 5 ] ; then
					usage
					exit 1
				fi
			fi
			shift
			check_aor "$1"
			if [ "$?" -ne "0" ] ; then
				echo "speeddial: $1 is not a valid AoR (user@domain)"
				exit 1
			fi

			check_aor "$2"
			if [ "$?" -ne "0" ] ; then
				echo "speeddial: $2 is not a valid AoR (user@domain)"
				exit 1
			fi
			
			check_sipaor "$3"
			if [ "$?" -ne "0" ] ; then
				echo "speeddial: $3 is not a valid SIP AoR (sip:user@domain)"
				exit 1
			fi
			
			set_user $1
			TMP_SERUSER=$SERUSER
			TMP_SERDOMAIN=$SERDOMAIN
			set_user $2
			
			QUERY="INSERT INTO $SD_TABLE \
				($SD_USER_COLUMN,$SD_DOMAIN_COLUMN,$SD_SD_USER_COLUMN,$SD_SD_DOMAIN_COLUMN,$SD_NEW_URI_COLUMN,$SD_DESC_COLUMN) \
                    VALUES ('$TMP_SERUSER','$TMP_SERDOMAIN','$SERUSER','$SERDOMAIN','$3','$4');"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "speeddial: SQL Error"
				exit 1
			fi
			
			exit $?
			;;
		rm)
			if [ $# -ne 3 ] ; then
				echo "speeddial rm: invalid number of parameters"
				usage
				exit 1
			fi
			
			shift
			
			check_aor "$1"
			if [ "$?" -ne "0" ] ; then
				echo "speeddial: $1 is not a valid AoR (user@domain)"
				exit 1
			fi
			
			check_aor "$2"
			if [ "$?" -ne "0" ] ; then
				echo "speeddial: $2 is not a valid AoR (user@domain)"
				exit 1
			fi

			set_user $1
			TMP_SERUSER=$SERUSER
			TMP_SERDOMAIN=$SERDOMAIN
			set_user $2

			CLAUSE="WHERE $SD_USER_COLUMN='$TMP_SERUSER' AND $SD_DOMAIN_COLUMN='$TMP_SERDOMAIN' \
                         AND $SD_SD_USER_COLUMN='$SERUSER' AND $SD_SD_DOMAIN_COLUMN='$SERDOMAIN'"
			QUERY="DELETE FROM $SD_TABLE $CLAUSE;"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "speeddial: SQL Error"
				exit 1
			fi
			
			;;
			
		help)
			usage_speeddial "alone"
			;;
			
		*)
			echo "speeddial: unknown command"
			usage
			exit 1
			;;
	esac
} # end speed_dial()


# AVP operations
# avp list [-T table] [-u <sip-id|uuid>]
#     [-a attribute] [-v value] [-t type] ... list AVPs
# avp add [-T table] <sip-id|uuid>
#     <attribute> <type> <value> ............ add AVP (*)
# avp rm [-T table]  [-u <sip-id|uuid>]
#     [-a attribute] [-v value] [-t type] ... remove AVP (*)

avpops() {
	if [ "$#" -lt 2 ] ; then
		echo "avpops: error - too few parameters"
		echo
		usage
		exit 1
	fi
	if [ "$1" = "avp" ] ; then
		shift
	else
		echo "avpops: error - unknown command $1"
		echo
		usage
		exit 1
	fi

	case $1 in 
		list)
			shift
			CLAUSE=""
			while [ "$#" != "0" ] 
			do
				TMP_ARG=$1
				shift
				case $TMP_ARG in 
					-T)
						if [ -z "$1" ] ; then
							echo "avpops: table name parameter missing"
							exit 1
						fi
						AVP_TABLE=$1
					;;
					-u)
						if [ -z "$1" ] ; then
							echo "avpops: user id or uuid parameter missing"
							exit 1
						fi
						is_aor "$1"
						if [ "$?" -eq "0" ] ; then
							set_user $1
							if [ "$CLAUSE" = "" ] ; then
								CLAUSE=" WHERE $AVP_USER_COLUMN='$SERUSER' AND $AVP_DOMAIN_COLUMN='$SERDOMAIN'"
							else
								CLAUSE="$CLAUSE AND $AVP_USER_COLUMN='$SERUSER' AND $AVP_DOMAIN_COLUMN='$SERDOMAIN'"
							fi
						else
							if [ "$CLAUSE" = "" ] ; then
								CLAUSE=" WHERE $AVP_UUID_COLUMN='$1'"
							else
								CLAUSE="$CLAUSE AND $AVP_UUID_COLUMN='$1'"
							fi
						fi				
					;;
					-a)
						if [ -z "$1" ] ; then
							echo "avpops: AVP attribute name parameter missing"
							exit 1
						fi
						if [ "$CLAUSE" = "" ] ; then
							CLAUSE=" WHERE $AVP_ATTRIBUTE_COLUMN='$1'"
						else
							CLAUSE="$CLAUSE AND $AVP_ATTRIBUTE_COLUMN='$1'"
						fi
					;;
					-v)
						if [ -z "$1" ] ; then
							echo "avpops: AVP value parameter missing"
							exit 1
						fi
						if [ "$CLAUSE" = "" ] ; then
							CLAUSE=" WHERE $AVP_VALUE_COLUMN='$1'"
						else
							CLAUSE="$CLAUSE AND $AVP_VALUE_COLUMN='$1'"
						fi
					;;
					-t)
						if [ -z "$1" ] ; then
							echo "avpops: AVP type parameter missing"
							exit 1
						fi
						if [ "$CLAUSE" = "" ] ; then
							CLAUSE=" WHERE $AVP_TYPE_COLUMN='$1'"
						else
							CLAUSE="$CLAUSE AND $AVP_TYPE_COLUMN='$1'"
						fi
					;;
					*)
						echo "avpops: unknown parameter $1"
						exit 1
					;;
				esac
				shift
			done
			
			QUERY="SELECT $AVP_UUID_COLUMN, $AVP_USER_COLUMN, $AVP_DOMAIN_COLUMN, $AVP_ATTRIBUTE_COLUMN, $AVP_TYPE_COLUMN, $AVP_VALUE_COLUMN FROM $AVP_TABLE $CLAUSE;"
			# echo "Query: $QUERY"
			echo "Dumping AVPs"
			echo
			sql_ro_query "$QUERY" # | $AWK 'BEGIN {line=0;}
			#			/^\+/ { next }
			#			{	if(line==0) print "##   UUID   \tUserID     \tAttribute     \tType     \tValue\n";
			#				else {
			#					ORS_BAK=ORS;
			#					ORS="";
			#					print line ")  " $1  $2 "@" $3 "\t" $4 "\t\"" $5;
			#					for (i=6;i<=NF;++i) print FS $i;
			#					ORS=ORS_BAK;
			#					print "\"";
			#				}
			#				line++;
			#			}'
			
			exit $?
			;;
			
		add)
			shift
			if [ $# -ne 4 ] ; then
				if [ $# -ne 6 ] ; then
					echo "avpops add: bad number of parameters"
					echo
					usage
					exit 1
				fi
			fi
			if [ $# -eq 6 ] ; then
				if [ "$1" = "-T" ] ; then
					AVP_TABLE=$2
					shift
					shift
				else
					echo "avpops add: unknown parameter '$1'"
					echo
					usage
					exit 1					
				fi
			fi
						
			is_aor "$1"
			if [ "$?" -eq "0" ] ; then
				set_user $1
			else
				AVP_UUID=$1
			fi

			QUERY="INSERT INTO $AVP_TABLE \
				($AVP_UUID_COLUMN,$AVP_USER_COLUMN,$AVP_DOMAIN_COLUMN,$AVP_ATTRIBUTE_COLUMN,$AVP_TYPE_COLUMN,$AVP_VALUE_COLUMN,$AVP_MODIFIED_COLUMN) \
                    VALUES ('$AVP_UUID','$SERUSER','$SERDOMAIN','$2',$3,'$4',NOW());"
			# echo "Query: $QUERY"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "avpops: SQL Error"
				exit 1
			else
				echo
				echo "avpops: AVP added"
			fi
			
			exit $?
			;;

		rm)
			shift
			CLAUSE=""
			while [ "$#" != "0" ] 
			do
				TMP_ARG=$1
				shift
				case $TMP_ARG in 
					-T)
						if [ -z "$1" ] ; then
							echo "avpops: table name parameter missing"
							exit 1
						fi
						AVP_TABLE=$1
					;;
					-u)
						if [ -z "$1" ] ; then
							echo "avpops: user id or uuid parameter missing"
							exit 1
						fi
						is_aor "$1"
						if [ "$?" -eq "0" ] ; then
							set_user $1
							if [ "$CLAUSE" = "" ] ; then
								CLAUSE="WHERE $AVP_USER_COLUMN='$SERUSER' AND $AVP_DOMAIN_COLUMN='$SERDOMAIN'"
							else
								CLAUSE="$CLAUSE AND $AVP_USER_COLUMN='$SERUSER' AND $AVP_DOMAIN_COLUMN='$SERDOMAIN'"
							fi
						else
							if [ "$CLAUSE" = "" ] ; then
								CLAUSE="WHERE $AVP_UUID_COLUMN='$1'"
							else
								CLAUSE="$CLAUSE AND $AVP_UUID_COLUMN='$1'"
							fi
						fi				
					;;
					-a)
						if [ -z "$1" ] ; then
							echo "avpops: AVP attribute name parameter missing"
							exit 1
						fi
						if [ "$CLAUSE" = "" ] ; then
							CLAUSE="WHERE $AVP_ATTRIBUTE_COLUMN='$1'"
						else
							CLAUSE="$CLAUSE AND $AVP_ATTRIBUTE_COLUMN='$1'"
						fi
					;;
					-v)
						if [ -z "$1" ] ; then
							echo "avpops: AVP value parameter missing"
							exit 1
						fi
						if [ "$CLAUSE" = "" ] ; then
							CLAUSE="WHERE $AVP_VALUE_COLUMN='$1'"
						else
							CLAUSE="$CLAUSE AND $AVP_VALUE_COLUMN='$1'"
						fi
					;;
					-t)
						if [ -z "$1" ] ; then
							echo "avpops: AVP type parameter missing"
							exit 1
						fi
						if [ "$CLAUSE" = "" ] ; then
							CLAUSE="WHERE $AVP_TYPE_COLUMN='$1'"
						else
							CLAUSE="$CLAUSE AND $AVP_TYPE_COLUMN='$1'"
						fi
					;;
					*)
						echo "avpops: unknown parameter $1"
						exit 1
					;;
				esac
				shift
			done
			QUERY="DELETE FROM $AVP_TABLE $CLAUSE;"
			# echo "Query: $QUERY"
			sql_query "$QUERY"
			if [ $? -ne 0 ] ; then
				echo "avpops: SQL Error"
				exit 1
			else
				echo
				echo "avpops: AVP(s) deleted"
			fi
			
			exit $?
			;;
			
		help)
			usage_avp "alone"
			;;
			
		*)
			echo "avpops: unknown command"
			usage
			exit 1
			;;
	esac
} # end avpops()


#================================================================

# if the script calls itself ...
export PW

case $1 in

	start)
		echo
		printf "Starting OpenSER : "
		if [ -r $PID_FILE ] ; then
			echo "PID file exists! ($PID_FILE) already running?"
			exit 1
		else
			if [ ! -x "$SERBIN" ] ; then
				echo "OpenSER binaries not found at $SERBIN; reconfigure SERBIN in $0"
				exit 1
			fi
			if [ $SYSLOG = 1 ] ; then
				$SERBIN -P $PID_FILE $STARTOPTIONS 1>/dev/null 2>/dev/null
			else
			 	$SERBIN -P $PID_FILE -E $STARTOPTIONS
			fi
			sleep 1
			if [ ! -s $PID_FILE ] ; then
				echo "PID file $PID_FILE does not exist -- OpenSER start failed"
				exit 1
			fi
			echo "started pid(`cat $PID_FILE`)"
		fi
		exit 0
	;;

	stop)
		printf "Stopping OpenSER : "
		if [ -r $PID_FILE ] ; then
			kill `cat $PID_FILE`
			echo "stopped"
		else
			echo No PID file found! OpenSER probably not running
			exit 1
		fi
		exit 0
	;;

	restart)
		$0 stop
		if [ "$?" -ne 0 ] ; then
			exit 1
		fi
		sleep 2
		$0 start
		exit 0
	;;

	passwd)
		if [ $# -ne 3 ] ; then
			usage
			exit 1
		fi
		shift
		credentials $1 $2
		prompt_pw

		is_user $1
		if [ $? -ne 0 ] ; then
			echo non-existent user
			exit 1
		fi
		QUERY="update $SUB_TABLE \
			set $HA1_COLUMN='$HA1', $HA1B_COLUMN='$HA1B', $PASSWORD_COLUMN='$2' \
			, $SUB_MODIFIED_COLUMN=now() \
			WHERE $SUBSCRIBER_COLUMN='$SERUSER' and $REALM_COLUMN='$SERDOMAIN';"
		sql_query "$QUERY"
		if [ $? -ne 0 ] ; then
			echo "password change failed"
		else
			echo "password change succeeded"
		fi

		;;		

	add)
		if [ $# -ne 4 ] ; then
			usage
			exit 1
		fi
		shift
		credentials $1 $2
		prompt_pw
		is_user $1
		if [ $? -eq 0 ] ; then
			echo user already exists
			exit 1
		fi  
		# check_alias "$SERUSER@$SERDOMAIN"
	    is_alias_db $1
        if [ $? -eq 0 ] ; then
			echo username already exists as alias
			exit 1
       	fi  

		set_user $1

		QUERY="insert into $SUB_TABLE \
			($SUBSCRIBER_COLUMN,$REALM_COLUMN,$HA1_COLUMN,\
			$HA1B_COLUMN,$PASSWORD_COLUMN,$EMAIL_COLUMN,$SUB_CREATED_COLUMN, \
			$PHP_LIB_COLUMN) \
			values ('$SERUSER','$SERDOMAIN','$HA1','$HA1B','$2','$3',now(),'$HA1');";
		sql_query "$QUERY"
		if [ $? -ne 0 ] ; then
			echo "introducing the new user to the database failed"
		else
			echo "new user added"
		fi

		;;

	monitor|console|moni|con)
		name=ser_receiver_$$
		path=/tmp/$name
		if [ ! -w $SER_FIFO ]; then
			echo "Error opening openser's FIFO $SER_FIFO"
			echo "Make sure you have line fifo=$SER_FIFO in your config"
			exit 1
		fi
		mkfifo $path
		if [ $? -ne 0 ] ; then
			echo "error opening read fifo $path"
			exit 1
		fi
		chmod a+w $path
		trap "rm $path;  clear; echo sc monitor ^C-ed; exit 1" 2
		attempt=0
		if [ "$2" == "" ]; then
		    loops=-1;
		else
		    loops=$2;
		fi
		clear
		while [ $loops -ne $attempt ] ; do
			attempt=$(($attempt + 1))
			#clear
			tput cup 0 0
			print_stats $name $path $attempt
			if [ $loops -ne $attempt ] ; then
				sleep $WATCH_PERIOD
			fi
				
		done
		rm $path
		exit 0
		;;

	mail)
		if [ $# -ne 2 ] ; then
			usage
			exit 1
		fi
		shift
		set_user $1
		QUERY="select $SUB_TABLE.$EMAIL_COLUMN from $SUB_TABLE where  \
			$SUB_TABLE.$SUBSCRIBER_COLUMN='$SERUSER' and $SUB_TABLE.$REALM_COLUMN='$SERDOMAIN'"
		EA=`sql_ro_query "$QUERY" "-B" | grep -v ERROR | $LAST_LINE`
		if [ $? -ne 0 ] ; then
			echo "MySql query failed"
			exit 1
		fi
		echo "Write email to $1: $EA now ..."
		mail -s "Message from $SERDOMAIN SIP admin" $EA
		if [ $? -eq 0 ] ; then
			echo message sent
		else
			echo sending message failed
		fi

		;;

	alias|ul)
		usrloc "$@"
		;;

	alias_db)
		dbaliases "$@"
		;;
		
	speeddial)
		speed_dial "$@"
		;;

	avp)
		avpops "$@"
		;;

	pa)
		presence_agent "$@"
		;;

	rpid)
		rpid "$@"
		;;

	online)
		fifo_cmd ul_dump |grep aor| awk '{print $3}' | sort | sort -mu
		exit $?
		;;


	showdb|userdb)
		shift
		if [ $# -eq 1 ] ; then
			is_user $1
			if [ $? -ne 0 ] ; then
				echo non-existent user
				exit 1;
			fi
			QUERY1="select $SUB_TABLE.$EMAIL_COLUMN from $SUB_TABLE \
					where $SUB_TABLE.$SUBSCRIBER_COLUMN='$SERUSER' and \
					$SUB_TABLE.$REALM_COLUMN='$SERDOMAIN' "
			QUERY2="select $UL_TABLE.* from $UL_TABLE where \
					$UL_TABLE.$USER_COLUMN='$SERUSER' and 
					$UL_TABLE.$REALM_COLUMN='$SERDOMAIN' order by expires desc"
			sql_ro_query "$QUERY1"
			sql_ro_query "$QUERY2"
		else
			QUERY3="select $UL_TABLE.$USER_COLUMN, $SUB_TABLE.$EMAIL_COLUMN, \
				$UL_TABLE.$CALLID_COLUMN from $SUB_TABLE, $UL_TABLE where  \
				$SUB_TABLE.$SUBSCRIBER_COLUMN=$UL_TABLE.$USER_COLUMN  \
				order by $UL_TABLE.$USER_COLUMN" 
			sql_ro_query "$QUERY3"
		fi
		echo "Note: Due to usage of cache, server's list " \
			"may differ from DB list."

		;;

	rm)
		if [ $# -ne 2 ] ; then
			usage
			exit 1
		fi
		shift 
		prompt_pw 

		is_user $1 
		if [ $? -ne 0 ] ; then
			echo non-existent user
			exit 1
		fi

		# begin with remove all user's privileges
		$0 acl revoke $1  > /dev/null 2>&1

		QUERY="delete from $DA_TABLE where $DA_USER_COLUMN='$SERUSER' and $DA_DOMAIN_COLUMN='$SERDOMAIN'"
		sql_query "$QUERY"


		# destroy the user now
		QUERY="delete from $SUB_TABLE where $SUB_TABLE.$SUBSCRIBER_COLUMN='$SERUSER' and $SUB_TABLE.$REALM_COLUMN='$SERDOMAIN'"
		sql_query "$QUERY"

		# and also all his contacts
		$0 ul rm $1   > /dev/null 2>&1
        ;;
			
	ps)
		fifo_cmd ps
		;;

	acl)
		shift
		acl "$@"
		;;

	domain)
		shift
		domain "$@"
		;;

	lcr)
		shift
		lcr "$@"
		;;

	fifo)
		shift
		fifo_cmd "$@"
		;;

	ping)
		# error handling is hacked -- filter_fl should not
		# consume positive status -- that should be done by
		# calling app
		if [ "$#" -ne 2 ] ; then	
			usage
			exit 1
		fi
		myhost=`get_my_host`
		RET=`fifo_cmd t_uac_dlg OPTIONS "$2" "." \
			"From: sip:daemon@$myhost" \
			"To: <$2>" "Contact: <sip:daemon@!!>" "." "." \
			| head -1 ` 
		print_status $RET
		;;

	cisco_restart)
		if [ "$#" -ne 2 ] ; then	
			usage
			exit 1
		fi
		myhost=`get_my_host`
		RET=`fifo_cmd t_uac_dlg NOTIFY "$2" "." \
			"From: sip:daemon@$myhost" \
			"To: <$2>" "Event: check-sync" \
			"Contact: <sip:daemon@!!>" "." "." |
			head -1 `
		print_status $RET
		;;

	version)
		echo  "$0 $VERSION"
		;;
		
	*)
		usage
		exit 1
		;;

esac

