#!/bin/bash

#getting the config
source /etc/nlvmi/nlvmi.conf
if [ $LOGLEVEL -gt "2" ]; then echo "configuration loaded"; fi

#check if we are root and wrap if we are not
U=`/usr/bin/whoami`
if [ $U != "root" ]; then
	if [ ! -z $1 ]; then A="$1"; else A="bla"; fi
	if [ ! -z $2 ]; then B="$2"; else B="bla"; fi
	if [ ! -z $3 ]; then C="$3"; else C="bla"; fi
	/usr/bin/wrap-nlvmi \"$A\" \"$B\" \"$C\" && exit
fi
if [ ! -d $RUNDIRECTORY ]; then if [ $LOGLEVEL -gt "1" ]; then echo "creating $RUNDIRECTORY"; fi; mkdir -p $RUNDIRECTORY; chown root:nlvmi -R $RUNDIRECTORY; chmod g+w $RUNDIRECTORY; fi

#checking database
function checkdb {
    if [ $DATABASETYPE == "sqlite" ]; then
        if [ ! -e $SQLITEFILE ]; then echo "sqlite configured, but db-file not present! create the db first!"; exit 1; fi
	SQCHECK=`sqlite3 $SQLITEFILE "SELECT name FROM sqlite_master WHERE type='table' AND name='vms'"`
	if [ $SQCHECK == "vms" ]; then
		if [ $LOGLEVEL -gt "1" ]; then echo "DB ready to use"; fi
	else
		echo "error accessing sqlite!"
		exit 1;
	fi
	echo "sqlite ready to use";
    elif [ $DATABASETYPE == "mariadb" ]; then
        DBCON="mysql --disable-pager -u $MARIAUSER -p$MARIAPASS -h $MARIAHOST $MARIADB"
        declare -a DBC=`echo "SHOW TABLES FROM $MARIADB; " | $DBCON | sed 1d`
        if [ -z $DBC ]; then
            echo "mariadb connection failed"; exit 1
        fi
    fi
    return 0
}


#creating database
function createdb {
    if [ $LOGLEVEL -gt "1" ]; then echo "going to create the db"; fi
    if [ $DATABASETYPE == "sqlite" ]; then
        sqlite3 $SQLITEFILE "CREATE TABLE vms (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		    vmname VARCHAR(50) NOT NULL,
		    user VARCHAR(50) NOT NULL,
		    server VARCHAR(50),
		    arch VARCHAR(50) NOT NULL,
		    cputype VARCHAR(50),
		    cpus INTEGER,
		    memory INTEGER,
		    usbdev VARCHAR(50),
		    kblang VARCHAR(50),
		    custom VARCHAR(50),
		    bootoption VARCHAR(2) NOT NULL,
		    autostart INTEGER,
		    drive1 VARCHAR(50),
		    format1 VARCHAR(50),
		    drive2 VARCHAR(50),
		    format2 VARCHAR(50),
		    drive3 VARCHAR(50),
		    format3 VARCHAR(50),
		    cdrom VARCHAR(50),
		    tapdev1 VARCHAR(50),
		    macaddr1 VARCHAR(50),
		    brdev1 VARCHAR(50),
		    tapdev2 VARCHAR(50),
		    macaddr2 VARCHAR(50),
		    brdev2 VARCHAR(50),
		    tapdev3 VARCHAR(50),
		    macaddr3 VARCHAR(50),
		    brdev3 VARCHAR(50),
		    vncport INTEGER,
		    websocket INTEGER,
		    vncpassword VARCHAR(50),
		    prio INTEGER
	);"
        sqlite3 $SQLITEFILE "CREATE TABLE users (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		    username VARCHAR(50) NOT NULL,
		    password VARCHAR(255),
		    admin INTEGER
	);"
	sqlite3 $SQLITEFILE "CREATE TABLE servers (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
			hostname VARCHAR(50) NOT NULL,
			connectstring VARCHAR(50),
			vmdirectory VARCHAR(255),
			isodirectory VARCHAR(255)
	);"

	chown -R nobody $SQLITEFILE
    fi
    checkdb && echo "DB creation successful!" || (echo "Failed to create the DB"; exit 1)
}
#create signing key
function createkey {
	openssl req -nodes -x509 -sha256 -newkey rsa:4096 -keyout "/etc/nlvmi/nlvmi_priv.key" -out "/etc/nlvmi/nlvmi_sign.crt" -days 9999 -subj "/CN=nlvmi_signing"
}

