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.
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
17 # The exit code returned by 'wait' when a process is terminated by SIGTERM.
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
26 # Constants controlling the host process relaunch throttling.
27 MINIMUM_RELAUNCH_INTERVAL
=60
28 MAXIMUM_HOST_FAILURES
=10
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
33 PERMISSION_DENIED_PARENTAL_CONTROL
=126
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"
50 local host_failure_count
=0
51 local host_start_time
=0
54 if [[ ! -f "$ENABLED_FILE" ]]; then
55 echo "Daemon is disabled."
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."
73 local relaunch_in
=$
(($MINIMUM_RELAUNCH_INTERVAL - $host_lifetime))
74 echo "Relaunching in ${relaunch_in}s"
77 # If the host ran for long enough, reset the crash counter.
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" &
88 # Wait for the host to return and process its 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.
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
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)"""
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.
135 rm -f "$ENABLED_FILE"
136 elif [[ "$1" = "--enable" ]]; then
138 # Ensure the config file is private whilst being written.
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
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)"