#!/bin/bash
#
# $Revision: 1.83 $, $Date: 2004/03/10 20:28:15 $
#
#
# Function name:	Number of args:	Description of args:
# dml_buttons():	optional	Ok/Anuluj/Edytuj/Powrt/Pomoc/Przywr/Kod/Log/Wyjcie;
# dml_cancel_check():	1 arg		$1 is file to return to;
# dml_edit_check():	1 arg		$1 is file to edit;
# dml_help_check():	1 arg		arg1 is file to view in less;
# dml_check_the_rest():	1 arg		check if exit|source|ok were pressed, 
#					arg1 is file to return to after run_main();
# dml_recover_check():	2 args		copy $1 (backup file) into $2 (current);
# install_if_missing(): 1 arg		$1 is $packets_to_install;
# backup_file(): 	1 arg	 	backup if not backed up already;
# show_message		1 arg		$1 is the message for the user 
# show_verbose_message	optional	$1 is the the extra message for the user, $2(opt) is file to be displayed
# line_remove():	2 args		$1 is string in line to remove, $2 is the file
# line_replace():	3 or 4 args	$1 is string in line before, $2 is line after, $3 is /the/file
#					$4 is optional separator for s/BAR/bar/ (take care of $BAR=/usr/bin)
#					see comments & examples below
# dir_string_replace(): opt		Mainly for usage inside pldconf for it's developers
#					replaces all strings $FROM in given directory $DIR. 
#					$FROM & $TO are strings, $DIR is directory to work in (default .), 
#					$DROP is a match for filenames to leave unchanged
#					$EXT is file extensions (default all), $SEPARATOR is separator (default %)
# example usage:
# dir_string_replace FROM=BAR TO=bar DIR=/usr/share/pldconf EXT="pl\ sh\ txt" DROP="this_file\ foo_file"
#							 note the  ^   ^		     ^	       
#
#					Better do backup of the $DIR and then see diff -r $DIR $DIR.bak;
# yes_no():		2		Show them the dialog and wait for [t/n] answer. $1 is message, 
#					$2 command to be executed;
# install_packets():	1 arg		$1 is set of packets to install. This func is a poldek's wrapper -
#					poldek won't forgive even one missing package - it simply
#					drops the whole list and doesn't install anything - this func
#					adresses the issue;
#
#   CAREFUL WITH line_replace() !
#
# Be careful about example file below:
# nameserver 192.168.1.100
#
# Say you want to add a new nameserver 192.168.1.1  ->  line_replace "192.168.1.1" "192.168.1.1" /etc/resolv.conf 
# The above call is supposed to	replace old 192.168.1.1 to avoid duplicate entries in /etc/resolv.conf, but 
# 192.168.1.1 matches 192.168.1.100 also - that would cause overwriting 192.168.1.100 into 192.168.1.1 . 
# In such cases use line_replace "192.168.1.1\b" "192.168.1.1" /etc/resolv.conf  (see man perlre for \b)
# 					     ^^
# This aplies to files that may contain strings being substrings of other strings, (i.e. /etc/resolv.conf,
# /etc/hosts): 192.168.1.2 192.168.1.23 192.168.1.230 or ALA_MA_KOTA ALA ALA_MA
#
# Default SEPARATOR is now %. Only if one needs to change string containing % there's a need to set SEPARATOR:
# example usage: line_replace "this is % mark" "this is BAR mark" file SEPARATOR=/
#
# example usage: line_replace "user\@.*" "jasiek\@onet.pl" file
# example usage: line_replace "MOUSETYPE=" "MOUSETYPE=$TYPE" ${FILE_CONF} 
# example usage: line_replace "192.168.1.1\b" "192.168.1.1" /etc/resolv.conf 
# example usage: line_replace "/usr/local/bin/" "/usr/bin/" file  
#
#
#
# Variables list:	Description:
# dml_ok		associated with dml_check_the_rest();
# dml_cancel		associated with dml_cancel_check();
# dml_edit		associated with dml_edit_check();
# dml_help		associated with dml_help_check();
# dml_recover		associated with dml_recover_check();
# dml_source		associated with dml_check_the_rest();
# dml_exit		associated with dml_check_the_rest();
# -----------------------

. /etc/pldconf/ustawienia

export KERNEL_VER=`uname -r | cut -b1-3`
export PLDCONF_VERSION=0.3.11
export EXEC_PREFIX=/usr/bin
export DATA_DIR=/usr/share/pldconf
export CONF_DIR=/etc/pldconf
export VF_MNTPOINT=/mnt/cdrom 
export VF_EJECT=eject
export PATH="$PATH:/usr/X11R6/bin"

if [ -z $EDITOR ]; then
	which vim 1>/dev/null && export EDITOR=vim || { echo "Ustaw domylny edytor w pldconf -> Inne"; exit; }
fi

export MODULES_CONFIG=/etc/modules.conf
[ $KERNEL_VER = 2.6 ] && export MODULES_CONFIG=/etc/modprobe.conf