#check if VM is running
function checkvm {
	if [ -z $1 ]; then echo "checkvm needs one argument!"; exit 1; fi
	sqlite3 $SQLITEFILE "SELECT connectstring from vms LEFT JOIN servers ON vms.server = servers.hostname WHERE vmname='$1'" | while read line; do
	    CONN=$line
	    if [ ! -z $CONN ]; then
		su nlvmi -c "ssh $CONN \"RPID=\\\$(<\\\"$RUNDIRECTORY/$1.pid\\\"); ps -ef | grep -v grep | grep  \\\$RPID | grep qemu\"" &>/dev/null  && echo "VM is running" || echo "VM is not running"
	    else
		ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null && echo "VM is running" || echo "VM is not running"

	    fi
	done
}



#autostart VMs
function vmautostart {
	if [ -z $MASTERSERVER ]; then
		for startfile in /home/nlvmi/start*.tmp; do
			vmname=`echo $startfile | cut -d "." -f1 | rev | cut -d "/" -f 1 | rev | sed 's/start//g'`
			checkvm ${vmname} | grep "is not running" >/dev/null && sh $startfile;
		done
	else
		for startsign in /home/nlvmli/start*.tmp.sha512; do
			startfile=`echo $startsign | cut -d "." -f 1-2`
			vmname=`echo $startfile | cut -d "." -f1 | rev | cut -d "/" -f1 | rev | sed 's/start//g'`
			checkvm ${vmname} | grep "is not running" >/dev/null && if [ -e $startfile ]; then
				openssl dgst -sha512 -verify  <(openssl x509 -in "/etc/nlvmi/nlvmi_sign.crt"  -pubkey -noout) -signature $startsign $startfile >/dev/null && /bin/bash $2 || echo "signature failed!!"
			fi
		done
	fi
}

