Archive for the ‘Shell Scripting’ Category

magic_shutdown: Shutdown computer remotely using Magic Packet


2008
02.15

The title says it all. If you don’t know what a Magic Packet is then read here. Below is the code of a shell script (I call magic_shutdown) that uses tcpdump to listen for Magic Packets. When it receives on then the shell script verifies its content to make sure that this packet was meant for this computer. Note this script doesn’t require that your network interface card support Wake-on-LAN. It has no special hardware dependencies.

All-in-all, this script lets you create create a shortcut which will act as remote power button for your computer. Press it to turn the computer ON. Press it again to turn the computer OFF.

Get magic_shutdown‘s code
License: GNU Public License version 3.

#!/bin/bash
#Author:AppleGrew
#License:GPL version 3

listenPort=9
interface="eth0"

#Forking to daemonize...
if [[ "$2" != "forked" ]]
then
 echo "Forking $0..."
 "$0" "$1" forked &
 echo "Forked."
 exit 0
fi

#Creating pid file
ppid=$$
echo $ppid >"$1"

echo "Started"
mac=`ifconfig "$interface"|head -n1|sed  -e 's/.*HWaddr \([0-9:a-fA-F]*\)/\1/g' -e 's/://g'`
pckt_expect=`echo "ff ff ff ff ff ff $mac $mac $mac $mac $mac $mac $mac $mac"|sed 's/ //g'|tr 'A-Z' 'a-z'`
while `true`
do
 pckt_data=`tcpdump -i "$interface" -x -c 1 udp port ${listenPort}`
 if [[ $? != 0 ]]
 then
  echo "tcpdump returned error."
  exit 1
 fi

 pckt_data=`echo "$pckt_data" | \
  grep '0x[0-9]*:'| \
  tr 'A-Z' 'a-z'| \
  sed 's/[ \t]//g'| \
  sed 's/0x[0-9]*:\([0-9a-f]*\)/\1/g'| \
  tr -d '\n\r'| \
  cut -c 57-`
 if [[ "$pckt_data" == "$pckt_expect" ]]
 then
  echo "Matched! Received Magic packet shutting down..."
  shutdown -P now #Not recommended
  #For Gnome #Doesn't work dunno why?
  #dbus-send --session --dest=org.gnome.PowerManager \
  # --type=method_call --print-reply --reply-timeout=2000 \
  # /org/gnome/PowerManager org.gnome.PowerManager.Shutdown
  #For KDE 3.5
  #dcop `dcop|grep power-manager` power-manager shutdown
  exit 0
 fi
done

echo "EXITED"
exit 0

Below is the startup script that must be used to launch magic_shutdown script.

Get launch_magic_shutdown‘s code
License: GNU Public License version 3.

#!/bin/bash
#Author:AppleGrew
#License:GPL version 3

SCRIPT="/opt/magic_shutdown"
PID_FILE="/var/run/magic_shutdown.pid"
case "$1" in
 start)
 test -f "$PID_FILE" && echo "Already Running..." && exit 1
 "$SCRIPT" "$PID_FILE"
 echo "Started"
 ;;
 stop)
 pid=`cat "$PID_FILE"`

 tcpPid=`pgrep -P $pid tcpdump`
 kill -9 $pid
 kill -2 $tcpPid
 if [ -f "$PID_FILE" ] && ! ps -p $pid >/dev/null
 then
 rm -f "$PID_FILE"
 else
 echo "Failed to delete pid file. Maybe its already deleted."
 fi
 echo "Stopped"
 ;;
esac

Installations:-
Assuming that you have downloaded the above two codes into your home directory. Now run the following commands.

sudo cp launch_magic_shutdown /etc/init.d
sudo chmod a+x /etc/init.d/launch_magic_shutdown
cd /etc/rc2.d
sudo ln -s ../init.d/launch_magic_shutdown S99launch_magic_shutdown

sudo cp magic_shutdown /opt/magic_shutdown
sudo chmod a+x /opt/magic_shutdown

Hope this helps. Report in the comments section if you encounter any problem.

autoWallChange: Automatically changes wallpaper


2008
02.10

About the script
This is a KDE (may not work in KDE 4) only shell script which changes wallpaper every few minutes as set by you. KDE too has a built-in feature to change wallpaper but it has few limitations:-

  1. It doesn’t show pictures within the sub-directories of the given path.
  2. It applies the same picture position setting (i.e. Scala&Crop, Tile, etc.) to all the pictures.

This script allows you to apply different picture position settings to pictures from different directories. e.g. if you use the following settings

picDir=”/home/geek/Pictures”
shapeDir=”Rectangle Square Tall”
shapeMode=”8 8 5″