show_message () {
	echo; echo "$1"; echo
	[ $TIMEOUT_MODE -eq 1 ] && sleep $SLEEP_TIME || { echo '<enter>'; read; }
}

show_verbose_message () {
	[ $VERBOSE_MODE -eq 1 ] && { echo; echo; eval "$2"; echo; echo; show_message "$1"; }
}

line_replace () {
	unset addon
	[ -f $3 ] || { touch $3; show_verbose_message "Utworzenie brakujcego pliku $3"; }

	# there's no such entry in the given file yet
	cat $3 | egrep "^$1" || { echo "$2" >> $3; addon="Nowy wpis"; }

	# entry exists, doing the replace
	if [ -z "$addon" ]; then
		SEPARATOR=%; eval $4
		addon="SEPARATOR=$SEPARATOR"
		perl -pi -e "s$SEPARATOR^$1.*$SEPARATOR$2$SEPARATOR" $3
	fi
	show_verbose_message "$3: Po zmianie \"$1\" na \"$2\"    $addon" "cat $3"
}


line_remove () {
	if [ -f "$2" ]; then
		TMPFILE=`mktemp /tmp/pldconf.XXXXXX` || exit
		grep -v "$1" "$2" > $TMPFILE
		cp $TMPFILE $2 # cp vs mv preserves access mode for the file
		rm $TMPFILE
		show_verbose_message "$2: Po usuniciu linii zawierajcej \"$1\"  " "cat $2"
	else
		show_verbose_message "Brak pliku \"$2\""
	fi
}

leave_section () {
	sed -i -n -e "/$1/,/$2/p" $3
	show_verbose_message "$3: Po zmianie \"$1\" na \"$2\" " "cat $3"
}

drop_section () {
	sed -i -e "/$1/,/$2/d" $3
	show_verbose_message "$3: Po zmianie \"$1\" na \"$2\" " "cat $3"
}

dir_string_replace () {
	unset FROM TO DIR DROP; EXT='*'; SEPARATOR=%; DIR=.
	for k in "$@"; do
		eval "$k"	# passed $FROM, $TO, $DIR, $DROP, $EXT, $SEPARATOR 
	done
	echo "Przykad: dir_string_replace FROM=BAR TO=bar DIR=/usr/share/pldconf EXT=\"pl\ sh\ txt\" DROP=\"svn\ CVS\""
	echo "FROM=\"$FROM\" TO=\"$TO\" DIR=$DIR  DROP=\"$DROP\" EXT=\"$EXT\"  SEPARATOR=$SEPARATOR"; echo "<enter>"
	read
	if [ "X$EXT" = "X*" ]; then
		sub_dir_string_replace "*"
	else
		for i in $EXT; do
			sub_dir_string_replace "*$i"
		done
	fi
	echo; echo; echo "Znalezione pliki sed*"; find $DIR -iname "sed*"
	yes_no "Usun pliki sed* ?" "find $DIR -iname \"sed*\" -exec rm -rf {} \;"

	echo; echo; echo "Znalezione pliki *~"; find $DIR -iname "*~"
	yes_no "Usun pliki *~ ?" "find $DIR -iname \"*~\" -exec rm -rf {} \;"
}

sub_dir_string_replace () {
	for j in `find $DIR -name "$1"`; do

		# substitute only in text files, binary are skipped
		file $j | grep text 1>&2 > /dev/null || { echo "$j: to nie jest plik tekstowy, pomijam"; continue; }

		# drop file names that match $DROP
		for k in $DROP; do
			echo $j | grep $k 1>&2 > /dev/null &&  { echo "$j: podany jako DROP, pomijam"; continue 2; }
		done

		echo "Zamiana w $j..."
		sed -i "s${SEPARATOR}${FROM}${SEPARATOR}${TO}${SEPARATOR}g" $j
	done
}

yes_no() {
	echo; echo "$1" 
	echo "[t/n]"
	read a
	[ "$a" = "t" ] && { echo "Wykonuj $2"; echo; eval $2; }
}

backup_file () {
	[ `id -nu` = root ] && BACKUP_DIR=${CONF_DIR} || BACKUP_DIR=~/.pldconf
	if [ ! -f $BACKUP_DIR/`basename $1` ]; then
		show_verbose_message "Backup $1 w $BACKUP_DIR/"
		mkdir -p $BACKUP_DIR
		cp $1 $BACKUP_DIR/
	else
		show_verbose_message "Backup $1 w $BACKUP_DIR/: OK, plik ju istnieje"
	fi
}

dml_buttons () {
	for button in $@; do
		case $button in
			Ok)
			echo "<button id=dml_ok caption=Ok>"
			;;
			Anuluj)
			echo "<button id=dml_cancel caption=Anuluj>"
			;;
			Powrt)
			echo "<button id=dml_cancel caption=Powrt>"
			;;
			Edytuj)
			echo "<button id=dml_edit caption=Edytuj>"
			;;
			Pomoc)
			echo "<button id=dml_help caption=Pomoc>"
			;;
			Przywr)
			echo "<button id=dml_recover caption=Przywr>"
			;;
		esac
	done
	echo "<br><button id=dml_source caption='Poka kod'><button id=dml_exit caption=Wyjcie>" 
}