#start single VM
function vmstart {
	if [ -z $1 ]; then echo "function start needs an id!"; exit 1; fi
	if [ $LOGLEVEL -gt "2" ]; then echo "startvm function entered for vmid $1"; fi
	sqlite3 $SQLITEFILE "SELECT * FROM vms LEFT JOIN servers on vms.server = servers.hostname WHERE vms.id=$1" | while read line; do
			IFS='|' read -r -a array <<< "$line"
			#prepare tmpfile
			TMPF=/home/nlvmi/start${array[32]}-${array[1]}.tmp
			rm /home/nlvmi/start*-${array[1]}.tmp &>/dev/null
			touch $TMPF && chmod 660 $TMPF && chown nlvmi: $TMPF
			#add user if necessary
			echo "if ! \`id -u ${array[2]} &>/dev/null\`; then useradd ${array[2]} -d /run/nlvmi -g nlvmi -M -s /bin/false -G kvm; fi" >>$TMPF
			#chown mon and pid files
			echo "if [ -e $RUNDIRECTORY/${array[1]}.mon ] || [ -e $RUNDIRECTORY/${array[1]}.pid ]; then chown ${array[2]}:nlvmi $RUNDIRECTORY/${array[1]}.*; fi" >>$TMPF
			if [ ! -z ${array[5]} ]; then CPUTYPE="-cpu ${array[5]}"; fi
			if [ ! -z ${array[6]} ]; then SMP="-smp ${array[6]}"; fi
			if [ ! -z ${array[7]} ]; then MEMORY="-m ${array[7]}"; fi
			if [ ! -z ${array[8]} ]; then USBDEV="-usb -device usb-ehci,id=ehci -device usb-${array[8]},bus=usb-bus.0"; fi
			if [ ! -z ${array[9]} ]; then KB="-k ${array[9]}"; fi
			if [ ! -z ${array[10]} ]; then CUSTOM="${array[10]}"; fi
			if [ ! -z ${array[13]} ]; then DRIVE1="-drive file=${array[13]}"; echo "chown ${array[2]}:nlvmi ${array[13]}" >>$TMPF; fi
			if [ ! -z ${array[14]} ]; then FORMAT1=",format=${array[14]},if=virtio"; fi
			if [ ! -z ${array[15]} ]; then DRIVE2="-drive file=${array[15]}"; echo "chown ${array[2]}:nlvmi ${array[15]}" >>$TMPF; fi
			if [ ! -z ${array[16]} ]; then FORMAT2=",format=${array[16]},if=virtio"; fi
			if [ ! -z ${array[17]} ]; then DRIVE3="-drive file=${array[17]}"; echo "chown ${array[2]}:nlvmi ${array[17]}" >>$TMPF; fi
			if [ ! -z ${array[18]} ]; then FORMAT3=",format=${array[18]},if=virtio"; fi
			if [ ! -z ${array[19]} ]; then CDROM="-cdrom ${array[19]}"; fi
			if [ ! -z ${array[20]} ]; then TAPDEV1="-netdev tap,ifname=${array[20]},script=no,id=net0"; echo "which tunctl && tunctl -t ${array[20]} -u ${array[2]} >/dev/null || ip tuntap add ${array[20]} mode tap user ${array[2]}; ifconfig ${array[20]} up" >>$TMPF; fi
			if [ ! -z ${array[21]} ]; then MACADDR1="-net nic,macaddr=${array[21]},model=virtio,netdev=net0"; fi
			if [ ! -z ${array[22]} ]; then BRDEV1="${array[22]}"; TAPDS1=`echo ${array[20]} | cut -c 1-15`;  echo "if  [ -L /sys/devices/virtual/net/${TAPDS1}/master ]; then OLDBR=\`readlink -f /sys/devices/virtual/net/${TAPDS1}/master | rev | cut -d "/" -f1 | rev\`; brctl delif \$OLDBR ${array[20]}; fi; /sbin/brctl addif ${array[22]} ${array[20]} >/dev/null" >>$TMPF; fi
			if [ ! -z ${array[23]} ]; then TAPDEV2="-netdev tap,ifname=${array[23]},script=no,id=net1"; echo "which tunctl && tunctl -t ${array[23]} -u ${array[2]} >/dev/null || ip tuntap add ${array[23]} mode tap user ${array[2]}; ifconfig ${array[23]} up" >>$TMPF; fi
			if [ ! -z ${array[24]} ]; then MACADDR2="-net nic,macaddr=${array[24]},model=virtio,netdev=net1"; fi
			if [ ! -z ${array[25]} ]; then BRDEV2="${array[25]}"; echo "if  [ -L /sys/devices/virtual/net/${array[23]}/master ]; then OLDBR=\`readlink -f /sys/devices/virtual/net/${array[23]}/master | rev | cut -d "/" -f1 | rev\`; brctl delif \$OLDBR ${array[23]}; fi; /sbin/brctl addif ${array[25]} ${array[23]} >/dev/null" >>$TMPF; fi
			if [ ! -z ${array[26]} ]; then TAPDEV3="-netdev tap,ifname=${array[26]},script=no,id=net2"; echo "which tunctl && tunctl -t ${array[26]} -u ${array[2]} >/dev/null || ip tuntap add ${array[26]} mode tap user ${array[2]}; ifconfig ${array[26]} up" >>$TMPF; fi
			if [ ! -z ${array[27]} ]; then MACADDR3="-net nic,macaddr=${array[27]},model=virtio,netdev=net2"; fi
			if [ ! -z ${array[28]} ]; then BRDEV3="${array[28]}"; echo "if  [ -L /sys/devices/virtual/net/${array[26]}/master ]; then OLDBR=\`readlink -f /sys/devices/virtual/net/${array[26]}/master | rev | cut -d "/" -f1 | rev\`; brctl delif \$OLDBR ${array[26]}; fi; /sbin/brctl addif ${array[28]} ${array[26]} >/dev/null" >>$TMPF; fi
			if [ ! -z ${array[30]} ]; then WPORT=$((${array[30]} + 5700)); WEBSOCK=",websocket=$WPORT"; else WEBSOCK=""; fi
			if [ ! -z ${array[31]} ]; then VNCPASS=",password"; fi
			if [ ! -z ${array[29]} ]; then VNCPORT="-vnc :${array[29]}$WEBSOCK$VNCPASS"; fi
#			echo "which ${array[4]} && QEMUCOMMAND=/usr/bin/${array[4]} || QEMUCOMMAND=/usr/libexec/qemu-kvm" >>$TMPF
			COMMAND=(su - ${array[2]} -s /bin/bash -c \"which ${array[4]} \&\& QEMUCOMMAND=/usr/bin/${array[4]} \|\| QEMUCOMMAND=/usr/libexec/qemu-kvm\; \\\$QEMUCOMMAND -name ${array[1]} -enable-kvm ${array[10]} $CPUTYPE $MEMORY $SMP -device virtio-rng-pci -boot ${array[11]} $USBDEV $KB -daemonize $DRIVE1$FORMAT1 $DRIVE2$FORMAT2 $DRIVE3$FORMAT3 $CDROM $MACADDR1 $TAPDEV1 $MACADDR2 $TAPDEV2 $MACADDR3 $TAPDEV3 $VNCPORT $CUSTOM -pidfile $RUNDIRECTORY/${array[1]}.pid -monitor unix:$RUNDIRECTORY/${array[1]}.mon,server,nowait\")
			if [ $LOGLEVEL -gt "1" ]; then echo ${COMMAND[@]}; fi
			echo "${COMMAND[@]}" >>$TMPF
			#Set VNC Password
			echo "echo \"change vnc password ${array[31]}\" | socat - unix-connect:$RUNDIRECTORY/${array[1]}.mon >/dev/null" >>$TMPF
			if [ ! -z "${array[35]}" ]; then
				echo "chmod g+w $RUNDIRECTORY/${array[1]}.mon" >>$TMPF
				echo "chmod g+r $RUNDIRECTORY/${array[1]}.pid" >>$TMPF
				openssl dgst -sha512 -sign "/etc/nlvmi/nlvmi_priv.key" -out /home/nlvmi/start${array[32]}-${array[1]}.tmp.sha512 $TMPF
				TMPFR="/home/nlvmi/rstart${array[32]}-${array[1]}.tmp"
				mv $TMPF $TMPFR
				su nlvmi -c "ssh ${array[35]} \"rm /home/nlvmi/start*-${array[1]}.tmp*\""
				mv $TMPFR $TMPF
				su nlvmi -c "scp $TMPF* ${array[35]}:/home/nlvmi/"
				OUT=`su nlvmi -c "ssh ${array[35]} \"/usr/bin/nlvmi remote $TMPF run\"" 2>&1`
				echo $OUT
				if [ ${array[12]} == "0" ]; then
					su nlvmi -c "ssh ${array[35]} \"rm $TMPF $TMPF.sha512\""
					echo $OUT
				fi
				rm $TMPF $TMPF.sha512
			else
				OUT=`/bin/bash $TMPF 2>&1`
				echo $OUT
				if [ ${array[12]} == "0" ]; then
					rm $TMPF
				fi
			fi
			if [ ! -z $WPORT ] && [ ! -z $NGINXCONFIGPATH ]; then
				echo "location /${array[1]}/ {" >$NGINXCONFIGPATH/${array[1]}.conf
				echo "	proxy_pass http://${array[3]}:$WPORT/;" >>$NGINXCONFIGPATH/${array[1]}.conf
				echo "	proxy_http_version 1.1;" >>$NGINXCONFIGPATH/${array[1]}.conf
				echo "	proxy_set_header Upgrade \$http_upgrade;" >>$NGINXCONFIGPATH/${array[1]}.conf
				echo "	proxy_set_header Connection \"Upgrade\";" >>$NGINXCONFIGPATH/${array[1]}.conf
				echo "	proxy_read_timeout 61s;" >>$NGINXCONFIGPATH/${array[1]}.conf
				echo "	proxy_buffering off;" >>$NGINXCONFIGPATH/${array[1]}.conf
				echo "}" >>$NGINXCONFIGPATH/${array[1]}.conf
				if [ ! -z $NGINXRESTARTCOMMAND ]; then $NGINXRESTARTCOMMAND; fi
			fi
	done
	export VMFOUND="yes"
}

#stop VM
function vmstop {
	if [ $LOGLEVEL -gt "2" ]; then echo "stopvm function entered for VM $1"; fi
		sqlite3 $SQLITEFILE "SELECT vms.id AS vid,vmname,connectstring FROM vms LEFT JOIN servers ON vms.server = servers.hostname WHERE vmname='$1'" | while read line; do
			IFS='|' read -r -a array <<< "$line"
			if [ -z ${array[2]} ]; then
				if [ ! -e $RUNDIRECTORY/$1.pid ]; then echo "pidfile $RUNDIRECTORY/$1.pid does not exist"; exit 1; fi
					echo "system_powerdown" | socat - unix-connect:$RUNDIRECTORY/${array[1]}.mon >/dev/null
			else
				su nlvmi -c "ssh ${array[2]} \"echo \\\"system_powerdown\\\" | socat - unix-connect:$RUNDIRECTORY/${array[1]}.mon >/dev/null\""
			fi
			sleep 5s
			STOPPED="no"
			COUNTER=0
			while [ $STOPPED = "no" ]; do
				if [ $COUNTER == 10 ]; then
					if [ -z ${array[2]} ]; then
						kill `cat $RUNDIRECTORY/${array[1]}.pid`
						echo "${array[1]} forcefully killed!";
						STOPPED="yes"
					else
						TMPF=/home/nlvmi/${array[1]}.tmp
						echo "kill \$(<\"$RUNDIRECTORY/${array[1]}.pid\")" >$TMPF
						openssl dgst -sha512 -sign "/etc/nlvmi/nlvmi_priv.key" -out $TMPF.sha512 $TMPF
						su nlvmi -c "scp $TMPF* ${array[2]}:/home/nlvmi/"
						su nlvmi -c "ssh ${array[2]} \"/usr/bin/nlvmi remote /home/nlvmi/${array[1]}.tmp stop\""
						su nlvmi -c "ssh ${array[2]} \"rm $TMPF $TMPF.sha512\""
						rm $TMPF $TMPF.sha512
						echo "remotekill"
						STOPPED="yes"
					fi
				fi
				((COUNTER++))
				checkvm ${array[1]} | grep "is not running" >/dev/null && STOPPED="yes"
				sleep 1s
			done
	done
}


#stop local vm
function vmlocalstop {
	if [ ! -e $RUNDIRECTORY/$1.pid ]; then echo "pidfile $RUNDIRECTORY/$1.pid does not exist"; exit 1; fi
	echo "system_powerdown" | socat - unix-connect:$RUNDIRECTORY/$1.mon >/dev/null
	sleep 5s
	STOPPED="no"
	COUNTER=0
	while [ $STOPPED = "no" ]; do
		if [ $COUNTER == 10 ]; then
			kill `cat $RUNDIRECTORY/$1.pid`
			echo "$1 forcefully killed!";
			STOPPED="yes"
		fi
		((COUNTER++))
		ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null || STOPPED="yes"
		sleep 1s
	done
}

#stopall local vms
function stopall {
	for vms in $RUNDIRECTORY/*.pid; do
		vmname=`echo ${vms} | rev | cut -d "/" -f1 | rev | sed 's/.pid//g'`
		vmlocalstop ${vmname}
	done
}

function listdirs {
	if [ $2 == "isodirectory" ] || [ $2 == "vmdirectory" ]; then
		COLNAMES=$2
		MODE="vm"
	else
		COLNAMES="isodirectory,vmdirectory"
		MODE="img"
	fi
	sqlite3 $SQLITEFILE "SELECT $COLNAMES,connectstring FROM servers WHERE hostname='$1'" | while read line; do
		IFS='|' read -r -a array <<< "$line"
		if [ $MODE == "vm" ]; then
			IFS=';' read -r -a dirs <<< "${array[0]}"
			for di in ${dirs[@]}; do
				if [ -z ${array[1]} ]; then
					ls -lrt -d -1 $di/{*,.*}
				else
					su nlvmi -c "ssh ${array[1]} \"ls -lrt -d -1 $di/{*,.*}\""
				fi
			done
		elif [ $MODE == "img" ]; then
			IFS=';' read -r -a dirs <<< "${array[0]};${array[1]}"
			for di in ${dirs[@]}; do
				if [ $di == $2 ]; then
					if [ -z ${array[2]} ]; then
						ls -lrt -d -1 $di/{*,.*}
					else
						su nlvmi -c "ssh ${array[2]} \"ls -lrt -d -1 $di/{*,.*}\""
					fi
				fi
			done
		fi
	done
}

function delimg {
	DDIR=`echo $2 | rev | cut -d "/" -f 2- | rev`
	sqlite3 $SQLITEFILE "SELECT vmdirectory,isodirectory,connectstring FROM servers WHERE hostname='$1'" | while read line; do
		IFS="|" read -r -a array <<< "$line"
		IFS=";" read -r -a dirs <<< "${array[0]};${array[1]}"
		for dir in ${dirs[@]}; do
			if [ $dir == $DDIR ]; then
				if [ -z ${array[2]} ]; then
					if [ -e $2 ]; then rm $2 && echo "delete completed"; fi
				else
					su nlvmi -c "ssh ${array[2]} \"if [ -e $2 ]; then rm $2 && echo delete completed; fi\""
				fi
			fi
		done
	done
}

function createimg {
	re='^[0-9]+$'
	if ! [[ $2 =~ $re ]] ; then
		echo "size argument is not numeric" >&2; exit 1
	fi
	IFS=';' read -r -a T <<< "$1"
	TDIR=`echo ${T[1]} | rev | cut -d "/" -f 2- | rev`
	TFOUND="no"
	declare -a A=`sqlite3 $SQLITEFILE "SELECT vmdirectory,connectstring FROM servers WHERE hostname='${T[0]}'" | while read line; do
		IFS="|" read -r -a array <<< "$line"
		IFS=";" read -r -a dirs <<< "${array[0]}"
		for di in ${dirs[@]}; do
			if [ $di == $TDIR ]; then
				TFOUND="yes"
				TCONN=${array[1]}
			fi
		done
		echo "($TFOUND $TCONN)"
	done`
	if [ ${A[0]} == "yes" ]; then
		if [ -z ${A[1]} ]; then
			qemu-img create -f qcow2 ${T[1]} ${2}G && echo "creatimg completed"
		else
			su nlvmi -c "ssh ${A[1]} \"qemu-img create -f qcow2 ${T[1]} ${2}G\"" && echo "createimg completed"
		fi
	fi
}

function copyimg {
	IFS=';' read -r -a S <<< "$1"
	IFS=';' read -r -a T <<< "$2"
	SDIR=`echo ${S[1]} | rev | cut -d "/" -f 2- | rev`
	TDIR=`echo ${T[1]} | rev | cut -d "/" -f 2- | rev`
	SFOUND="no"
	TFOUND="no"
	for m in S T; do
		A="$m"DIR
		declare -a B=`sqlite3 $SQLITEFILE "SELECT vmdirectory,isodirectory,connectstring FROM servers WHERE hostname='${!m[0]}'" | while read line; do
			IFS='|' read -r -a array <<< "$line"
			IFS=';' read -r -a dirs <<< "${array[0]};${array[1]}"
			for di in ${dirs[@]}; do
				if [ $di == ${!A} ]; then
					if [ $m == "S" ]; then
						if [ -z ${array[2]} ]; then
							if [ -e ${S[1]} ]; then FOUND="yes"; CONN="empty"; fi
						else
							su nlvmi -c "ssh ${array[2]} \"if [ ! -e ${S[1]} ]; then exit 1; fi\"" && FOUND="yes"; CONN=${array[2]}
						fi
					elif [ $m == "T" ]; then FOUND="yes"; CONN=${array[2]}; if [ -z $CONN ]; then CONN="empty"; fi; fi
				fi
			done
			echo "($FOUND $CONN)"
		done`
		export ${m}FOUND=${B[0]}
		export ${m}CONN=${B[1]}
	done
	if [ $SFOUND == "yes" ] && [ $TFOUND == "yes" ]; then
		if [ $SCONN == "empty" ] && [ $TCONN == "empty" ]; then
			if [ -z $FID ]; then
				FID="nldebugger"
			fi
			rsync --progress ${S[1]} ${T[1]} >/tmp/$FID && echo done >/tmp/$FID || echo fail >/tmp/$FID
		elif [ $SCONN == "empty" ]; then
			su nlvmi -c "rsync --progress ${S[1]} $TCONN:${T[1]} >/tmp/$FID && echo done >/tmp/$FID || echo fail >/tmp/$FID"
		elif [ $SCONN == $TCONN ]; then
			su nlvmi -c "ssh $TCONN \"rsync --progress ${S[1]} ${T[1]}\"" >/tmp/$FID && echo done >/tmp/$FID || echo fail >/tmp/$FID
		elif [ $TCONN == "empty" ]; then
			su nlvmi -c "rsync --progress $SCONN:${S[1]} ${T[1]} >/tmp/$FID && echo done >/tmp/$FID || echo fail >/tmp/$FID"
		else
			su nlvmi -c "echo "noprogressavailable" >/tmp/$FID && scp -3 $SCONN:${S[1]} $TCONN:${T[1]}" && echo done >/tmp/$FID || echo fail >/tmp/$FID
		fi
	fi
}

#mainloop
if [ $# -gt 0 ]; then
	if [ $1 == "createdb" ]; then
		createdb
	elif [ $1 == "autostart" ]; then
		vmautostart
	elif [ $1 == "checkvm" ]; then
		if [ -z $2 ]; then echo "checkvm needs two arguments"; fi
		checkvm $2
	elif [ $1 == "delautostart" ]; then
		if [ $2 == "local" ]; then
			rm /home/nlvmi/start*-$3.tmp
			rm /home/nlvmi/start*-$3.tmp.sha512
		else
			su nlvmi -c "ssh $2 \"rm /home/nlvmi/start*-$3.tmp; rm /home/nlvmi/start*-$3.tmp.sha512\""
		fi
	elif [ $1 == "delnginx" ]; then
		if [ $2 == "local" ]; then
			rm $NGINXCONFIGPATH/$3.conf
			if [ -n $NGINXRESTARTCOMMAND ]; then $NGINXRESTARTCOMMAND; fi
		fi
	elif [ $1 == "start" ]; then
		if [ -z $2 ]; then echo "start needs a vmname!"; exit 1; fi
		VMFOUND="no"
		if [ $LOGLEVEL -gt "2" ]; then echo "searching for vmname $2"; fi
		sqlite3 $SQLITEFILE "SELECT id FROM vms WHERE vmname='$2'" | (while read line; do
			IFS='|' read -r -a arrays <<< "$line"
			declare VMFOUND="yes"
			export "$VMFOUND"
			vmstart $arrays
		done
		if [[ $VMFOUND == "no" ]]; then echo "no VM with that name found!"; exit 1; fi)
	elif [ $1 == "stop" ]; then
		if [ -z $2 ]; then echo "stop needs a vmname!"; exit 1; fi
		VMFOUND="no"
		if [ $LOGLEVEL -gt "2" ]; then echo "searching for vmname $2"; fi
		sqlite3 $SQLITEFILE "SELECT id FROM vms WHERE vmname='$2'" | (while read line; do
			IFS='|' read -r -a arrays <<< "$line"
			declare VMFOUND="yes"
			export "$VMFOUND"
			vmstop $2
		done
			if [[ $VMFOUND == "no" ]]; then echo "no VM with that name found!"; exit 1; fi)
	elif [ $1 == "stopall" ]; then
		stopall
	elif [ $1 == "listdirs" ]; then
		if [ -z $2 ] || [ -z $3 ]; then echo listdirs needs two arguments; exit 1; fi
		listdirs $2 $3
	elif [ $1 == "createimg" ]; then
		if [ -z $2 ] || [ -z $3 ]; then echo createimg needs two arguments; exit 1; fi
		createimg $2 $3
	elif [ $1 == "copyimg" ]; then
		if [ -z $2 ] || [ -z $3 ]; then echo copyimg needs two arguments; exit 1; fi
		copyimg $2 $3
	elif [ $1 == "delimg" ]; then
		if [ -z $2 ] || [ -z $3 ]; then echo delimg needs two arguments; exit 1; fi
		delimg $2 $3
	elif [ $1 == "remote" ]; then
		if [ ! -z $MASTERSERVER ]; then
			if `echo $SSH_CLIENT | grep "$MASTERSERVER " &>/dev/null`; then
				if [ -e $2 ]; then
					source /etc/profile
					openssl dgst -sha512 -verify  <(openssl x509 -in "/etc/nlvmi/nlvmi_sign.crt"  -pubkey -noout) -signature $2.sha512 $2 >/dev/null && /bin/bash $2 || echo "signature failed!!"
				fi
			else
				echo "not allowed";
			fi
		fi
	elif [ $1 == "createkey" ]; then
		if [ ! -z $MASTERSERVER ]; then
			createkey
		fi
	fi
else
    checkdb
fi