Then pictures from /home/geek/Pictures/Rectangle and /home/geek/Pictures/Square will be shown using Scale & Crop position setting, and pictures from /home/geek/Pictures/Tall will be Titled Maxpect. Following is the table for which number stands for what position setting.

  • 1 -> Centered
  • 2 -> Titled
  • 3 -> Center Titled
  • 4 -> Centered Maxpect
  • 5 -> Titled Maxpect
  • 6 -> Scaled
  • 7 -> Centered Auto Fit
  • 8 -> Scale & Crop

This script is best used with my iflickrDown script (see here).

The code
License: GNU Public License version 3.

#!/bin/bash
#Coded by AppleGrew
#License: GPL version 3

#############################################
############Alternative way to set###########
##########the following variables############
#Create another shell script and export it  #
#from there.                                #
#===============SAMPLE=======================
#  #!/bin/bash
#  export picDir="/home/geek/Pictures" #Donot put '/' at the end
#  export shapeDir="Square Rectangle Tall"
#  export shapeMode="8 8 5"
#  export changeWallIntv=2 #in mins
#
#  ./autoWallChange >/tmp/autoWall.log & #Launching the main program.
############Configs##########################
picDir="" #Donot put '/' at the end
shapeDir=""
shapeMode=""
changeWallIntv=1 #in mins
#############################################

tmpFile="/tmp/autoWallChange.tmp"
lstFile="/tmp/autoWallChange.lst"
fileLen=0
factor=0

shapeDir=( $shapeDir )
shapeMode=( $shapeMode )

echo "${shapeDir[@]}"
echo "${shapeMode[@]}"

function refreshFileList(){
       local DIR_PATH=$1
       local sM=$2
       echo "Refreshing content of '$DIR_PATH', shape mode is $sM"

       if [ -a "$DIR_PATH" ] && [ -d "$DIR_PATH" ] && [ -w "$DIR_PATH" ]
       then
               for f in `find "$DIR_PATH" -type f -print | sed 's/ /|/g'`
               do
                       matchFound=0
                       for fl in `cat "$tmpFile"`
                       do
                               fl=`echo "$fl"|sed -e 's/\([^>]*\)>\([^>]*\)/\1\n\2/g'|head -n 1|tail -n 1`
                               [[ "$fl" == "$f" ]] && matchFound=1 && break
                       done
                       [[ $matchFound == 0 ]] && printf "%s>%d\n" $f $sM >>"$tmpFile" && let 'fileLen++'
               done
       let 'factor=(fileLen-1)*100000000/32767'
       fi
       echo "Refreshed"
}

printf "">"$tmpFile" #Creating new empty file.
i=0
for shape in ${shapeDir[@]}
do
       test -a "$picDir/$shape" && find -L "$picDir/$shape" -type f -print > "$lstFile.$i"
       test -a "$picDir/$shape" && refreshFileList "$picDir/$shape" ${shapeMode[$i]}
       let 'i++'
done

shownPicsLine=0
lastL=""
totShown=0
RANDOM=$$
while true
do
       let 'l=(factor*RANDOM+100000000)/100000000'
       test $totShown -ge $fileLen && lastL="" && totShown=0
       while echo "$lastL" | grep -o "\"$l\"" > /dev/null
       do
               let "l++"
               test $l -gt $fileLen && l=1
       done
       lastL="${lastL}\"$l\""
       let "totShown++"

       pfileL=`cat "$tmpFile"|head -n $l|tail -n 1`
       pfilePath=`echo "$pfileL"|sed -e 's/\([^>]*\)>\([^>]*\)/\1\n\2/g'|head -n 1|tail -n 1|sed 's/|/ /g'`
       pfileMode=`echo "$pfileL"|sed -e 's/\([^>]*\)>\([^>]*\)/\1\n\2/g'|head -n 2|tail -n 1`

       if [ $totShown -ge $fileLen ]
       then
               lastL=""
               totShown=0
       fi

       [ -f "$pfilePath" ] && dcop kdesktop KBackgroundIface setWallpaper "$pfilePath" "$pfileMode"

       i=0
       for shape in ${shapeDir[@]}
       do
               if test -a "$picDir/$shape" && ! find -L "$picDir/$shape" -type f -print | diff "$lstFile.$i" ->/dev/null
               then
                       echo "'$picDir/$shape' content changed"
                       refreshFileList "$picDir/$shape" ${shapeMode[$i]}
                       find -L "$picDir/$shape" -type f -print > "$lstFile.$i"
               fi
               let 'i++'
       done
       echo "sleeping"
       sleep "${changeWallIntv}m"
done<