#!/bin/bash -x # # Copyright 1999-2004 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 # $Header: /home/cvsroot/gentoo-src/mozilla-launcher/mozilla-launcher,v 1.10 2004/05/26 16:26:04 agriffis Exp $ # Set MOZILLA_NEWTYPE to "window" in your environment if you prefer # new windows instead of new tabs newtype=${MOZILLA_NEWTYPE:-"window"} # Make sure necessary progs are in the PATH PATH=/usr/bin:/bin:/usr/X11R6/bin:$PATH main() { local args mozargs urls u i local candidates retval=0 # Determine if we're called as firefox or mozilla and set up # variables appropriately which_browser || exit 1 # Parse the command-line and set args, mozargs and urls parse_cmdline "$@" || exit 1 # Make sure we'll get at least an empty window/tab # when nothing else is specified on the cmdline. if [[ $# -eq 0 ]]; then urls=('') fi # Set the candidates array with find_running find_running # Handle some special args. We want to handle these ourselves so # that we can find the right window on the screen to target. set -- "${mozargs[@]}" while [[ $# -gt 0 ]]; do case $1 in -mail) try_running 'xfeDoCommand(openInbox)' ;; -compose) try_running 'xfeDoCommand(composeMessage)' ;; -remote) try_running "$2" && shift ;; esac [[ $? -eq 0 ]] && { shift; continue; } # Error path: try_running failed, so prepend remaining mozargs to # args and drop through to call the browser binary args=("$@" "${args[@]}") break done # If there's no running browser, or we've got args, start an # instance. if [[ ${#args[@]} -gt 0 ]] || ! try_running 'ping()'; then # Assume the first url should just be tacked on the end. try_start "${args[@]}" ${urls:+"${urls[0]}"} set -- "${urls[@]}"; shift; urls=("$@") # shift off the first url candidates=$DISPLAY args=() # Handle case of multiple URLs by waiting for browser to map to # the screen so that it can be found by $remote below if [[ ${#urls[@]} -gt 0 ]]; then if [[ -x /usr/bin/xtoolwait ]]; then xtoolwait sleep 10 # hope it hasn't mapped yet else sleep 1 for ((i = 0; i < 40; i = i + 1)); do try_running 'ping()' && break || sleep 0.25 done fi fi fi # Handle multiple URLs by looping over the xremote call for u in "${urls[@]}"; do if [[ $u == mailto:* ]]; then try_running "mailto(${u#mailto:})" || retval=$? else try_running "openURL($u,new-$newtype)" || retval=$? fi done # Will only wait here if browser was started by this script if ! wait; then retval=$? echo "${mozbin##*/} exited with non-zero status ($?)" >&2 fi exit $retval } which_browser() { local zero=${0##*/} # Support mozilla, mozilla-bin, firefox, firefox-bin, thunderbird, # thunderbird-bin! # This case statement does the setup for source-based browsers and # just drops through for binary-based browsers. case $zero in *fox) export MOZILLA_FIVE_HOME="/usr/lib/MozillaFirefox" remote=$MOZILLA_FIVE_HOME/mozilla-xremote-client mozbin=$MOZILLA_FIVE_HOME/firefox-bin grepfor=Firefox-bin prefs=$HOME/.phoenix ;; *mozilla) export MOZILLA_FIVE_HOME="/usr/lib/mozilla" remote=$MOZILLA_FIVE_HOME/mozilla-xremote-client mozbin=$MOZILLA_FIVE_HOME/mozilla-bin grepfor=Mozilla-bin prefs=$HOME/.mozilla ;; *thunderbird) export MOZILLA_FIVE_HOME="/usr/lib/MozillaThunderbird" remote=$MOZILLA_FIVE_HOME/mozilla-xremote-client mozbin=$MOZILLA_FIVE_HOME/thunderbird-bin grepfor=Thunderbird-bin prefs=$HOME/.thunderbird ;; *-bin) unset mozbin # just in case... ;; # but don't do anything yet *) echo "$0: unknown browser" >&2 return 1 ;; esac # Attempt to use -bin version if source version isn't available if [[ -n $mozbin && ! -f $mozbin ]]; then unset mozbin # it's bogus anyway zero=${zero}-bin fi case $zero in *fox-bin) export MOZILLA_FIVE_HOME="/opt/firefox" remote=$MOZILLA_FIVE_HOME/mozilla-xremote-client mozbin=$MOZILLA_FIVE_HOME/firefox-bin grepfor=Firefox-bin prefs=$HOME/.phoenix ;; *mozilla-bin) export MOZILLA_FIVE_HOME="/opt/mozilla" remote=$MOZILLA_FIVE_HOME/mozilla-xremote-client mozbin=$MOZILLA_FIVE_HOME/mozilla-bin grepfor=Mozilla-bin prefs=$HOME/.mozilla ;; *thunderbird-bin) export MOZILLA_FIVE_HOME="/opt/thunderbird" remote=$MOZILLA_FIVE_HOME/mozilla-xremote-client mozbin=$MOZILLA_FIVE_HOME/thunderbird-bin grepfor=Thunderbird-bin prefs=$HOME/.thunderbird ;; esac # Make sure we got something if [[ -z $mozbin || ! -f $mozbin ]]; then echo "$0: can't find the browser :-(" >&2 return 1 fi # Read the preferences directory from appreg # so that we can delete XUL.mfasl since it causes so many problems. # (This code works but is commented out since I'm not sure that we # actually need it) #if [[ -n $prefs && -r $prefs/appreg ]]; then # prefs=$(strings $prefs/appreg 2>/dev/null | sed -n '/^directory$/{n;p;q}') #fi # Set LD_LIBRARY_PATH (also set in /etc/env.d/10*) export LD_LIBRARY_PATH=$MOZILLA_FIVE_HOME:$MOZILLA_FIVE_HOME/plugins${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} return 0 } # parse_cmdline: set args, mozargs and urls, which are dynamically # scoped in main() parse_cmdline() { # Validate the args and extract the urls args=() # general arguments mozargs=() # arguments that we handle specifically urls=() # urls to open while [[ $# -ne 0 ]] ; do if [[ $1 == -* ]] ; then case "${1#-}" in height|width|CreateProfile|P|UILocale|contentLocale|edit|chrome) args=("${args[@]}" "$1" "$2") shift 2 ;; mail|compose) mozargs=("${mozargs[@]}" "$1") shift 1 ;; remote) mozargs=("${mozargs[@]}" "$1" "$2") shift 2 ;; *) args=("${args[@]}" "$1") shift 1 ;; esac else if [[ $1 == *://*/* ]]; then urls=("${urls[@]}" "$1") elif [[ $1 == *://* ]]; then # as of mozilla_1.7_rc1 the url checking changed for xremote # calls... now three slashes are required for urls, otherwise we # get the following error from xremote: # Error: Failed to send command: 509 internal error urls=("${urls[@]}" "$1/") elif [[ $1 != *://* && $1 != /* && -e $1 ]]; then # relative path to a file, transform to absolute path urls=("${urls[@]}" "file://$PWD/$1") elif [[ $1 != *:* && $1 == *@* ]]; then # looks like an email address, prefix with mailto: so we can # recognize it later. urls=("${urls[@]}" "mailto:$1") else # no idea what this is! just add it to urls and hope it works urls=("${urls[@]}" "$1") fi shift fi done return 0 } # set_logname: make sure LOGNAME is set set_logname() { : ${LOGNAME:=$USER} : ${LOGNAME:=$(whoami)} export LOGNAME } # fake_user: fake user string on browser windows that should be found # by $remote. This is a hack, but on the other hand, anything other # than patching the xremote source would be a hack. This prevents # xremote from mixing up mozilla and firefox windows. fake_user() { local id set_logname # Find browser windows with a _MOZILLA_USER property and fake it for id in $(xwininfo -root -tree | awk -v gf="$grepfor" '$0~gf{print $1}'); do local props=$(xprop -notype -id $id) grep -Fqx "_MOZILLA_USER = \"$LOGNAME\"" <<<"$props" \ && xprop -id $id -f _MOZILLA_USER 8s -set _MOZILLA_USER "${0##*/}-$LOGNAME" done } # unfake_user: remove the hackery done by fake_user unfake_user() { local id set_logname # Find browser windows with a fake _MOZILLA_USER and fix it for id in $(xwininfo -root -tree | awk -v gf="$grepfor" '$0~gf{print $1}'); do xprop -notype -id $id | grep -Fqx "_MOZILLA_USER = \"${0##*/}-$LOGNAME\"" \ && xprop -id $id -f _MOZILLA_USER 8s -set _MOZILLA_USER "$LOGNAME" done } # find_running: sets the candidates array find_running() { local screens s # Try to start in an existing session; check all screens # with priority on the current screen screens=("$DISPLAY" $(xdpyinfo | awk ' /^name of display:/ { disp = substr($NF, 0, match($NF, /\.[^.]*$/)-1) } /^number of screens:/ { for (i = 0; i < $NF; i++) { this = sprintf("%s.%d", disp, i) if (this != ENVIRON["DISPLAY"]) print this } }') ) # Attempt to fix bug 39797 by making sure MozillaFirefox is running # on the DISPLAY prior to calling mozilla-xremote-client. The # problem here is that mozilla-xremote-client will return a zero # exit status if it contacts a Thunderbird-0.3 instance, even though # Thunderbird can't handle the openURL request. :-( # # Note 1: This seems to be fixed with Thunderbird-0.4, which rejects # the openURL request appropriately. # # Note 2: This takes prohibitively long for remote displays, so # assume that we're running everywhere. if [[ $DISPLAY == :* ]]; then candidates=() for s in "${screens[@]}"; do if DISPLAY=$s xwininfo -root -tree | grep -q "$grepfor"; then candidates=("${candidates[@]}" "$s") fi done else candidates=("${screens[@]}") fi } # try_running: try to use an existing browser to run a command try_running() { local s retval # Try mozilla-xremote-client on each candidate screen. # Only use mozilla-xremote-client if we have no other args (which # must be passed to the browser binary). if [[ ${#candidates[@]} > 0 ]]; then for s in "${candidates[@]}"; do # Check for newer xremote which supports -a programname # which thankfully obviates fake_user if $remote 2>&1 | grep -Fq '[-a '; then DISPLAY=$s $remote -a ${0##*/} "$@" retval=$? elif [[ $s == :* && -z $MOZ_NO_FAKE_USER ]]; then DISPLAY=$s fake_user LOGNAME="${0##*/}-$LOGNAME" DISPLAY=$s $remote "$@" retval=$? DISPLAY=$s unfake_user else # fake_user stuff takes prohibitively long on a remote # display, so I guess this has the potential to exhibit the # mozilla/firefox mixups for the 1% of users that are running # both simultaneously from a remote machine. DISPLAY=$s $remote "$@" retval=$? fi if [[ $retval -eq 0 ]]; then candidates=("$s") # for future calls break fi done else # simulate mozilla-xremote-client's response when it can't find an instance retval=2 fi # Might as well do this error interpretation here case $retval in 0) ;; 1) echo "Unable to connect to X server" >&2 ;; 2) echo "No running windows found" >&2 ;; 3) echo "Browser doesn't understand command" >&2 ;; *) echo "Unknown error $retval from mozilla-xremote-client" >&2 ;; esac return $retval } # try_start: attempt to start a browser try_start() { # Delete XUL cache since it causes so many problems # (depends on commented code in which_browser) #[[ -f $prefs/XUL.mfasl ]] && rm -f $prefs/XUL.mfasl $mozbin "$@" & } # Call the main sub, which is defined at the top of this script main "$@" # vim:expandtab sw=2: