Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / remoting / host / installer / mac / PrivilegedHelperTools / org.chromium.chromoting.me2me.sh
1 #!/bin/sh
2
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 NAME=org.chromium.chromoting
8 HOST_BUNDLE_NAME=@@HOST_BUNDLE_NAME@@
9 PREFPANE_BUNDLE_NAME=@@PREFPANE_BUNDLE_NAME@@
10 CONFIG_DIR=/Library/PrivilegedHelperTools
11 ENABLED_FILE=$CONFIG_DIR/$NAME.me2me_enabled
12 CONFIG_FILE=$CONFIG_DIR/$NAME.json
13 HOST_EXE=$CONFIG_DIR/$HOST_BUNDLE_NAME/Contents/MacOS/remoting_me2me_host
14 PLIST_FILE=$CONFIG_DIR/$HOST_BUNDLE_NAME/Contents/Info.plist
15 PREF_PANE_BUNDLE=/Library/PreferencePanes/$PREFPANE_BUNDLE_NAME
16
17 # The exit code returned by 'wait' when a process is terminated by SIGTERM.
18 SIGTERM_EXIT_CODE=143
19
20 # Range of exit codes returned by the host to indicate that a permanent error
21 # has occurred and that the host should not be restarted. Please, keep these
22 # constants in sync with remoting/host/host_exit_codes.h.
23 MIN_PERMANENT_ERROR_EXIT_CODE=100
24 MAX_PERMANENT_ERROR_EXIT_CODE=105
25
26 # Constants controlling the host process relaunch throttling.
27 MINIMUM_RELAUNCH_INTERVAL=60
28 MAXIMUM_HOST_FAILURES=10
29
30 # Exit code 126 is defined by Posix to mean "Command found, but not
31 # executable", and is returned if the process cannot be launched due to
32 # parental control.
33 PERMISSION_DENIED_PARENTAL_CONTROL=126
34
35 HOST_PID=0
36 SIGNAL_WAS_TRAPPED=0
37
38 # This script works as a proxy between launchd and the host. Signals of
39 # interest to the host must be forwarded.
40 SIGNAL_LIST="SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGABRT SIGEMT \
41       SIGFPE SIGKILL SIGBUS SIGSEGV SIGSYS SIGPIPE SIGALRM SIGTERM SIGURG \
42       SIGSTOP SIGTSTP SIGCONT SIGCHLD SIGTTIN SIGTTOU SIGIO SIGXCPU SIGXFSZ \
43       SIGVTALRM SIGPROF SIGWINCH SIGINFO SIGUSR1 SIGUSR2"
44
45 handle_signal() {
46   SIGNAL_WAS_TRAPPED=1
47 }
48
49 run_host() {
50   local host_failure_count=0
51   local host_start_time=0
52
53   while true; do
54     if [[ ! -f "$ENABLED_FILE" ]]; then
55       echo "Daemon is disabled."
56       exit 0
57     fi
58
59     # If this is not the first time the host has run, make sure we don't
60     # relaunch it too soon.
61     if [[ "$host_start_time" -gt 0 ]]; then
62       local host_lifetime=$(($(date +%s) - $host_start_time))
63       echo "Host ran for ${host_lifetime}s"
64       if [[ "$host_lifetime" -lt "$MINIMUM_RELAUNCH_INTERVAL" ]]; then
65         # If the host didn't run for very long, assume it crashed. Relaunch only
66         # after a suitable delay and increase the failure count.
67         host_failure_count=$(($host_failure_count + 1))
68         echo "Host failure count $host_failure_count/$MAXIMUM_HOST_FAILURES"
69         if [[ "$host_failure_count" -ge "$MAXIMUM_HOST_FAILURES" ]]; then
70           echo "Too many host failures. Giving up."
71           exit 1
72         fi
73         local relaunch_in=$(($MINIMUM_RELAUNCH_INTERVAL - $host_lifetime))
74         echo "Relaunching in ${relaunch_in}s"
75         sleep "$relaunch_in"
76       else
77         # If the host ran for long enough, reset the crash counter.
78         host_failure_count=0
79       fi
80     fi
81
82     # Execute the host asynchronously and forward signals to it.
83     trap "handle_signal" $SIGNAL_LIST
84     host_start_time=$(date +%s)
85     "$HOST_EXE" --host-config="$CONFIG_FILE" &
86     HOST_PID="$!"
87
88     # Wait for the host to return and process its exit code.
89     while true; do
90       wait "$HOST_PID"
91       EXIT_CODE="$?"
92       if [[ $SIGNAL_WAS_TRAPPED -eq 1 ]]; then
93         # 'wait' returned as the result of a trapped signal and the exit code is
94         # the signal that was trapped + 128. Forward the signal to the host.
95         SIGNAL_WAS_TRAPPED=0
96         local SIGNAL=$(($EXIT_CODE - 128))
97         echo "Forwarding signal $SIGNAL to host"
98         kill -$SIGNAL "$HOST_PID"
99       elif [[ "$EXIT_CODE" -eq "0" ||
100               "$EXIT_CODE" -eq "$SIGTERM_EXIT_CODE" ||
101               "$EXIT_CODE" -eq "$PERMISSION_DENIED_PARENTAL_CONTROL" ||
102               ("$EXIT_CODE" -ge "$MIN_PERMANENT_ERROR_EXIT_CODE" && \
103               "$EXIT_CODE" -le "$MAX_PERMANENT_ERROR_EXIT_CODE") ]]; then
104         echo "Host returned permanent exit code $EXIT_CODE at ""$(date)"""
105         if [[ "$EXIT_CODE" -eq 101 ]]; then
106           # Exit code 101 is "hostID deleted", which indicates that the host
107           # was taken off-line remotely. To prevent the host being restarted
108           # when the login context changes, try to delete the "enabled" file.
109           # Since this requires root privileges, this is only possible when
110           # this script is launched in the "login" context. In the "aqua"
111           # context, just exit and try again next time.
112           echo "Host id deleted - disabling"
113           rm -f "$ENABLED_FILE" 2>/dev/null
114         fi
115         exit "$EXIT_CODE"
116       else
117         # Ignore non-permanent error-code and launch host again. Stop handling
118         # signals temporarily in case the script has to sleep to throttle host
119         # relaunches. While throttling, there is no host process to which to
120         # forward the signal, so the default behaviour should be restored.
121         echo "Host returned non-permanent exit code $EXIT_CODE at ""$(date)"""
122         trap - $SIGNAL_LIST
123         HOST_PID=0
124         break
125       fi
126     done
127   done
128 }
129
130 if [[ "$1" = "--disable" ]]; then
131   # This script is executed from base::mac::ExecuteWithPrivilegesAndWait(),
132   # which requires the child process to write its PID to stdout before
133   # anythine else. See base/mac/authorization_util.h for details.
134   echo $$
135   rm -f "$ENABLED_FILE"
136 elif [[ "$1" = "--enable" ]]; then
137   echo $$
138   # Ensure the config file is private whilst being written.
139   rm -f "$CONFIG_FILE"
140   umask 0077
141   cat > "$CONFIG_FILE"
142   # Ensure the config is readable by the user registering the host.
143   chmod +a "$USER:allow:read" "$CONFIG_FILE"
144   touch "$ENABLED_FILE"
145 elif [[ "$1" = "--save-config" ]]; then
146   echo $$
147   cat > "$CONFIG_FILE"
148 elif [[ "$1" = "--host-version" ]]; then
149   /usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PLIST_FILE"
150 elif [[ "$1" = "--relaunch-prefpane" ]]; then
151   # Wait for the parent (System Preferences applet) to die, by reading from
152   # stdin until the pipe is broken.
153   cat 2>/dev/null || true
154   open "$PREF_PANE_BUNDLE"
155 elif [[ "$1" = "--run-from-launchd" ]]; then
156   echo Host started for user $USER at $"$(date)"
157   run_host
158 else
159   echo $$
160   exit 1
161 fi