#!/bin/bash
#
# Produkt Dozziego, rozpowszechniany na licencji GPL.
# Sam skrypt nie jest idiotoodporny, gdybym go takim mial uczynic, skrypt
# rozroslby sie do rozmiarow Emacsa. Chociaz wstawilem dosc elementarna
# kontrole bledow.
# Mozna zabijac wiele procesow na raz, specyfikujac domyslny sygnal dla
# wszystkich procesow i osobne sygnaly dla kazdej z podanych masek z osobna.
#
# UWAGA: z pewnych wzgledow maska jest obustronnie przylepiana do koncow
# slowa, dokladnie jak przy uzyciu \<maska\> (bo i tez to zastosowalem ;) )
# Jesli chcesz ubic vim-a, nie ubijajac gvim-a, wystarczy wpisac "murder vim".
# To zachowanie latwo zmienic usuwajac odpowiedni wpis.
#
# INSTALACJA: skopiuj ten plik dokadkolwiek, byle to miejsce bylo
# przegladane podczas szukania polecen (niezlym pomyslem jest ~/bin/), a potem
# nadaj temu plikowi atrybuty wykonywalnosci poleceniem "chmod a+x murder".
# To wszystko.
#

if    [ $# -eq "0" ] || [ "$1" = "--help" ] \
   || [ "$1" = "-h" ] || [ "$1" = "-?" ]; then
  echo -n "Uzycie: $(basename "$0") [-w] [-X] maska [-Y] (maska [-Y] ...)"
  echo
  echo "maska - wyrazenie zrozumiale dla grepa pasujace pocesy do zabicia"
  echo "-w - szukaj calych slow zamiast jakiegokolwiek fragmentu"
  echo "Y - opcjonalny numer sygnalu, jakim grupa procesow ma by zakonczona"
  echo "X - opcjonalny sygnal, jakim beda konczone procesy bez podanego -Y"
  exit 0
fi

FINDALLWORDS="false"
# szukamy (albo i nie) calych slow 
if [ "$1" = "-w" ]; then
  FINDALLWORDS="true"
  shift
fi

# domyslne opcje zabijania procesow (domyslnie zabijamy na smierc)
if echo "$1" | grep -- '^-[0-9]\{1,2\}$' &> /dev/null; then
  DEFKILLOPTS=$1
  shift
else
  DEFKILLOPTS="-9"
fi

# szukamy (albo i nie) calych slow 
if [ "$1" = "-w" ]; then
  FINDALLWORDS="true"
  shift
fi

while [ "$#" -ge "1" ]; do
  # zapamietujemy maske procesow, przyda sie do wypisania komunikatu o bledzie
  MASK="$1"
  shift
  # listujemy procesy uzytkownika, filtrujemy tylko te potrzebne, wycinamy
  # same pidy znalezionych procesow
  if [ $FINDALLWORDS = true ]; then
    PROCESY=$(ps -u $USER | grep \\\<$MASK\\\> | cut -c 1-6)
  else
    PROCESY=$(ps -u $USER | grep $MASK | cut -c 1-6)
  fi

  # jesli ilosc znalezionych procesow jest niezerowa
  if [ `echo $PROCESY | wc -w` -ge 1 ]; then
    # jesli sa podane opcje zabijania, to je odczytujemy, jesli nie - ustawiamy
    # domyslne opcje
    if echo "$1" | grep -- '^-[0-9]\{1,2\}$' &> /dev/null; then
      KILLOPTS=$1
      shift
    else
      KILLOPTS="$DEFKILLOPTS"
    fi

    # zabijamy procesy z odpowiednimi opcjami
    kill $KILLOPTS $PROCESY
  else
    echo "Nie ma zadnych procesow pasujacych do \"$MASK\""
  fi
done
