source: trunk/debathena/debathena/firefox-wrapper/firefox.sh @ 22967

Revision 22967, 8.3 KB checked in by rbasch, 16 years ago (diff)
* athena/bin/firefox-wrapper/firefox.sh: Handle a profile directory name containing whitespace, when parsing the contents of the lock symlink.
Line 
1#!/bin/sh
2#
3# $Id: firefox.sh,v 1.8 2007-06-22 15:13:03 rbasch Exp $
4# Firefox wrapper script for Athena.
5
6moz_progname=firefox
7
8# Profile directory's parent.
9prof_parent=$HOME/.mozilla/firefox
10
11# The following lockers need to be attached to run plugins and helper
12# applications.
13lockers="infoagents acro"
14
15if [ $(lsb_release --short --id) = "Debian" ]; then
16  firefox_libdir=/usr/lib/iceweasel
17else
18  firefox_libdir=/usr/lib/firefox
19fi
20
21# mozilla-xremote-client sends a command to a running Mozilla
22# application using X properties.  Its possible return codes are:
23#   0  success
24#   1  failed to connect to the X server
25#   2  no running window found
26#   3  failed to send command
27#   4  usage error
28moz_remote=$firefox_libdir/mozilla-xremote-client
29
30# testlock is used to test whether the profile directory's lock file
31# is actually locked.
32testlock=/usr/bin/testlock
33
34# Set the plugin path.  We allow the user to skip loading our
35# standard plugins via the MOZ_PLUGIN_PATH_OVERRIDE variable.
36if [ "${MOZ_PLUGIN_PATH_OVERRIDE+set}" = set ]; then
37  MOZ_PLUGIN_PATH="$MOZ_PLUGIN_PATH_OVERRIDE"
38else
39  # Append our plugin path to the user's setting (if any).
40  MOZ_PLUGIN_PATH=${MOZ_PLUGIN_PATH:+"$MOZ_PLUGIN_PATH:"}$plugin_path
41fi
42export MOZ_PLUGIN_PATH
43
44# Get the profile directory path, by parsing the profiles.ini file.
45get_profdir () {
46  inifile="$prof_parent/profiles.ini"
47  if [ ! -s "$inifile" ]; then
48    return 1
49  fi
50  awk -F= -v parent="$prof_parent" '
51    BEGIN {
52      nprofiles = 0;
53      use_default = 1;
54    }
55 
56    $1 ~ /^\[.*\]$/ {
57      section = substr($1, 2, length($1) - 2);
58      if (section ~ /^Profile[0-9]*$/) {
59        id = section;
60        nprofiles++;
61      }
62    }
63    $1 == "StartWithLastProfile" {
64      if (section == "General")
65        use_default = int($2);
66    }
67    $1 == "Name"       { a[id, "name"] = $2; }
68    $1 == "IsRelative" { a[id, "isrelative"] = $2; }
69    $1 == "Path"       { a[id, "path"] = $2; }
70    $1 == "Default"    { a[id, "default"] = $2; }
71 
72    END {
73      count = 0;
74      default = "";
75      for (i = 0; i < nprofiles; i++) {
76        id = "Profile" i;
77        if (a[id, "name"] != "" && a[id, "isrelative"] != "" &&
78            a[id, "path"] != "") {
79          count++;
80          if (int(a[id, "default"]) != 0)
81            default = id;
82        }
83      }
84      if (use_default != 0 && default != "")
85        id = default;
86      else if (nprofiles == 1 && count == 1)
87        id = "Profile0";
88      else
89        id = "";
90      if (id != "") {
91        if (int(a[id, "isrelative"]) == 0)
92          print a[id, "path"];
93        else
94          print parent "/" a[id, "path"];
95      }
96    }' $inifile
97}
98
99# Prompt the user on how to deal with an existing locked profile when
100# no running Firefox window can be found, and take action accordingly.
101# Parameter 1 is the profile directory path.
102# If the function returns, the lock file(s) will have been removed per
103# the user's choice, and the caller should continue.  Otherwise, the
104# process will exit.
105dispose_lock () {
106  lockfile="$1/.parentlock"
107  locklink="$1/lock"
108  # Extract the IP address and PID from the contents of the symlink.
109  # Also note whether firefox used fnctl() to lock .parentlock,
110  # which is indicated with a leading '+' in the PID.
111  eval `ls -l "$locklink" | awk '{
112    if (split($NF, a, ":") == 2)
113      printf("lock_ip=%s ; lock_pid=%d ; use_fcntl=%d\n",
114              a[1], int(a[2]), (substr(a[2], 1, 1) == "+")); }'`
115
116  # If we cannot recognize the link contents, just continue.
117  if [ -z "$lock_ip" ]; then
118    return 0
119  fi
120
121  local=false
122  if [ "$use_fcntl" -ne 0 ]; then
123    # An fcntl()-style lock was acquired; check it.
124    if [ -f "$lockfile" ]; then
125      # testlock tests whether there is a write lock on the file.
126      # If so, it outputs the locker's PID, and exits with status 2.
127      # If the lock is held by a process running on another host, the
128      # PID will be 0.
129      pid=`$testlock "$lockfile" 2>/dev/null`
130      if [ $? -ne 2 ]; then
131        # File is not locked, remove the symlink and continue.
132        rm -f "$locklink"
133        return 0
134      fi
135      # The file is locked.  If the lock is held by a process on
136      # this machine, the locker pid will be non-0.
137      if [ "$pid" -ne 0 ]; then
138        local=true
139      fi
140    fi
141  else
142    # Handle an old-style (symlink) lock.
143    my_host=`hostname`
144    if [ "$lock_ip" = "`host $my_host | awk '{ print $NF; }'`" ]; then
145      # Lock is held on this machine.
146      local=true
147    fi
148  fi
149
150  if [ "$local" = true ]; then
151    # The lock is held by a process on this machine; check if it is
152    # still running.
153    if kill -0 $lock_pid 2>/dev/null ; then
154      # Lock is held by a running process.
155      lock_host="this machine"
156    else
157      # Process is no longer running.  Nuke the lock and continue.
158      rm -f "$lockfile" "$locklink"
159      return 0
160    fi
161  else
162    # The lock is held by a process on another machine.  Get its
163    # host name.
164    lock_host=`host $lock_ip | \
165      sed -n -e 's/^.*domain name pointer \(.*\)$/\1/p' | \
166      sed -e 's/\.*$//' | tr '[A-Z]' '[a-z]'`
167    if [ -z "$lock_host" ]; then
168      lock_host="$lock_ip"
169    fi
170  fi
171
172  dialog_text="
173  Your Firefox profile directory is locked by process $lock_pid 
174  on $lock_host. 
175"
176
177  dialog_text="$dialog_text
178  If you select \"OK\" to continue, the profile will be forcibly 
179  unlocked; if the process holding the lock is still running, 
180  you risk corrupting your profile.
181
182  If you are not certain whether your Firefox process is still
183  running on $lock_host, select \"Cancel\" to exit 
184  without starting Firefox. 
185"
186
187  zenity --title "Firefox profile locked" --warning --text "$dialog_text"
188
189  case $? in
190  0)
191    rm -f "$lockfile" "$locklink"
192    ;;
193  *)
194    exit 1
195    ;;
196  esac
197}
198
199# Give a warning if we're running on a dialup machine.
200if [ -x /etc/athena/dialuptype ]; then
201  cat << \EOF
202
203*** PLEASE DO NOT RUN FIREFOX ON THE DIALUPS! ***
204
205Firefox is a very large and resource-intensive program, and it is
206not appropriate to run it on a dialup machine.
207
208Please run Firefox on your local machine rather than on a dialup.
209
210Thank you.
211
212EOF
213fi
214
215# Attach needed lockers.
216for locker in $lockers ; do
217  /bin/attach -h -n -q $locker
218done
219
220# Configure fontconfig to use fonts for MathML.
221if [ -z "$FONTCONFIG_FILE" ]; then
222  FONTCONFIG_FILE=/mit/infoagents/share/fonts/fonts.conf
223  export FONTCONFIG_FILE
224fi
225
226# If this is the first time the user has run firefox, create
227# the top-level profile directory now, so that we can set
228# the ACL appropriately.
229if [ ! -d "$prof_parent" ]; then
230  mkdir -p "$prof_parent"
231  /usr/bin/fs setacl "$prof_parent" system:anyuser none system:authuser none
232fi
233
234# We want Firefox to download files for helper applications to
235# /var/tmp instead of /tmp, so that users have a better chance
236# of retrieving them later.
237if [ -z "$TMPDIR" ]; then
238  TMPDIR=/var/tmp
239  export TMPDIR
240fi
241
242# If the user specified any option, skip the check for a running
243# Firefox, and invoke the program now.
244case "$1" in
245-*)
246  exec /usr/bin/firefox.debathena-orig "$@"
247  ;;
248esac
249
250if [ "${MOZ_NO_REMOTE+set}" = "set" ]; then
251  found_running=false
252else
253  # See if there is a running instance of Firefox.
254  user="${LOGNAME:+-u $LOGNAME}"
255  $firefox_libdir/run-mozilla.sh $moz_remote $user -a "$moz_progname" \
256    "ping()" >/dev/null 2>&1
257  case $? in
258  0)
259    found_running=true
260    ;;
261  2)
262    # This is the expected status when there is no running firefox window.
263    # Clear the error condition.
264    remote_error=
265    found_running=false
266    ;;
267  *)
268    # An unexpected error occurred.
269    found_running=error
270    ;;
271  esac
272fi
273
274# If Firefox is not running, check for a (possibly stale) lock on
275# the profile directory.
276if [ $found_running != true ]; then
277  profdir=`get_profdir`
278  if [ -n "$profdir" ]; then
279    # firefox now uses fcntl()-style locking on .parentlock, but an
280    # apparent openafs bug leaves the lock set after the program exits.
281    # Fortunately, it still maintains the "lock" symlink (which may
282    # also have been left from running a pre-1.5.0 firefox on the
283    # profile), so use its presence to help detect a stale lock.
284    if [ -h "$profdir/lock" ]; then
285      # The symlink exists, so the profile is (potentially) locked.
286      dispose_lock "$profdir"
287    else
288      # The symlink is gone, so just nuke the lock file, to work around
289      # the aforementioned openafs bug.
290      rm -f "$profdir/.parentlock"
291    fi
292  fi
293fi
294
295exec /usr/bin/firefox.debathena-orig "$@"
Note: See TracBrowser for help on using the repository browser.