diff options
Diffstat (limited to 'abs/core/LinHES-system')
21 files changed, 1472 insertions, 0 deletions
diff --git a/abs/core/LinHES-system/LinHES-profile.sh b/abs/core/LinHES-system/LinHES-profile.sh new file mode 100644 index 0000000..830b819 --- /dev/null +++ b/abs/core/LinHES-system/LinHES-profile.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export LinHES_ROOT=/usr/LH +export PATH=$PATH:/usr/LH/bin
\ No newline at end of file diff --git a/abs/core/LinHES-system/LinHES-run b/abs/core/LinHES-system/LinHES-run new file mode 100644 index 0000000..1b91def --- /dev/null +++ b/abs/core/LinHES-system/LinHES-run @@ -0,0 +1,100 @@ +#!/bin/sh +. /etc/profile +. /etc/systemconfig + +#keylaunch & +#/usr/bin/tilda & + +#move mouse to corner +xdotool mousemove -10 -10 +/usr/X11R6/bin/unclutter -root -idle 1 -jitter 200 -noevents & +if [ x"$Screensavertype" = "xgscreensaver" ] +then + gnome-screensaver & +elif [ x"$Screensavertype" = "xxscreensaver" ] +then + xscreensaver -no-splash & +fi + +/usr/bin/xvattr -a XV_COLORKEY -v 0 +mtd & +#/usr/bin/nvidia-settings -l +#/usr/bin/nvidia-settings -a InitialPixmapPlacement=2 + +if [ x$ShowTips = "x1" ] +then + echo "Alt+h for help" | osd_cat --font="-adobe-helvetica-bold-*-*-*-34-*-*-*-*-*-*-*" --shadow=3 --pos=middle --align=centre --offset=200 --color=yellow --delay=5 & +fi + +# Run any scripting that applies to special hardware. These brand-specific commands that run +# after Tweaker will, of course, override generic or hardware-specific settings. +SpecialHardwareCommands() { + special_hardware_file=/myth/.special_hardware_type + special_hardware=`cat $special_hardware_file` + + case $special_hardware in + dragon*) + sudo -E twk_audio.pl --implement digital + sudo -E twk_dragon.pl --implement all + ;; + ausdragon*) + ;; + *) + # there are no brand-specific commands for configuring whatever + # special hardware the user chose + ;; + esac +} + +if [ ! $SystemType = "Frontend_only" ] +then + if [ -f ~/.configure ] + then + # Run Tweaker, which applies generic and hardware-specific settings + if [ ! -f ~/.no_meth ] + then + sudo -E tweaker.pl + /bin/rm /tmp/fps # ??? clean up a temp file that will eventually be obsolete anyway + # Run any brand-specific commands, if necessary. + SpecialHardwareCommands + else + rm -f ~/.no_meth + fi + sudo sv stop mythbackend + xterm -fn *18* -e sudo taskset -c 0 /usr/bin/mythtv-setup + sudo sv start mythbackend + sudo chown -R mythtv.mythtv /home/mythtv + nice -n 19 mythfilldatabase --quiet & + rm ~/.configure + fi +fi + + +if [ x"$UseMythWelcome" = "x1" ] +then + STARTCMD="/usr/bin/mythwelcome" +else + STARTCMD="/usr/bin/mythfrontend -d -l /var/log/mythtv/mythfrontend.log" +fi + +echo "=====================================================================" +echo "Starting $STARTCMD" +firstboot.sh & + +if [ -f /tmp/nomfe ] +then + exit 0 +else + if [ -f /tmp/debug ] + then + echo "using gbd/debug" + gdb /usr/bin/mythfrontend -x $MV_ROOT/mfegdbcommands.txt + mv gdb.txt gdb.txt.mythfrontend + sleep 10 + else + killall -9 irexec + /usr/bin/irexec -d + $STARTCMD 2>&1 + fi +fi + diff --git a/abs/core/LinHES-system/LinHES-session b/abs/core/LinHES-system/LinHES-session new file mode 100755 index 0000000..52924d2 --- /dev/null +++ b/abs/core/LinHES-system/LinHES-session @@ -0,0 +1,13 @@ +#!/bin/sh +. /etc/profile +. /etc/systemconfig + +xhost +local: +xhost +127.0.0.1 +xset -dpms s off +export MALLOC_CHECK_=0 +#start fluxbox +fluxbox > /var/log/fluxbox.log 2>&1 + + + diff --git a/abs/core/LinHES-system/LinHES-start b/abs/core/LinHES-system/LinHES-start new file mode 100755 index 0000000..3157a2e --- /dev/null +++ b/abs/core/LinHES-system/LinHES-start @@ -0,0 +1,162 @@ +#!/bin/sh +# $Xorg: startx.cpp,v 1.3 2000/08/17 19:54:29 cpqbld Exp $ +# +# This is just a sample implementation of a slightly less primitive +# interface than xinit. It looks for user .xinitrc and .xserverrc +# files, then system xinitrc and xserverrc files, else lets xinit choose +# its default. The system xinitrc should probably do things like check +# for .Xresources files and merge them in, startup up a window manager, +# and pop a clock and serveral xterms. +# +# Site administrators are STRONGLY urged to write nicer versions. +# +# $XFree86: xc/programs/xinit/startx.cpp,v 3.16tsi Exp $ +. /etc/profile + +unset DBUS_SESSION_BUS_ADDRESS +unset SESSION_MANAGER + +userclientrc=/etc/X11/Sessions/LinHES +userserverrc=$HOME/.xserverrc +sysclientrc=/usr/X11R6/lib/X11/xinit/xinitrc +sysserverrc=/usr/X11R6/lib/X11/xinit/xserverrc +defaultclient=/usr/X11R6/bin/xterm +defaultserver=/usr/X11R6/bin/X +defaultclientargs="" +defaultserverargs="" +clientargs="" +serverargs="" + + + + + + +if [ -f $userclientrc ]; then + defaultclientargs=$userclientrc +elif [ -f $sysclientrc ]; then + defaultclientargs=$sysclientrc +fi + + + + +if [ -f $userserverrc ]; then + defaultserverargs=$userserverrc +elif [ -f $sysserverrc ]; then + defaultserverargs=$sysserverrc +fi + +whoseargs="client" +while [ x"$1" != x ]; do + case "$1" in + # '' required to prevent cpp from treating "/*" as a C comment. + /''*|\./''*) + if [ "$whoseargs" = "client" ]; then + if [ x"$clientargs" = x ]; then + client="$1" + else + clientargs="$clientargs $1" + fi + else + if [ x"$serverargs" = x ]; then + server="$1" + else + serverargs="$serverargs $1" + fi + fi + ;; + --) + whoseargs="server" + ;; + *) + if [ "$whoseargs" = "client" ]; then + clientargs="$clientargs $1" + else + # display must be the FIRST server argument + if [ x"$serverargs" = x ] && \ + expr "$1" : ':[0-9][0-9]*$' > /dev/null 2>&1; then + display="$1" + else + serverargs="$serverargs $1" + fi + fi + ;; + esac + shift +done + +# process client arguments +if [ x"$client" = x ]; then + # if no client arguments either, use rc file instead + if [ x"$clientargs" = x ]; then + client="$defaultclientargs" + else + client=$defaultclient + fi +fi + +# process server arguments +if [ x"$server" = x ]; then + # if no server arguments or display either, use rc file instead + if [ x"$serverargs" = x -a x"$display" = x ]; then + server="$defaultserverargs" + else + server=$defaultserver + fi +fi + +if [ x"$XAUTHORITY" = x ]; then + XAUTHORITY=$HOME/.Xauthority + export XAUTHORITY +fi + +removelist= + + +# set up default Xauth info for this machine +case `uname` in +Linux*) + if [ -z "`hostname --version 2>&1 | grep GNU`" ]; then + hostname=`hostname -f` + else + hostname=`hostname` + fi + ;; +*) + hostname=`hostname` + ;; +esac + +authdisplay=${display:-:0} +mcookie=`mcookie` +for displayname in $authdisplay $hostname$authdisplay; do + if ! xauth list "$displayname" | grep "$displayname " >/dev/null 2>&1; then + xauth -q << EOF +add $displayname . $mcookie +EOF + removelist="$displayname $removelist" + fi +done + + +xinit $client $clientargs -- $server $display -logverbose 6 $serverargs + +if [ x"$removelist" != x ]; then + xauth remove $removelist +fi + + + + + +if command -v deallocvt > /dev/null 2>&1; then + deallocvt +fi + + + + + + + diff --git a/abs/core/LinHES-system/LinHES.install b/abs/core/LinHES-system/LinHES.install new file mode 100644 index 0000000..2d2bdf2 --- /dev/null +++ b/abs/core/LinHES-system/LinHES.install @@ -0,0 +1,90 @@ +# This is a default template for a post-install scriptlet. You can +# remove any functions you don't need (and this header). + +# arg 1: the new package version +pre_install() { +/bin/true +} + +# arg 1: the new package version +post_install() { +MVDIR=/usr/LH/bin +# ln -s $MVDIR/backup_job /etc/cron.daily/backup_cron +# ln -s $MVDIR/update_system /etc/cron.daily/xupdate_system_cron +# ln -s $MVDIR/repo_sync.sh /etc/cron.daily/zrepo_sync.sh + ln -s $MVDIR/myth_mtc.sh /etc/cron.daily/myth_mtc.sh + +#LINE="mythtv ALL = NOPASSWD: /sbin/sv stop mythbackend" +LINE="mythtv ALL=(ALL) NOPASSWD: ALL" +LINE1="%wheel ALL=(ALL) NOPASSWD: ALL" + + +for i in "$LINE" "$LINE1" "$LINE2" "$LINE3" "$LINE4" "$LINE5" "$LINE7" "$LINE8" "$LINE9" "$LINE10" "$LINE11" "$LINE12" "$LINE13" "$LINE14" "$LINE15" "$LINE16" +do + cp /etc/sudoers /etc/sudoers.bak + grep -q "$i" /etc/sudoers + if [ $? != 0 ] + then + echo "$i" >> /etc/sudoers + visudo -cf /etc/sudoers + if [ ! $? = 0 ] + then + cp /etc/sudoers.bak /etc/sudoers + echo $i + echo "Error adding files" + exit 1 + fi + fi +done + +REALTIME="session required pam_limits.so" +grep -q "pam_limits.so" /etc/pam.d/su + if [ $? != 0 ] + then + echo "$REALTIME" >> /etc/pam.d/su + + fi + + + +} + +# arg 1: the new package version +# arg 2: the old package version +pre_upgrade() { + if [ -e /etc/cron.daily/backup_cron ] + then + rm -f /etc/cron.daily/backup_cron + fi + if [ -e /etc/cron.daily/xupdate_system_cron ] + then + rm -f /etc/cron.daily/xupdate_system_cron + fi + + if [ -e /etc/cron.daily/myth_mtc.py ] + then + rm -f /etc/cron.daily/myth_mtc.py + fi + + +} + +# arg 1: the new package version +# arg 2: the old package version +post_upgrade() { + post_install +} + +# arg 1: the old package version +pre_remove() { + /bin/true +} + +# arg 1: the old package version +post_remove() { + /bin/true +} + +op=$1 +shift +$op $* diff --git a/abs/core/LinHES-system/PKGBUILD b/abs/core/LinHES-system/PKGBUILD new file mode 100644 index 0000000..2a10fe0 --- /dev/null +++ b/abs/core/LinHES-system/PKGBUILD @@ -0,0 +1,42 @@ +pkgname=LinHES-system +pkgver=1.0 +pkgrel=69 +arch=('i686') +MVDIR=$startdir/pkg/usr/LH +BINDIR=$startdir/pkg/usr/bin +install=LinHES.install +pkgdesc="scripts and things related to having a automated system" +depends=(linhes-sounds xdotool) +backup=(etc/modprobe.d/alsa-base) +binfiles="LinHES-start optimize_mythdb.py myth_mtc.py myth_mtc.sh LinHES-run firstboot.sh load-modules-mythvantage.sh unclutter-toggle.sh myth_mtc.lr" + +source=(LinHES-session LinHES-profile.sh $binfiles alsa-base) + +build() { + cd $startdir/src + install -m755 -D LinHES-session $startdir/pkg/etc/X11/Sessions/LinHES + install -m755 -D LinHES-profile.sh $startdir/pkg/etc/profile.d/LinHES-profile.sh +####### install to /usr/LH/bin +#mkdir -p $BINDIR + +for i in $binfiles +do + item=$i + install -m755 -D $item $MVDIR/bin/$item + echo $item + +done + +cd $startdir/bin +for i in * +do + item=$i + install -m755 -D $item $MVDIR/bin/$item + echo $item + +done +install -m755 -D $startdir/src/alsa-base $startdir/pkg/etc/modprobe.d/alsa-base +mkdir $startdir/pkg/etc/logrotate.d +cp $startdir/myth_mtc.lr $startdir/pkg/etc/logrotate.d +} + diff --git a/abs/core/LinHES-system/alsa-base b/abs/core/LinHES-system/alsa-base new file mode 100644 index 0000000..bf99ac3 --- /dev/null +++ b/abs/core/LinHES-system/alsa-base @@ -0,0 +1,10 @@ +# Prevent abnormal drivers from grabbing index 0 +options bt87x index=-2 +options cx88_alsa index=-2 +options saa7134-alsa index=-2 +options snd-atiixp-modem index=-2 +options snd-intel8x0m index=-2 +options snd-via82xx-modem index=-2 +options snd-usb-audio index=-2 +options snd-usb-usx2y index=-2 +options snd-usb-caiaq index=-2 diff --git a/abs/core/LinHES-system/bin/backupcommon b/abs/core/LinHES-system/bin/backupcommon new file mode 100644 index 0000000..d112341 --- /dev/null +++ b/abs/core/LinHES-system/bin/backupcommon @@ -0,0 +1,382 @@ +#!/bin/bash + +. /usr/LH/bin/library.sh || { + echo 1>&2 "Can not load common library!" + exit 1 +} + +# You need to be root at least via sudo for the backup utilities to work. +must_be_root + +#---------------------------------------------------------------------------- +DATABASE="mythconverg" +DATABASE_DIR="/data/srv/mysql/$DATABASE" +BACKUP_LIST="./root ./home ./etc + ./var/lib/alsa/asound.state" +RESTORE_LIST="./root ./home ./etc/mythtv/modules ./etc/lirc + ./etc/X11/xorg.conf ./etc/asound.conf ./etc/default/aumix + ./var/lib/alsa/asound.state ./etc/mplayer/mplayer.conf + ./etc/localtime ./etc/timezone ./etc/asound.state" +# Both BLACK_LIST and IGNORE_LIST need to have only one file per line +# They also can't have any extra whitespace... +# Files and directories we should refuse to restore +BLACK_LIST='./etc/fstab +./etc/modules +./proc +./dev +./lib +./var/lib +./myth +./myth/backup +./home/mythtv/.my.cnf +./root/.my.cnf +./home/mythtv/.Xauthority +./root/.Xauthority' +# Files we ignore as differences +IGNORE_LIST='./home/mythtv/.upgrade +./home/mythtv/.configure +./home/mythtv/.newcard +./home/mythtv/.xscreensaver +./home/mythtv/appletrailer.xml +./root/ati-driver-installer-8-01-x86.x86_64.run +./root/ati-driver-installer-8-3-x86.x86_64.run +./root/mythstreamweb.tar +./home/mythtv/.Xauthority +./root/.Xauthority' +BACKUP_DIR="/myth/backup" +BACKUP_EXTRAS="$BACKUP_DIR/backup.list" +RESTORE_EXTRAS="$BACKUP_DIR/restore.list" +BACKUP_TAR="$BACKUP_DIR/savedfiles.tar" +BACKUP_SQL="$BACKUP_DIR/$DATABASE.sql" +#DROP_SQL="/usr/local/share/knoppmyth/drop.sql" +UTIL_DIR="/usr/LH/bin" +# Do we really still need to update from myth-0.11 to myth-0.12 ? +UPDATE_SQL="/usr/share/mythtv/sql/0.11-to-0.12.sql" +UPDATE_FILES="$UTIL_DIR/restore_fixups.sh" +COMPRESSION=".gz" +SOUNDS="/usr/share/sounds" +SILENCE="$SOUNDS/half_second_of_silence.wav" +PLAYER="/usr/bin/aplay" +#---------------------------------------------------------------------------- +AWK=/bin/awk +BASH=/bin/bash +BUNZIP2=/bin/bunzip2 +BZIP2=/bin/bzip2 +CAT=/bin/cat +CHMOD=/bin/chmod +CHOWN=/bin/chown +EGREP=/bin/egrep +GREP=/bin/grep +GUNZIP=/bin/gunzip +GZIP=/bin/gzip +LS=/bin/ls +MV=/bin/mv +RM=/bin/rm +SED=/bin/sed +TAR=/bin/tar +TR=/bin/tr +DIFF=/usr/bin/diff +FIND=/usr/bin/find +MD5SUM=/usr/bin/md5sum +MYISAMCHK=/usr/bin/myisamchk +MYSQL=/usr/bin/mysql +MYSQLADMIN=/usr/bin/mysqladmin +MYSQLDUMP=/usr/bin/mysqldump +MYTHSHUTDOWN=/usr/bin/mythshutdown +SORT=/usr/bin/sort +WC=/usr/bin/wc +SV=/sbin/sv + +#---------------------------------------------------------------------------- + +require file+r+x $AWK $BASH $BUNZIP2 $BZIP2 $CAT $CHMOD $CHOWN $EGREP $GREP \ + $GUNZIP $GZIP $LS $MV $RM $SED $TAR $TR $DIFF $FIND $MD5SUM \ + $MYISAMCHK $MYSQL $MYSQLADMIN $MYSQLDUMP $MYTHSHUTDOWN \ + $SORT $WC $SV + +#require file+r "$DROP_SQL" + +require dir+r+w+x /tmp "$BACKUP_DIR" "$DATABASE_DIR" + +play_sound () { + ($PLAYER $SILENCE $SOUNDS/$1 >& /dev/null)& +} + +# Filter against an exclude list like the black list or the ignore list above +filter_list () { + $GREP -vxF "$*" | + $SORT -u +} + +# Some people just can't read or follow directions... :-/ +# This should track the directory names in the default backup list above +# We also use this to short circuit a certain incredibly dumb stunt +filter_redundant () { + filter_list "$($TR -s ' ' '\n' <<<"$BACKUP_LIST ./myth")" | + $EGREP -v '^\./(root|home|etc|myth)/' | + $SORT -u +} + +get_extras () { + # One entry per line, and normalize the prefix + $TR ' ' '\n' <"$1" | + $AWK '/^$/ {next} + /^\.\// {print $0 ; next} + /^\// {print "." $0 ; next} + { print "./" $0}' +} + +[ -f "$BACKUP_EXTRAS" ] && + BACKUP_LIST="$BACKUP_LIST $(get_extras $BACKUP_EXTRAS | + filter_redundant)" + +[ -f "$RESTORE_EXTRAS" ] && + RESTORE_LIST="$RESTORE_LIST $(get_extras $RESTORE_EXTRAS | + filter_list "$BLACK_LIST")" + +# Build tar exclusion parameters out of $BLACK_LIST +EXCLUSION="" +case $0 in +*restore) + for file in $BLACK_LIST ; do + EXCLUSION="$EXCLUSION --exclude $file " + done + ;; +*) + ;; +esac + +shrink () { + case "$COMPRESSION" in + .gz) + $GZIP -9 "$@" + ;; + .bz2) + $BZIP2 -9 "$@" + ;; + *) + ;; + esac +} + +expand () { + case "$*" in + *.gz) + $GUNZIP "$@" + ;; + *.bz2) + $BUNZIP2 "$@" + ;; + -c\ *) + $CAT $2 /dev/null + ;; + -t\ *) + return 0 + ;; + *) + echo 1>&2 "Error, unknown file type!" + return 1 + ;; + esac +} + +single_format () { + candidates=$($LS -1 "$1.gz" "$1.bz2" "$1" 2>/dev/null) + case $($WC -l <<<"$candidates") in + 1) return 0 # One is good! + ;; + 0) echo "Error, no $1 found!" + return 1 + ;; + *) echo "Warning, multiple formats for $1 found!" + echo "Candidates are: $candidates" + ;; + esac +} + +compression_type () { + for compression in .gz .bz2 "" ; do + if [ -f "$1$compression" ] ; then + echo "$compression" + return 0 + fi + done + return 1 +} + +backup_roller () { # Gets the rollover sequence to use. + prev_i=$1 ; shift + for i in "$@" ; do + for c in .gz .bz2 "" ; do + for f in $BACKUP_SQL $BACKUP_TAR ; do + $RM -f $f$c$prev_i + if [ -f "$f$c$i" ] ; then + echo "Moving $f$c$i to $f$c$prev_i" + $MV -f $f$c$i $f$c$prev_i + fi + done + done + prev_i="$i" + done +} + +# Given "subset A B" return true if is A a subset of B +subset () { + cnt=$($DIFF $1 $2 | $GREP '^<' | $WC -l) + [ "$cnt" -eq 0 ] && return 0 + $DIFF $1 $2 +} + +mysql_cmd () { + $MYSQL -u root $DATABASE -sBe "$*" +} + +mysql_stdin () { + $MYSQL -u root $DATABASE -sB +} + +check_files () { + OBJECT_LIST="$*" + LIVE_FILES=/tmp/live_files_$$ + SAVED_FILES=/tmp/saved_files_$$ + + echo "Checking for the existance of the backup tar file..." + single_format "$BACKUP_TAR" + c=$(compression_type "$BACKUP_TAR") || + { echo "Error, missing tar file - '$BACKUP_TAR$c'." ; return 1 ; } + echo "Using file $BACKUP_TAR$c" + echo "Backup tar file exists. Checking the compression..." + expand -t $BACKUP_TAR$c || + { echo "Error, bad compressed tarball - '$BACKUP_TAR$c'." ; return 1 ; } + echo "Compression looks OK. Checking backup tar file contents..." + + echo "Generating a list of the backup contents..." + { + expand -c $BACKUP_TAR$c | + $TAR tf - $OBJECT_LIST $EXCLUSION | + $SED '/\/$/s///' | + filter_list "$IGNORE_LIST" >$SAVED_FILES + } 2>&1 | $SED -e '/Error exit delayed from previous errors/d' + + echo "Generating a list of the directory contents..." + cd / + $FIND $OBJECT_LIST \( -type d -or -type f -or -type l \) -print | + filter_list "$IGNORE_LIST" >$LIVE_FILES + + echo "Comparing directory versus backup contents..." + case $0 in + *backup) # backup must contain everything selected from the directories + subset $LIVE_FILES $SAVED_FILES + ;; + *restore) # directories must contain everything selected from the backup + subset $SAVED_FILES $LIVE_FILES + ;; + *) + $DIFF $LIVE_FILES $SAVED_FILES + ;; + esac + FILE_STATUS=$? + $RM $LIVE_FILES $SAVED_FILES + if [ $FILE_STATUS -eq 0 ] ; then + echo "Live and saved file lists match." + else + echo "Warning, file lists are not identical!" + fi + return $FILE_STATUS +} + +has_records () { + filename="$1" + description="$2" + if [ $($WC -l < "$filename") -eq 0 ] ; then + echo "Warning, could not get record counts from $description!" + return 1 + fi + if [ $($AWK '{cnt+=$2} END {print cnt}' < "$filename") -eq 0 ] ; then + echo "Warning, total record count from $description is zero!" + return 1 + fi + return 0 +} + +check_tables () { + LIVE_TABLES=/tmp/live_tables_$$ + SAVED_TABLES=/tmp/saved_tables_$$ + + echo "Checking for the existance of the DB dump file..." + single_format "$BACKUP_SQL" + c=$(compression_type "$BACKUP_SQL") || + { echo "Error, missing DB dump - '$BACKUP_SQL$c'" ; return 1 ; } + echo "Using file $BACKUP_SQL$c" + echo "DB dump file exists. Checking the compression..." + expand -t $BACKUP_SQL$c || + { echo "Error, bad compressed DB dump - '$BACKUP_SQL$c'." ; return 1 ; } + echo "Compression looks OK. Checking DB dump contents..." + + echo "Generating a list of tables and record counts in the DB dump..." + expand -c "$BACKUP_SQL$c" | + $AWK '/CREATE TABLE/ { tbl = $3; gsub("`","",tbl); records[tbl] = 0; } \ + /INSERT INTO/ { tbl = $3; gsub("`","",tbl); \ + n = split(substr($0,index($0,"VALUES (")+7),vals,"\\),\\("); \ + records[tbl] += n; } \ + END { for (tbl in records) print tbl, records[tbl]; }' | + $SED 's/mythlog [0-9]*/mythlog 0/' | + $SORT >$SAVED_TABLES + has_records "$SAVED_TABLES" "DB dump" || return 1 + + echo "Generating a list of tables and record counts in the live DB..." + for tbl in $(mysql_cmd "show tables") ; do + mysql_cmd "select '$tbl', count(*) from $tbl" + done | + $TR -s '\t' ' ' | + $SED 's/mythlog [0-9]*/mythlog 0/' | + $SORT >$LIVE_TABLES + has_records "$LIVE_TABLES" "live DB" || return 1 + + echo "Comparing live versus saved tables..." + case $0 in + *restore) # database must include everything from the backup + subset $SAVED_TABLES $LIVE_TABLES + ;; + *) # backup must exactly match the database + $DIFF $LIVE_TABLES $SAVED_TABLES + ;; + esac + TABLE_STATUS=$? + $RM $LIVE_TABLES $SAVED_TABLES + if [ $TABLE_STATUS -eq 0 ] ; then + echo "Live and saved table lists match." + else + echo "Warning, table lists are not identical!" + fi + return $TABLE_STATUS +} + +check_files_and_tables () { + STATUS=0 + echo + check_files "$@" || STATUS=1 + echo + check_tables || STATUS=1 + echo + return $STATUS +} + +stop_mysqld () { $SV stop mysql ; } +start_mysqld () { + $SV start mysql + for t in 1 2 4 8 ; do + ready=$(mysql_cmd 'select 1 from dual' 2>/dev/null) + [ "$ready" = "1" ] && break + sleep "$t" + done + [ "$ready" != "1" ] && echo "Error, DB not available after 15 seconds!" +} + +stop_mythbackend () { $SV stop mythbackend ; } +start_mythbackend () { $SV start mythbackend ; } + +lock_myth () { $MYTHSHUTDOWN --lock ; } +unlock_myth () { $MYTHSHUTDOWN --unlock ; } + +true # Make sure that this shows success diff --git a/abs/core/LinHES-system/bin/checkbackup b/abs/core/LinHES-system/bin/checkbackup new file mode 100755 index 0000000..b6d8587 --- /dev/null +++ b/abs/core/LinHES-system/bin/checkbackup @@ -0,0 +1,16 @@ +#!/bin/bash + +#---------------------------------------------------------------------------- +. /usr/LH/bin/backupcommon || { + echo 1>&2 "Can not load common settings!" + exit 1 +} +#---------------------------------------------------------------------------- + +if check_files_and_tables $BACKUP_LIST ; then + echo "Backup passes all checks." + exit 0 +else + echo "The backup is bad or already out of date!" + exit 1 +fi diff --git a/abs/core/LinHES-system/bin/checkrestore b/abs/core/LinHES-system/bin/checkrestore new file mode 100755 index 0000000..ef0360c --- /dev/null +++ b/abs/core/LinHES-system/bin/checkrestore @@ -0,0 +1,16 @@ +#!/bin/bash + +#---------------------------------------------------------------------------- +. /usr/LH/bin/backupcommon || { + echo 1>&2 "Can not load common settings!" + exit 1 +} +#---------------------------------------------------------------------------- + +if check_files_and_tables $RESTORE_LIST ; then + echo "Restore passes all checks." + exit 0 +else + echo "The restore failed or was already modified!" + exit 1 +fi diff --git a/abs/core/LinHES-system/bin/library.sh b/abs/core/LinHES-system/bin/library.sh new file mode 100755 index 0000000..2049de3 --- /dev/null +++ b/abs/core/LinHES-system/bin/library.sh @@ -0,0 +1,164 @@ +msg () { # A status reporting function + [ "${VERBOSE:-0}" -gt 0 ] && echo "$*" +} + +error () { # An error reporting function + echo 1>&2 "$*" +} + +fatal () { # Report an error and exit with a failure code + error "$*" + exit 1 +} + +# The only non builtin this uses is tr... +require () { # Check prerequisites + e=0 + props="$1" ; shift + for obj in "$@" ; do + [ -z "$obj" ] && continue # Too late to do anything itelligent... + problems="" + for prop in $(/bin/tr '+,' ' ' <<<"$props") ; do + case "$prop" in + e|exists) # kind of useless... + [ -e "$obj" ] || problems="$problems, does not exist" ;; + f|file) + [ -f "$obj" ] || problems="$problems, is not a file" ;; + d|dir) + [ -d "$obj" ] || problems="$problems, is not a directory" ;; + l|symlink) + [ -L "$obj" ] || problems="$problems, is not a symlink" ;; + nosymlink) + [ -L "$obj" ] && problems="$problems, is a symlink" ;; + r|readable) + [ -r "$obj" ] || problems="$problems, is not readable" ;; + w|writable) + [ -w "$obj" ] || problems="$problems, is not writable" ;; + x|executable) + [ -x "$obj" ] || problems="$problems, is not executable" ;; + *) + fatal "Programmer error, unknown property: '$prop'" ;; + esac + done + if [ -n "$problems" ] ; then + error "Error: '$obj'$problems." + e=1 + fi + done + [ "$e" -ne 0 ] && fatal "Errors noted above are fatal." +} + +require file+r+x /bin/bash /bin/grep /bin/rm /bin/tr \ + /usr/bin/basename /usr/bin/env \ + /usr/bin/mysql /usr/bin/sort + +if [ -n "$DEBUG" ] ; then + for debug_opt in $(/bin/tr ',' ' ' <<<"$DEBUG") ; do + echo '============================================================' + echo "==== $debug_opt" + + # Note that the order you specifiy these debug options in matters. + # I recommend always listing log first. For example: + # export DEBUG=log,env,set,trace + case "$debug_opt" in + env) /usr/bin/env | /usr/bin/sort ;; + set) set ;; + trace) set -vx ;; + log) logfile="/tmp/$(/usr/bin/basename $0).$$.debug" + /bin/rm -f "$logfile" # Try to avoid privilege escalation bugs + echo "Redirecting stdout and stderr to '$logfile'" + exec >"$logfile" 2>&1 ;; + *) error "Unknown debug option '$debug_opt'" ;; + esac + done + echo '============================================================' +fi + +must_be_root () { # For things which must be run as root + [ $(/usr/bin/id -u) -ne 0 ] && fatal "You must run this script as root!" +} + +must_be_mythtv () { # For things which must be run as mythtv (su if possible) + case $(/usr/bin/id -nu) in + mythtv) ;; # Continue + root) /bin/su - mythtv -c "$0 $*" ; exit $? ;; + *) fatal "You must run this script at mythtv or root!" ;; + esac +} + +# Use a variable so you can override it. +DATABASE="mythconverg" + +mysql_cmd () { # Execute SQL from the command line + /usr/bin/mysql -u root "$DATABASE" -sBe "$*" +} + +mysql_stdin () { # Execute SQL from stdin + /usr/bin/mysql -u root "$DATABASE" -sB +} + +machine_clause () { # Helper function + if [ -z "$1" ] ; then + echo "(hostname = '' or hostname is null)" + else + echo "hostname = '$1'" + fi +} + +get_all_setting_names () { # List setting names + case "$#" in + 0) MACHINE_CLAUSE="" ;; + 1) MACHINE_CLAUSE="where $(machine_clause "$1")" ;; + *) fatal "Programmer error, get_all_names must be passed 0 or 1 args, got $#" ;; + esac + mysql_cmd "select distinct value from settings $MACHINE_CLAUSE order by value" +} + +get_all_setting_values () { # List settings + case "$#" in + 0) MACHINE_CLAUSE="" ;; + 1) MACHINE_CLAUSE="where $(machine_clause "$1")" ;; + *) fatal "Programmer error, get_all_values must be passed 0 or 1 args, got $#" ;; + esac + mysql_cmd "select value, data, hostname from settings $MACHINE_CLAUSE order by hostname, value, data" +} + +get_setting_value () { # Get the data for a setting (may return multiples!) + case "$#" in + 1) MACHINE_CLAUSE="" ;; + 2) MACHINE_CLAUSE="and $(machine_clause "$2")" ;; + *) fatal "Programmer error, get_value must be passed 1 or 2 args, got $#" ;; + esac + mysql_cmd "select data from settings where value = '$1' $MACHINE_CLAUSE" +} + +set_setting_value () { # Insert or update aome setting + case "$#" in + 2) RECORD_CNT=$(get_value "$1" | wc -l) ;; + 3) RECORD_CNT=$(get_value "$1" "$3" | wc -l) ;; + *) fatal "Programmer error, set_value must be passed 2 or 3 args, got $#" ;; + esac + MACHINE_CLAUSE="" + if [ "$RECORD_CNT" -eq 0 ] ; then + [ -n "$3" ] && MACHINE_CLAUSE=", $(machine_clause "$3")" + mysql_cmd "insert into settings set value = '$1', data = '$2' $MACHINE_CLAUSE" + else + [ "$#" -eq 3 ] && MACHINE_CLAUSE="and $(machine_clause "$3")" + mysql_cmd "update settings set data = '$2' where value = '$1' $MACHINE_CLAUSE" + fi +} + +delete_setting_value () { # Totally remove some setting + case "$#" in + 1) MACHINE_CLAUSE="" ;; + 2) MACHINE_CLAUSE="and $(machine_clause "$2")" ;; + *) fatal "Programmer error, get_value must be passed 1 or 2 args, got $#" ;; + esac + mysql_cmd "delete from settings where value = '$1' $MACHINE_CLAUSE" +} + +# Filter against a newline seperated exclude list +filter_list () { + /bin/grep -vxF "$*" | + /usr/bin/sort -u +} diff --git a/abs/core/LinHES-system/bin/mythbackup b/abs/core/LinHES-system/bin/mythbackup new file mode 100755 index 0000000..d0d028d --- /dev/null +++ b/abs/core/LinHES-system/bin/mythbackup @@ -0,0 +1,71 @@ +#!/bin/bash + +#---------------------------------------------------------------------------- +. /usr/LH/bin/backupcommon || { + echo 1>&2 "Can not load common settings!" + exit 1 +} +#---------------------------------------------------------------------------- + +# Prevent mythshutdown from shutting down the system in the middle... +lock_myth + +# Play a sound to let you know I'm starting. +play_sound init.wav + +# Keep a chain of recent backups, +echo "Starting rollover of old backups, this may take a while..." +[ -f "$BACKUP_SQL" ] && shrink $BACKUP_SQL +[ -f "$BACKUP_TAR" ] && shrink $BACKUP_TAR +backup_roller .19 .18 .17 .16 .15 .14 .13 .12 .11 .10 .9 .8 .7 .6 .5 .4 .3 .2 .1 '' +echo "Rollover completed." + +# Start with the database backup, first we make sure it's healthy, and +# then we can dump it. +# Doing this while the backend is active would be BAD. +stop_mythbackend + +# Stop, check, and fix $DATABASE db to ensure clean copy, then restart it. +stop_mysqld +cd $DATABASE_DIR +$MYISAMCHK -f *.MYI +start_mysqld + +# Dumps the $DATABASE database +$MYSQLDUMP -v -c -u root $DATABASE > $BACKUP_SQL +shrink $BACKUP_SQL + +# Now to backup the other files, no fooling around, grab everything in the +# list because you never know what you'll want, and we can always get clever +# about what to restore later... + +# gather all the things in the list into a nice tidy bundle +cd / +$TAR cvf $BACKUP_TAR $BACKUP_LIST 2>&1 | + $SED -e '/Error exit delayed from previous errors/d' +shrink $BACKUP_TAR + +# If you can't read this you've got no business restoring from it anyway. +$CHOWN root:root $BACKUP_TAR* $BACKUP_SQL* +$CHMOD go-rwx $BACKUP_TAR* $BACKUP_SQL* + +echo "Sanity checking your backup..." +play_sound testing.wav +# Play a sound to let you know the outcome. +if check_files_and_tables $BACKUP_LIST ; then + echo "Backup passes all checks." + play_sound complete.wav + STATUS=0 +else + echo "The backup is bad or already out of date!" + play_sound fail.wav + STATUS=1 +fi + +# Now we can restart the backend. +start_mythbackend + +# Unlock the system again... +unlock_myth + +exit $STATUS diff --git a/abs/core/LinHES-system/bin/mythrestore b/abs/core/LinHES-system/bin/mythrestore new file mode 100755 index 0000000..7fce371 --- /dev/null +++ b/abs/core/LinHES-system/bin/mythrestore @@ -0,0 +1,92 @@ +#!/bin/bash + +#---------------------------------------------------------------------------- +. /usr/LH/bin/backupcommon || { + echo 1>&2 "Can not load common settings!" + exit 1 +} +#---------------------------------------------------------------------------- + +do_file_updates() { # A function because we need to do this in two places + echo "Doing any needed file updates..." + [ -n "$UPDATE_FILES" -a -f "$UPDATE_FILES" -a -x "$UPDATE_FILES" ] && + "$UPDATE_FILES" +} + +do_db_updates() { + # We need to redo this since we just restored the old settings... + lock_myth + # This is gross, but makes sure that the lock count has a sane value... + mysql_cmd "update settings set data = '1' where value = 'MythShutdownLock'" + + # Clean up ambiguous schema version settings... + for val in $(mysql_cmd "select distinct value from settings where value like '%SchemaVer'") ; do + # Find the numeric maximum version for this schema + max_ver=$(mysql_cmd "select max(0 + ifnull(data, 0)) from settings where value = '$val'") + # Wipe out all the existing ones + mysql_cmd "delete from settings where value = '$val'" + # Insert a nice clean unique one. + mysql_cmd "insert into settings set value = '$val', data = '$max_ver'" + done + + # This table causes problems with mythweb on upgrades... + mysql_cmd "update settings set data = '0' where value = 'WebDBSchemaVer'" + mysql_cmd "drop table mythweb_sessions" >/dev/null 2>&1 +} + +# Let's prevent mythshutdown from shutting down the system. +lock_myth + +# Play a sound to let you know I'm starting. +play_sound restore.wav + +# Doing this while the backend is active could be BAD. +stop_mythbackend + +# If the standard backup file exists we try to restore the files based +# on our restore list. +if compression=$(compression_type "$BACKUP_TAR") ; then + echo "Starting the restore of files..." + cd / + expand -c $BACKUP_TAR$compression | + $TAR xpvf - $RESTORE_LIST $EXCLUSION 2>&1 | + $SED -e '/Error exit delayed from previous errors/d' + echo "Completed the restore of files." +fi + +# If the db backup file exists start the DB restore and upgrade +if compression=$(compression_type "$BACKUP_SQL") ; then + echo "Starting the DB restore, this can take a while..." + echo "Clearing out the existing skeleton..." + #mysql_stdin < $DROP_SQL + echo "Recreating the db..." + $MYSQLADMIN -u root create $DATABASE + echo "Restoring the data (long)..." + expand -c $BACKUP_SQL$compression | mysql_stdin + echo "Doing any needed db updates..." + [ -n "$UPDATE_SQL" -a -f "$UPDATE_SQL" ] && + mysql_stdin < $UPDATE_SQL + echo "Completed the DB restore." +fi + +echo "Sanity checking your restore..." +play_sound vr.wav +# Play a sound to let you know the outcome. +if check_files_and_tables $RESTORE_LIST ; then + echo "Restore passes all checks." + play_sound restored.wav + STATUS=0 +else + echo "The restore failed or was already modified!" + play_sound rf.wav + STATUS=1 +fi + +# Make any updates _after_ we verify the backup... +do_db_updates +do_file_updates + +# Now it's more or less safe to restart the backend. +start_mythbackend + +exit $STATUS diff --git a/abs/core/LinHES-system/bin/rollback.sh b/abs/core/LinHES-system/bin/rollback.sh new file mode 100755 index 0000000..12897da --- /dev/null +++ b/abs/core/LinHES-system/bin/rollback.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +#---------------------------------------------------------------------------- +. /usr/LH/bin/backupcommon || { + echo 1>&2 "Can not load common settings!" + exit 1 +} +#---------------------------------------------------------------------------- + +require file+r+x $MYTHSHUTDOWN + +# Prevent mythshutdown from shutting down the system in the middle... +lock_myth + +echo "Starting rollback of old backups" +backup_roller '' .1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .12 .13 .14 .15 .16 .17 .18 .19 +echo "Rollback completed." + +# Unlock the system again... +unlock_myth diff --git a/abs/core/LinHES-system/firstboot.sh b/abs/core/LinHES-system/firstboot.sh new file mode 100755 index 0000000..47aa0f9 --- /dev/null +++ b/abs/core/LinHES-system/firstboot.sh @@ -0,0 +1,43 @@ +#!/bin/bash +. ~/.configured +ATTEMPT=0 +function try_smolt { + ((ATTEMPT=ATTEMPT+1)) + status=$(echo "jump mythsmolt" | telnet localhost 6546 2>&1) + echo $status|grep -q refused + status=$? + if [ $status != 0 ] + then + fb_status=0 + echo "FB=NO" > ~/.configured + fi + if [ $ATTEMPT = 200 ] + then + fb_status=0 + fi +} + +if [ ! -e /tmp/debug ] +then + if [ ! -e /tmp/nomfe ] + then + if [ ! -e ~/.mythtv/pub-uuid ] + then + if [ x$FB != xNO ] + then + fb_status=4 + while [ $fb_status != 0 ] + do + try_smolt + if [ $fb_status != 0 ] + then + sleep 1 + fi + done + fi + fi + fi +fi + + + diff --git a/abs/core/LinHES-system/load-modules-mythvantage.sh b/abs/core/LinHES-system/load-modules-mythvantage.sh new file mode 100755 index 0000000..06c8a96 --- /dev/null +++ b/abs/core/LinHES-system/load-modules-mythvantage.sh @@ -0,0 +1,64 @@ +#!/bin/bash +#/usr/bin/load-modules-mythvantage.sh UNLOAD LCD +export TERM=linux +. /etc/rc.conf +. /etc/rc.d/functions +. /etc/systemconfig +case $1 in +UNLOAD|unload ) + MODULELIST=`grep /etc/modules.mythvantage $2` + for i in $MODULELIST + do + /sbin/rmmod $i + done + + ;; + + *) printhl " Loading MythVantage-modules" + #try to load the cx88 modules + if [ ! x$SystemType = xFrontend_only ] + then + /sbin/modprobe cx88-dvb 2>/dev/null + fi + + if [ -f /etc/modules.mythvantage ] + then + while read line + do + module=`echo $line |cut -d# -f1` + #this doesn't do anything on boot cause ttySX does not yet exisit + if [ x$module = xlirc_serial ] + then + if [ x$ReceiverType = xSerial ] + then + case $ReceiverSerialport in + ttyS0) FLAGS="io=0x3f8 irq=4";; + ttyS1) FLAGS="io=0x2f8 irq=3" ;; + ttyS2) FLAGS="io=0x3e8 irq=4" ;; + ttyS3) FLAGS="io=0x2f8 irq=3" ;; + esac + /usr/bin/setserial /dev/$ReceiverSerialport uart none 2>/dev/null + if [ $? = 0 ] + then + /sbin/modprobe lirc_serial $FLAGS 2>/dev/nulla + fi + elif [ x$HostBlasterType = xSerial ] + then + case $HostSerialPort_blasterlirc in + ttyS0) FLAGS="io=0x3f8 irq=4";; + ttyS1) FLAGS="io=0x2f8 irq=3" ;; + ttyS2) FLAGS="io=0x3e8 irq=4" ;; + ttyS3) FLAGS="io=0x2f8 irq=3" ;; + esac + /usr/bin/setserial /dev/$HostSerialPort_blasterlirc uart none 2>/dev/null + if [ $? = 0 ] + then + /sbin/modprobe lirc_serial $FLAGS 2>/dev/nulla + fi + fi + fi + /sbin/modprobe $module 2> /dev/null + done < /etc/modules.mythvantage + fi +esac + diff --git a/abs/core/LinHES-system/myth_mtc.lr b/abs/core/LinHES-system/myth_mtc.lr new file mode 100644 index 0000000..23f8711 --- /dev/null +++ b/abs/core/LinHES-system/myth_mtc.lr @@ -0,0 +1,9 @@ +/var/log/mythtv/myth_mtc.log { + copytruncate + daily + size 10M + missingok + rotate 7 + compress + notifempty +} diff --git a/abs/core/LinHES-system/myth_mtc.py b/abs/core/LinHES-system/myth_mtc.py new file mode 100755 index 0000000..5505b0a --- /dev/null +++ b/abs/core/LinHES-system/myth_mtc.py @@ -0,0 +1,139 @@ +#!/usr/bin/python + + +import sys,popen2 +import optparse +import re +import socket +import os +import datetime,time + + + +try: + from MythTV import MythTV + mythtv = MythTV() +except: + mythtv = None + +#print mythtv.db.getSetting( 'Theme', socket.gethostname()) + +def optimize(): + cursor = mythtv.db.cursor() + cursor.execute("SHOW tables") + result = cursor.fetchall() + ops=["REPAIR","OPTIMIZE","ANALYZE"] + for row in result: + ctable=row[0] + for op in ops: + print op,ctable + cmd= "%s table %s" %(op,ctable) + cursor.execute(cmd) + + +def upcoming_check(): + upcoming = mythtv.getUpcomingRecordings() + try: + show=str(upcoming[0]) + show=show.strip() + showtime=show.partition("(")[2].strip(")") + now=time.time() + rec_time=time.strptime( showtime ,"%Y-%m-%d %H:%M:%S" ) + r=time.mktime(rec_time) + time_diff= ( r - now ) / 60 + except: + time_diff=100 + show="No show" + if ( time_diff > 30) : + return True + else: + print show , "is upcoming in " , time_diff + return False + + +def schemalock_check(): + c = mythtv.db.cursor() + c.execute("select count(*) from schemalock") + results=c.fetchone() + schemalock=results[0] + if schemalock == 0: + return True + else: + print "schema is locked" + return False + +def job_check(): + c = mythtv.db.cursor() + c.execute("select count(*) from jobqueue where status = 4") + results=c.fetchone() + jobs= results[0] + if jobs == 0 : + return True + else: + print " jobs are running" + return False + + +def in_use(): + c = mythtv.db.cursor() + c.execute("select count(*) from inuseprograms") + results=c.fetchone() + prginuse=results[0] + if prginuse == 0 : + return True + else: + print "programs in use" + return False + +def mfd_check(): + ismfd=popen2.Popen3('/bin/ps cax|/bin/grep -v grep |/bin/grep mythfilldatabase') + ismfd.wait() + mfdIdle=ismfd.poll() + if mfdIdle == 0: + print "mythfilldatabase is running" + return False + else: + return True + + + +def idle_check(): + if ( upcoming_check() and schemalock_check() and job_check() and in_use() and mfd_check() ): + idle=True + print "Myth is idle" + else: + idle=False + print "Myth is NOT idle" + return idle + +def run_stuff(): + if idle_check(): + print "Running optimize" + optimize() + + print "Running backup" + os.system('/usr/LH/bin/backup_job') + + print "Running system_update" + os.system('/usr/LH/bin/update_system') + continue_loop=False + else: + continue_loop=True + return continue_loop + +#--------------------------------- +starttime=time.time() +ctin=True +while ctin: + ctin=run_stuff() + if ctin: + time.sleep(600) + current_time=time.time() + if (current_time - starttime) > 10800 : + ctin = False + print "time exceeded (3 hours)" + exit(1) + + + + diff --git a/abs/core/LinHES-system/myth_mtc.sh b/abs/core/LinHES-system/myth_mtc.sh new file mode 100755 index 0000000..487513b --- /dev/null +++ b/abs/core/LinHES-system/myth_mtc.sh @@ -0,0 +1,12 @@ +#!/bin/bash +. /etc/profile +logFile='/var/log/mythtv/myth_mtc.log' +date=`date +%Y-%m-%d` + +myth_mtc.py > $logFile 2>&1 +if [ $? = 0 ] +then + echo "Finished $date" >> $logFile +else + echo "Time Exceede $date" >> $logFile +fi diff --git a/abs/core/LinHES-system/optimize_mythdb.py b/abs/core/LinHES-system/optimize_mythdb.py new file mode 100755 index 0000000..e7b35ed --- /dev/null +++ b/abs/core/LinHES-system/optimize_mythdb.py @@ -0,0 +1,16 @@ +#!/usr/bin/python +# import MySQL module +import MySQLdb +import socket +import sys +db = MySQLdb.connect(host="localhost", user="mythtv", passwd="mythtv", db="mythconverg") +cursor = db.cursor() +cursor.execute("SHOW tables") +result = cursor.fetchall() +ops=["REPAIR","OPTIMIZE","ANALYZE"] +for row in result: + ctable=row[0] + for op in ops: + print op,ctable + cmd= "%s table %s" %(op,ctable) + cursor.execute(cmd) diff --git a/abs/core/LinHES-system/unclutter-toggle.sh b/abs/core/LinHES-system/unclutter-toggle.sh new file mode 100644 index 0000000..0ead751 --- /dev/null +++ b/abs/core/LinHES-system/unclutter-toggle.sh @@ -0,0 +1,8 @@ +#!/bin/bash +PIDUNC=`pidof unclutter` +if [ -n "${PIDUNC}" ]; +then + killall -9 unclutter +else + /usr/X11R6/bin/unclutter -root -idle 1 -jitter 200 -noevents & +fi |