dml_cancel_check() {
	[ "X$dml_cancel" = "Xyes" ] && exec $1
}

dml_edit_check() {
	[ "X$dml_edit" = "Xyes" ] && { $EDITOR $1; exec $0; }
}

dml_help_check() {
	[ "X$dml_help" =  "Xyes" ] && { $PLDCONF_PAGER "$1"; exec $0; }
}

dml_recover_check(){
	[ "$dml_recover" = "yes" ] && { show_verbose_message "Kopiuj $1 na $2"; cp $1 $2; exec $0; }
}

dml_check_the_rest() {
	[ "X$dml_source" =  "Xyes" ] && { $EDITOR $0; exec $0; }
	[ "X$dml_ok" = "Xyes" ] && { run_main 2>/dev/null; exec $1; }
	[ "X$dml_exit" = "Xyes" ] && exit
}

install_if_missing() {
	[ "X$ERRORS_HANDLE" = "XALWAYS_IGNORE" ]  && return 0 #This is specially for RO filesystems (PLD LiveCD guys)
							#It says missing packets were succesfully installed!
	packets_to_install="$1"
	case $packets_to_install in
		gnome-session)
		packets_to_install="gnome-desktop gnome-themes gnome-session gnome-panel nautilus metacity metacity-themes-Simple metacity-themes-Atlanta metacity-themes-Crux metacity-themes-Metabox metacity-themes-AgingGorilla"
		;;
		startkde)
		packets_to_install="kdebase"
		;;
		wmaker)
		packets_to_install="WindowMaker"
		;;
		xfwm4)
		packets_to_install="xfwm4 xfce4-panel xfce-utils xfce4-mixer"
		;;
		cups)
		packets_to_install="cups cups-clients cups-filter-pstoraster"
		;;
		alsa)
		packets_to_install="kernel-sound-alsa alsa-utils-init aumix"
		;;
		pcmcia)
		packets_to_install="pcmcia-cs kernel-pcmcia-cs"
		;;
		mail)
		packets_to_install="procmail fetchmail"
		;;
		mcedit)
		packets_to_install="mc"
		;;
	esac

	rpm -q $packets_to_install 1>&2 >/dev/null
	if [ $? -ne 0 ]; then
		echo; echo; echo "Brak przynajmniej jednego z poniszych pakietw:"
		echo "$packets_to_install"; echo 
		[ `id -nu` != root ] && { show_message "Tylko root moe instalowa pakiety..."; return 1; }

		if [ "X$ERRORS_HANDLE" = "XALWAYS_ASK" ]; then
			cat << EOF
<enter>	-instaluj
n	-nie instaluj
a	-automatycznie naprawiaj wszyskie bdy
w	-wycz ostrzeganie i nigdy nie naprawiaj zwracajc pomylne wykonanie operacji (nie zalecane)

Powysze opcje mog by zmieniane w pldconf -> Ustawienia
<ctrl+c> przerywa program

EOF
			read input
			case $input in
				n)
				return 1
				;;
				a)
				line_replace "export ERRORS_HANDLE" "export ERRORS_HANDLE=ALWAYS_FIX" ${CONF_DIR}/ustawienia
				export ERRORS_HANDLE=ALWAYS_FIX
				;;
				w)
				line_replace "export ERRORS_HANDLE" "export ERRORS_HANDLE=ALWAYS_IGNORE" ${CONF_DIR}/ustawienia
				export ERRORS_HANDLE=ALWAYS_IGNORE
				return 0 	
				;;
			esac
		fi

		# we enter here after <enter> or automatically with $ERRORS_HANDLE != {ALWAYS_IGNORE,ALWAYS_ASK}
		install_packets "$packets_to_install" 
		rpm -q $packets_to_install 1>&2 >/dev/null
		return $? # callers may like to check the return value, 0 means all packets are succesfully installed
	fi
}

install_packets() {
	packets_list=$1
	show_verbose_message "poldek -vU $packets_list"	
	poldek_log=`mktemp /tmp/pldconf_poldek_log.XXXXXX` || exit
	poldek -vU $packets_list --log=$poldek_log
	if [ $? -ne 0 ]; then
		for i in $packets_list; do
			if [ -n "`echo $i | grep \*`" ]; then # theme_packs* 
				separate_install_set="$separate_install_set $i"
			else
				grep "nie znaleziono $i" $poldek_log || 
				grep "$i not found" $poldek_log || 
				install_set="$install_set $i"
			fi
		done
		[ -n "$install_set" ] && poldek -vU $install_set 
		[ -n "$separate_install_set" ] && poldek -vU $separate_install_set
		show_message "Bdy wynikaj z nieobecnoci pakietw w rdle - zainstalowano tylko dostpne pakiety"
	fi
	rm $poldek_log
}


export -f  dml_buttons dml_cancel_check dml_edit_check dml_help_check dml_recover_check dml_check_the_rest install_if_missing line_replace line_remove backup_file show_message show_verbose_message install_packets leave_section drop_section dir_string_replace yes_no
