1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
@SHEBANGGUARD@#!/bin/bash -p
# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Called by the application to install in a new location. Generally, this
# means that the application is running from a disk image and wants to be
# copied to /Applications. The application, when running from the disk image,
# will call this script to perform the copy.
#
# This script will be run as root if the application determines that it would
# not otherwise have permission to perform the copy.
#
# When running as root, this script will be invoked with the real user ID set
# to the user's ID, but the effective user ID set to 0 (root). bash -p is
# used on the first line to prevent bash from setting the effective user ID to
# the real user ID (dropping root privileges).
set -eu
# This script may run as root, so be paranoid about things like ${PATH}.
export PATH="/usr/bin:/usr/sbin:/bin:/sbin"
# Uses "defaults read" to obtain the value of a key in a property list.
#
# See chrome/installer/mac/keystone_install.sh for more details.
infoplist_read() {
__CFPREFERENCES_AVOID_DAEMON=1 defaults read "${@}"
}
# If running as root, output the pid to stdout before doing anything else.
# See chrome/browser/mac/authorization_util.h.
if [ ${EUID} -eq 0 ] ; then
echo "${$}"
fi
if [ ${#} -ne 2 ] ; then
echo "usage: ${0} SRC DEST" >& 2
exit 2
fi
SRC=${1}
DEST=${2}
# Make sure that SRC is an absolute path and that it exists.
if [ -z "${SRC}" ] || [ "${SRC:0:1}" != "/" ] || [ ! -d "${SRC}" ] ; then
echo "${0}: source ${SRC} sanity check failed" >& 2
exit 3
fi
# Make sure that DEST is an absolute path and that it doesn't yet exist.
if [ -z "${DEST}" ] || [ "${DEST:0:1}" != "/" ] || [ -e "${DEST}" ] ; then
echo "${0}: destination ${DEST} sanity check failed" >& 2
exit 4
fi
# Do the copy.
rsync --links --recursive --perms --times "${SRC}/" "${DEST}"
# The remaining steps are not considered critical.
set +e
# Notify LaunchServices.
CORESERVICES="/System/Library/Frameworks/CoreServices.framework"
LAUNCHSERVICES="${CORESERVICES}/Frameworks/LaunchServices.framework"
LSREGISTER="${LAUNCHSERVICES}/Support/lsregister"
"${LSREGISTER}" -f "${DEST}"
# If this script is not running as root and the application is installed
# somewhere under /Applications, try to make it writable by all admin users.
# This will allow other admin users to update the application from their own
# user Keystone instances even if the Keystone ticket is not promoted to
# system level.
#
# If the script is not running as root and the application is not installed
# under /Applications, it might not be in a system-wide location, and it
# probably won't be something that other users on the system are running, so
# err on the side of safety and don't make it group-writable.
#
# If this script is running as root, a Keystone ticket promotion is expected,
# and future updates can be expected to be applied as root, so
# admin-writeability is not a concern. Set the entire thing to be owned by
# root in that case, regardless of where it's installed, and drop any group
# and other write permission.
#
# If this script is running as a user that is not a member of the admin group,
# the chgrp operation will not succeed. Tolerate that case, because it's
# better than the alternative, which is to make the application
# world-writable.
CHMOD_MODE="a+rX,u+w,go-w"
if [ ${EUID} -ne 0 ] ; then
if [ "${DEST:0:14}" = "/Applications/" ] &&
chgrp -Rh admin "${DEST}" >& /dev/null ; then
CHMOD_MODE="a+rX,ug+w,o-w"
fi
else
chown -Rh root:wheel "${DEST}" >& /dev/null
fi
chmod -R "${CHMOD_MODE}" "${DEST}" >& /dev/null
# On the Mac, or at least on HFS+, symbolic link permissions are significant,
# but chmod -R and -h can't be used together. Do another pass to fix the
# permissions on any symbolic links.
find "${DEST}" -type l -exec chmod -h "${CHMOD_MODE}" {} + >& /dev/null
# Because this script is launched by the application itself, the installation
# process inherits the quarantine bit (LSFileQuarantineEnabled). Any files or
# directories created during the update will be quarantined in that case,
# which may cause Launch Services to display quarantine UI. That's bad,
# especially if it happens when the outer .app launches a quarantined inner
# helper. Since the user approved the application launch if quarantined, it
# it can be assumed that the installed copy should not be quarantined. Use
# xattr to drop the quarantine attribute.
QUARANTINE_ATTR=com.apple.quarantine
xattr -d -r "${QUARANTINE_ATTR}" "${DEST}" >& /dev/null
# Install the updater at system level when running as root.
# (At user level, Chrome will install it and register as needed when run).
if [ ${EUID} -eq 0 ] ; then
readonly CHROME_APP_INFO_PLIST="${DEST}/Contents/Info.plist"
# Create the brand file, if specified.
brand_file_written="false"
brand="$(infoplist_read "${CHROME_APP_INFO_PLIST}" "KSBrandID")"
if [[ -n "${brand}" ]]; then
readonly BRAND_PLIST="/Library/Google/@BROWSER_PRODUCT_NAME@ Brand.plist"
defaults write "${BRAND_PLIST}" "KSBrandID" \
-string "${brand}" \
&& chmod 644 "${BRAND_PLIST}" \
&& brand_file_written="true"
fi
set -e
"${DEST}/Contents/Frameworks/@BROWSER_PRODUCT_NAME@ Framework.framework/Helpers/@UPDATER_PRODUCT_NAME@.app/Contents/MacOS/@UPDATER_PRODUCT_NAME@" "--install" "--system"
readonly KS_ADMIN="/Library/@UPDATER_COMPANY_SHORT_NAME@/@KEYSTONE_APP_NAME@/@KEYSTONE_APP_NAME@.bundle/Contents/MacOS/ksadmin"
product="$(infoplist_read "${CHROME_APP_INFO_PLIST}" "KSProductID")"
version="$(infoplist_read "${CHROME_APP_INFO_PLIST}" "KSVersion")"
ksadmin_args=(
--register
--productid "${product}"
--version "${version}"
--xcpath "${DEST}"
--tag-path "${CHROME_APP_INFO_PLIST}"
--tag-key "KSChannelID"
--version-path "${CHROME_APP_INFO_PLIST}"
--version-key "KSVersion"
)
# Tag to use if the app info plist is gone (i.e. the program is uninstalled).
if channel="$(infoplist_read "${CHROME_APP_INFO_PLIST}" "KSChannelID")"; then
ksadmin_args+=(
--tag "${channel}"
)
fi
if [[ "${brand_file_written}" == "true" ]]; then
ksadmin_args+=(
--brand-path "${BRAND_PLIST}"
--brand-key "KSBrandID"
)
fi
"${KS_ADMIN}" "${ksadmin_args[@]}"
set +e
fi
# Great success!
exit 0
|