#!/bin/bash # (1) Primary setup #--------------------------------------------------------# # (1) Get current ABS directory ROOT=$(dirname `realpath $0`); # (2) Check required arguments test $# -lt 4 && echo -e "ERR: Missing arguments\n\nARGUMENTS:\n\tname\t\tThe name of the machine\n\ttarget_host\tThe hostname (or ip) of the target\n\tout_port\tThe port you want to use to send\n\tin_port\t\tThe port the peer uses to listen\n\ttrigger_port\tOptional param. Used to trigger the peer connection\n" && exit 1; # (3) Manage optional param # TRIGGER=""; test $# -ge 5 && TRIGGER="$5"; # (2) Secondary setup #--------------------------------------------------------# # (1) Create config dir (if doesn't exist) # test ! -d $ROOT/config && mkdir $ROOT/config; # (2) Reset configuration file (if exists) CONF_FILE=$ROOT/config/$1; test -f $CONF_FILE && rm $CONF_FILE; # (3) Create buffer paths BUF_IN="/tmp/buf_in_$1"; BUF_OUT="/tmp/buf_out_$1"; # (4) Flush buffers echo -ne "" > $BUF_IN; echo -ne "" > $BUF_OUT; # (3) Launch INPUT server #--------------------------------------------------------# # (1) Start the script in background ( trap "echo 'launch.server.killed'; kill -9 %1 2>/dev/null && echo 'launch.server.nc.killed';" INT KILL; infail=0; # kill script after 10 failures while [ $infail -lt 10 ]; do # main command echo "(.) started [input]"; ( nc -lp $4 >> $BUF_IN 2> /dev/null && infail=0 || ( infail=`expr $infail + 1`; exit 1 ) || echo "Port $4 already in use" ) & wait $!; # try to kill proccess that uses port if failed and such proccess exists if [ $infail -eq 0 ]; then echo " > END [input]"; else echo " > FAIL [input]"; LISTEN_PID=`lsof -n -i4TCP:$4 | grep LISTEN | awk '{print $2}'`; test ! -z "$LISTEN_PID" && kill -9 $LISTEN_PID 2>/dev/null; fi; done; )& # (2) Store the background proccess PID # IN_PID=$!; ################################ # IF SET, SEND TRIGGER TO PEER # ################################ test ! -z "$TRIGGER" && ( echo "(.) sending [trigger:$2:$TRIGGER]"; bash -c "exec 3<>/dev/tcp/$2/$TRIGGER" && echo " > SENT [trigger:$2:$TRIGGER]" || echo " > ERR [trigger:$2:$TRIGGER]" ) ################################## # WAIT 2s FOR THE PEER TO LISTEN # ################################## sleep 2; # (4) Launch OUTPUT client #--------------------------------------------------------# # (1) Start the script in background ( trap "echo 'launch.client.killed'; kill -9 %1 2>/dev/null && echo 'launch.client.nc.killed';" INT KILL; outfail=0; # stop after 5 failed attempts while [ $outfail -lt 5 ]; do # main command echo "(.) started [output]"; ( tail -f $BUF_OUT | nc $2 $3 2>/dev/null && outfail=0 || ( outfail=`expr $outfail + 1`; exit 1 ) || echo "Cannot connect to $2:$3" ) & wait $!; test $outfail -eq 0 && echo " > END [output]" || echo " > FAIL [output]"; sleep 1; # can sleep because the buffer is never flushed done; )& # (2) Store the background proccess PID # OUT_PID=$!; # (5) Store the config file for 'write' + 'send' to work properly #--------------------------------------------------------# # (1) Store config file in 'config/$NAME' echo -e "#!/bin/bash\nBUF_IN=\"$BUF_IN\"; BUF_OUT=\"$BUF_OUT\";\nIN_PID=$IN_PID; OUT_PID=$OUT_PID;\n" > $CONF_FILE; # (2) Notify server started # # (6) Manage ending proccess #--------------------------------------------------------# # (1) Kill subproccesses if Ctrl+C # on_exit(){ echo "launch.kill"; ## {1} Kill client ## echo 'launch.client.kill'; kill -9 $OUT_PID 2>/dev/null; ## {2} Kill server ## echo 'launch.server.kill'; kill -9 $IN_PID 2>/dev/null; ## {3} Remove config file ## echo 'launch.config.delete'; rm $CONF_FILE 2>/dev/null; ## {4} Remove buffers ## echo 'launch.buffer.in.delete'; echo 'launch.buffer.out.delete'; rm $BUF_OUT $BUF_IN 2>/dev/null; exit 0; } # (2) Setup trap for signals INT + KILL # trap "on_exit" INT KILL; # (2) Wait for daemons to stop # wait $OUT_PID; wait $IN_PID; on_exit;