1#!/bin/sh
2# XScreenSaver, Copyright © 2013-2019 Jamie Zawinski <jwz@jwz.org>
3#
4# Permission to use, copy, modify, distribute, and sell this software and its
5# documentation for any purpose is hereby granted without fee, provided that
6# the above copyright notice appear in all copies and that both that
7# copyright notice and this permission notice appear in supporting
8# documentation.  No representations are made about the suitability of this
9# software for any purpose.  It is provided "as is" without express or
10# implied warranty.
11#
12# The guts of the installer.  Copies the screen savers out of the adjacent
13# "Screen Savers" directory and into "/Library/Screen Savers/".  We do it
14# this way instead of just including the screen savers in the package
15# because that would double the size of the DMG.
16#
17# Created: 27-Jul-2013.
18
19#exec >/tmp/xscreensaver.log 2>&1
20#set -x
21
22DEBUG=0
23REQUIRED_SPACE=160	# MB. Highly approximate.
24
25export PATH="/bin:/sbin:/usr/bin:/usr/sbin:$PATH"
26
27function error() {
28  echo "XScreenSaver Installer: Error: $@" >&2
29
30  # Using "System Events" says "No user interaction allowed" on 10.9.
31  # But using "SystemUIServer" or "Automator Runner" still seems to work.
32  #
33  runner="System Events"
34  if [ -d "/System/Library/CoreServices/SystemUIServer.app" ]; then
35    runner="SystemUIServer"
36  elif [ -d "/System/Library/CoreServices/Automator Runner.app" ]; then
37    runner="Automator Runner"
38  fi
39
40  (
41    osascript <<__EOF__
42      tell app "$runner" to \
43        display dialog "$@" \
44        buttons "Bummer" \
45        default button 1 \
46        with icon 0 \
47        with title "Installation Error"
48__EOF__
49  ) </dev/null >/dev/null 2>&1 &
50  exit 1
51}
52
53
54#if[ x"$DSTVOLUME"    = x ]; then error "DSTVOLUME unset";    fi
55if [ x"$PACKAGE_PATH" = x ]; then error "PACKAGE_PATH unset"; fi
56if [ x"$HOME"         = x ]; then error "HOME unset";         fi
57
58
59echo "Destination: $DSTVOLUME" >&2
60
61if [ x"$USER" = xjwz ]; then DEBUG=1; fi
62
63if [ "$DEBUG" != 0 ]; then DSTVOLUME=/tmp; fi
64
65SRC=`dirname "$PACKAGE_PATH"`/"Screen Savers"
66DST1="$DSTVOLUME/Library/Screen Savers"
67DST2="$DSTVOLUME/Applications"
68
69# Because of Sparkle.framework weirdness, "XScreenSaverUpdater.app" is
70# in the DMG as a compressed tar file instead of an app, and we unpack
71# it when installing.  Without this, auto-updates won't work: If there's
72# an .app there, Sparkle thinks that "XScreenSaverUpdater.app" is the
73# thing it should be updating instead of "Install Everything.pkg".
74#
75UPDATER_SRC="XScreenSaver.updater"
76UPDATER_DST="XScreenSaverUpdater.app"
77
78
79cd "$SRC" || error "The 'Screen Savers' folder does not exist.
80
81You can't copy the installer out of the Disk Image!"
82
83
84free=`df -k "$DSTVOLUME" |
85     tail -1 | head -1 | awk '{print $4}'`
86need=`echo $REQUIRED_SPACE \* 1024 | bc`
87if [ "$free" -lt "$need" ]; then
88 free=`echo $free / 1024 | bc`
89 error "Not enough disk space: $free MB available, $REQUIRED_SPACE MB required."
90fi
91
92
93mkdir -p "$DST1" || error "Unable to create directory $DST1/"
94mkdir -p "$DST2" || error "Unable to create directory $DST2/"
95
96# Install the savers and the updater in /System/Library/Screen Savers/
97# Install the other apps in /Applications/
98#
99for f in *.{saver,app} "$UPDATER_SRC" ; do
100  EXT=`echo "$f" | sed 's/^.*\.//'`
101  if [ "$f" = "$UPDATER_SRC" ]; then
102    DST="$DST1"
103  elif [ "$EXT" = "app" ]; then
104    DST="$DST2"
105  else
106    DST="$DST1"
107  fi
108
109  DD="$DST/$f"
110
111  echo "Installing $DD" >&2
112  rm -rf "$DD" || error "Unable to delete $DD"
113
114  if [ "$f" = "$UPDATER_SRC" ]; then
115    ( cd "$DST/" && tar -xzf - ) < "$f" || error "Unable to unpack $f in $DST/"
116  else
117    cp -pR "$f" "$DD" || error "Unable to install $f in $DST/"
118  fi
119
120  # The files in the DMG might be owned by "jwz:staff" (503:20)
121  chown root:wheel "$DD"
122
123  # Eliminate the "this was downloaded from the interweb" warning.
124  # (This trick probably doesn't work.)
125  xattr -r -d com.apple.quarantine "$DD"
126
127  if [ "$EXT" = "app" ]; then
128    # Eliminate the "this is from an unknown developer" warning.
129    # (This trick probably doesn't work.)
130    spctl --add "$DD"
131  fi
132
133  # If this saver or app is also installed in any per-user directory,
134  # delete those copies so that we don't have conflicts.
135  #
136  if [ "$DEBUG" = 0 ]; then
137    rm -rf "$DSTVOLUME/Users/"*"/Library/Screen Savers/$f"
138  fi
139done
140
141
142# Savers are sandboxed as of 10.15, which means the preferences files
143# moved.  If this is 10.15 or later, and there are old preferences files,
144# move them to the new location.  Without this, all saver preferences
145# would be wiped by the upgrade.
146#
147V=`sw_vers -productVersion`
148V0=`echo $V | sed 's/^\([^.]*\).*/\1/'`
149V1=`echo $V | sed 's/^[^.]*\.\([^.]*\).*$/\1/'`
150
151if [ "$V0" == 10 -a \! "$V1" \< 15 ]; then	# If >= 10.15
152  for HOME2 in "$DSTVOLUME/Users/"* ; do	# for each user
153
154    CON="$HOME2/Library/Containers"
155    LEG="$CON/com.apple.ScreenSaver.Engine.legacyScreenSaver"
156    NBH="$LEG/Data/Library/Preferences/ByHost"
157    OBH="$HOME2/Library/Preferences/ByHost"
158
159    if [ -d "$CON" ]; then		# if there are Containers
160      if ! [ -d "$LEG" ]; then		# but no legacyScreenSaver already
161        UG=`stat -f %u:%g "$CON"`
162        umask 077
163        mkdir -p "$NBH"			# create tree
164        chown -R "$UG" "$LEG"		# correct user/group
165        echo "Moving old prefs to $NBH" >&2
166        mv "$OBH/org.jwz.xscreensaver."* "$NBH/"
167      fi
168    fi
169  done
170fi
171
172
173# Launch System Preferences with the Screen Saver pane selected.
174#
175open /System/Library/PreferencePanes/DesktopScreenEffectsPref.prefPane &
176
177exit 0
178