#!/bin/sh # # Show a progress bar. # # If kdialog/zenity are available they are used. # Progress data is read from the created pipe, echoing "quit" to the pipe will # cause the script to terminate, as will the progress reaching 100% # # Pressing cancel on a zenity dialog will terminate right away, kdialog will # only terminate when the next line of data is read from the pipe. # # Check the which command exists, and if so make sure it behaves how we want # it to... WHICH=`which which 2>/dev/null` if [ "" = "${WHICH}" ]; then echo "which command not found. Aborting."; exit 0; else # Solaris sucks BADWHICH=`which /` if [ "${BADWHICH}" != "" ]; then echo "Replacing bad which command."; # "Which" on solaris gives non-empty results for commands that don't exist which() { OUT=`${WHICH} ${1}` if [ $? -eq 0 ]; then echo ${OUT} else echo "" fi; } fi; fi # Solaris also has a crappy version of tail! tail -n +1 /dev/null >/dev/null 2>&1 if [ $? -eq 2 ]; then TAILOPTS="-" else TAILOPTS="-n" fi; PIDOF=`which pidof` if [ "${PIDOF}" = "" ]; then # For some reason some distros hide pidof... if [ -e /sbin/pidof ]; then PIDOF=/sbin/pidof elif [ -e /usr/sbin/pidof ]; then PIDOF=/usr/sbin/pidof fi; fi; ## Helper Functions if [ -n "${PIDOF}" ]; then ISKDE=`${PIDOF} -x -s kdeinit kdeinit4` ISGNOME=`${PIDOF} -x -s gnome-panel` else ISKDE=`pgrep kdeinit` ISGNOME=`pgrep gnome-panel` fi; KDIALOG=`which kdialog` ZENITY=`which zenity` USEKDIALOG="0"; QDBUS=`which qdbus` DBUSSEND=`which dbus-send` DCOP=`which dcop` BC=`which bc` KDETYPE="" if [ "${ISKDE}" != "" -o "${ZENITY}" = "" ]; then # Check to see if we have the dcop or dbus binaries needed.. USEDCOP=`kdialog --help | grep -i dcop` if [ "${USEDCOP}" != "" -a "${DCOP}" != "" ]; then KDETYPE="dcop" USEKDIALOG="1"; elif [ "${USEDCOP}" = "" -a "${QDBUS}" != "" ]; then KDETYPE="qdbus" USEKDIALOG="1"; elif [ "${USEDCOP}" = "" -a "${DBUSSEND}" != "" ]; then KDETYPE="dbussend" USEKDIALOG="1"; fi; fi; # Check for special watchdog mode. # In this mode we are used to kill ourself after a certain time limit to make sure we don't hang. if [ "${1}" = "--watchdog" ]; then if [ "" != "${2}" ]; then echo "Watchdog for: ${2}" sleep 5; kill -1 ${2} >/dev/null 2>&1 & sleep 5; kill -9 ${2} >/dev/null 2>&1 & exit 0; else echo "No PID specified to watch." exit 1; fi; exit 1; fi; if [ "${1}" = "--pulsate" ]; then shift; PULSATE="1" else PULSATE="0" fi; CAPTION=${1} FILESIZE=${2} WGETPID=${4} progresswindow="" TYPE="" PIPE="progresspipe_${$}" retval="1" CONTINUE="1" readprogress() { data="" input="" while [ ${CONTINUE} -eq "1" -a -e ${PIPE} ]; do if [ "${TYPE}" = "KDE" ]; then wasCancelled="false" if [ "${KDETYPE}" = "dcop" ]; then wasCancelled=`${DCOP} ${progresswindow} wasCancelled`; elif [ "${KDETYPE}" = "qdbus" ]; then wasCancelled=`${QDBUS} ${progresswindow} org.kde.kdialog.ProgressDialog.wasCancelled`; elif [ "${KDETYPE}" = "dbussend" ]; then wasCancelled=`${DBUSSEND} --print-reply --dest=${progresswindow} org.kde.kdialog.ProgressDialog.wasCancelled | grep boolean | awk '{print $2}'`; fi if [ "${wasCancelled}" = "true" ]; then touch .downloadWasCancelled break; fi; fi; input=`cat "${PIPE}" | tail ${TAILOPTS}1` if [ "${input}" = "quit" ]; then break; elif [ "${input}" != "" ]; then data=${input} input="" if [ "${PULSATE}" = "1" ]; then val=-1 if [ "${data}" != "-1" ]; then if [ "${TYPE}" = "KDE" ]; then if [ "${KDETYPE}" = "dcop" ]; then ${DCOP} ${progresswindow} setLabelText "${data}" elif [ "${KDETYPE}" = "qdbus" ]; then ${QDBUS} ${progresswindow} org.kde.kdialog.ProgressDialog.setLabelText "${data}" elif [ "${KDETYPE}" = "dbussend" ]; then ${DBUSSEND} --print-reply --dest=${progresswindow} org.kde.kdialog.ProgressDialog.setLabelText "string:\'${data}\'" > /dev/null fi; elif [ "${TYPE}" = "GNOME" ]; then echo "${data}" | sed 's/^/# /g' else echo "${data}" fi; fi; else if [ "${BC}" != "" ]; then res=`echo "scale=4 ; (${data}/${FILESIZE})*100" | bc`; else # Note, this will return 0 or 100, nothing else, better than spamming # errors and never closing tho. res=`echo $(( (${data}/${FILESIZE})*100 ))`; fi; val=${res%%.*} if [ "${val}" = "" ]; then val=0 fi; fi; if [ "${TYPE}" = "KDE" ]; then if [ "${KDETYPE}" = "dcop" ]; then ${DCOP} ${progresswindow} setProgress ${val} returnVal=${?} elif [ "${KDETYPE}" = "qdbus" ]; then ${QDBUS} ${progresswindow} org.freedesktop.DBus.Properties.Set org.kde.kdialog.ProgressDialog value ${val} returnVal=${?} elif [ "${KDETYPE}" = "dbussend" ]; then ${DBUSSEND} --print-reply --dest=${progresswindow} org.freedesktop.DBus.Properties.Set string:'org.kde.kdialog.ProgressDialog' string:'value' variant:int32:${val} > /dev/null returnVal=${?} fi; if [ ${returnVal} -ne 0 ]; then break; fi; elif [ "${TYPE}" = "GNOME" ]; then echo ${val} if [ $? -ne 0 ] ; then break; fi else if [ $((${val} % 2)) -eq 0 ]; then echo "-> "${val}"%" fi; fi; if [ "${val}" = "100" ]; then retval="0" CONTINUE="0" break; fi; fi; done; } if [ "" = "${CAPTION}" -o "" = "${FILESIZE}" ]; then echo "Insufficient Parameters." echo "Usage: ${0} [pipename]" exit; fi; if [ "" != "${3}" ]; then # Assume pipe name is what we want, delete existing file. PIPE=${3} rm -Rf ${PIPE} else # Make sure we get a file that doesn't already exist, keep appending our # pid untill we get a file that hasn't been taken. while [ -e "${PIPE}" ]; do PIPE="${PIPE}_${$}" done; fi; echo "Using pipe: "${PIPE} mkfifo "${PIPE}" EMPTYPIPE="1" WDPID="" WD2PID="" closeProgress() { CONTINUE="0" if [ "${TYPE}" = "KDE" -a ${retval} != "0" ]; then if [ "${KDETYPE}" = "dcop" ]; then ${DCOP} ${progresswindow} close elif [ "${KDETYPE}" = "qdbus" ]; then ${QDBUS} ${progresswindow} org.kde.kdialog.ProgressDialog.close elif [ "${KDETYPE}" = "dbussend" ]; then ${DBUSSEND} --print-reply --dest=${progresswindow} org.kde.kdialog.ProgressDialog.close > /dev/null fi; fi; echo "Exiting with value: $retval" if [ "${WGETPID}" != "" ]; then echo "Attempting to kill wget (${WGETPID})" kill -9 ${WGETPID} fi; if [ -e ${PIPE} ]; then if [ "${EMPTYPIPE}" = "1" ]; then sh ${0} --watchdog ${$} & WDPID=${!} EMPTYPIPE="2" echo "Emptying pipe (${PIPE}) this may hang if no data has been written to the pipe." cat ${PIPE}; elif [ "${EMPTYPIPE}" = "2" ]; then echo "Helping pipe (${PIPE}) this may hang if nothing is reading from the pipe." sh ${0} --watchdog ${$} & WD2PID=${!} EMPTYPIPE="3" echo "." > ${PIPE}; else echo "Ignoring Pipe..." fi; echo "Killing watchdog 1." kill -9 ${WDPID} echo "Killing watchdog 2." kill -9 ${WD2PID} echo "Deleting Pipe ${PIPE}" rm -Rf "${PIPE}" fi; exit $retval; } trap 'closeProgress' INT TERM EXIT rm .downloadWasCancelled # if kdialog exists, and we have a display, and we are not running gnome, # and either we are running kde or zenity doesn't exist.. if [ "" != "${KDIALOG}" -a "" != "${DISPLAY}" -a "" = "${ISGNOME}" -a "${USEKDIALOG}" = "1" ]; then echo "Progress dialog on Display: ${DISPLAY}" progresswindow=`${KDIALOG} --title "DMDirc: ${CAPTION}" --progressbar "${CAPTION}" 100` if [ "${PULSATE}" = "1" ]; then SHOWCANCEL="false" else SHOWCANCEL="true" fi; if [ "${KDETYPE}" = "dcop" ]; then ${DCOP} ${progresswindow} setAutoClose true ${DCOP} ${progresswindow} showCancelButton ${SHOWCANCEL} elif [ "${KDETYPE}" = "qdbus" ]; then ${QDBUS} ${progresswindow} org.freedesktop.DBus.Properties.Set org.kde.kdialog.ProgressDialog autoClose true ${QDBUS} ${progresswindow} org.kde.kdialog.ProgressDialog.showCancelButton ${SHOWCANCEL} elif [ "${KDETYPE}" = "dbussend" ]; then ${DBUSSEND} --print-reply --dest=${progresswindow} org.kde.kdialog.ProgressDialog.showCancelButton boolean:${SHOWCANCEL} >/dev/null ${DBUSSEND} --print-reply --dest=${progresswindow} org.freedesktop.DBus.Properties.Set string:'org.kde.kdialog.ProgressDialog' string:'autoClose' variant:boolean:true > /dev/null fi; TYPE="KDE" readprogress CONTINUE="0" echo "Progress Bar Complete" elif [ "" != "${ZENITY}" -a "" != "${DISPLAY}" ]; then # Else, if zenity exists and we have a display echo "Progress dialog on Display: ${DISPLAY}" TYPE="GNOME" if [ "${PULSATE}" = "1" ]; then readprogress | ${ZENITY} --progress --pulsate --auto-close --title "DMDirc: ${CAPTION}" --text "${CAPTION}" else readprogress | ${ZENITY} --progress --auto-close --auto-kill --title "DMDirc: ${CAPTION}" --text "${CAPTION}" fi; CONTINUE="0" echo "Progress Bar Complete" else # Else, basic command-line progress echo "Progress For: ${CAPTION}" echo "-> 0%" readprogress CONTINUE="0" echo "" echo "Finished!" fi echo "Exiting progressbar" exit 0;