a2server/scripts/a2server-3-sharing.txt
T. Joseph Carter 6229dba43f Fix stupid logic error bug
We need a more robust way to detect whether netatalk is installed or
needs to be installed, the current check by a2server version isn't very
reliable anyway, assuming that netatalk will always be hand-compiled and
never upgraded.  But for now at least, let's fix my idiot mistake.
2018-09-01 16:03:42 -07:00

738 lines
30 KiB
Bash
Executable File

#! /bin/bash
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
# A2SERVER -- a virtual machine for sharing files to Apple II clients
# by Ivan X, ivan@ivanx.com
# Installs Netatalk 2.2.4 for debian/raspbian (Wheezy or Jessie)
# Thanks to Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, and others
# at comp.sys.apple2 for the work they've done and insight they've
# offered which made it possible to put this together.
# --- Installing netatalk
a2sBinaryURL="http://blocksfree.com/downloads"
useExternalURL=1
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
debianVersion="$(lsb_release -rs)"
isRpi=
arch=
if [[ -f /usr/bin/raspi-config ]]; then
isRpi=1
arch='rpi'
elif [[ "$(lsb_release -ds)" = Debian* ]]; then
if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then
uname_m="$(uname -m)"
if [[ $uname_m == "i686" ]]; then
arch='debian_x86'
elif [[ $uname_m == "x86_64" ]]; then
arch='debian_x64'
fi
fi
fi
debianName=$(lsb_release -cs)
# enable SSH (disabled by default in Raspbian from late 2016 onward)
if [[ $isRpi ]] && ! ps aux | grep -q '[s]shd'; then
echo "A2SERVER: Enabling ssh access..."
sudo systemctl enable ssh &> /dev/null && sudo systemctl start ssh &> /dev/null
else
echo "A2SERVER: ssh access is already enabled."
fi
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
read a2sVersion </usr/local/etc/A2SERVER-version
fi
# If A2SERVER 101 or greater is installed, we already did this and can skip it.
if [[ "$a2sVersion" != *.*.* || "$a2sVersion" -lt 101 ]]; then
echo "A2SERVER: Installing Netatalk (this will take a while)..."
# stop Netatalk and samba if running (during upgrade)
if [[ $(ps --no-headers -C afpd) ]]; then
sudo /etc/init.d/netatalk stop &> /dev/null
sudo /etc/init.d/samba stop &> /dev/null
fi
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
compileFromSource=1
urls=
while [[ $arch ]]; do
# Install runtime libraries needed by Netatalk
if [[ $(apt-cache search '^libdb5.1$') ]]; then # Wheezy
# Dependencies: netatalk 2.2.4
sudo apt-get -y install libdb5.1
elif [[ $(apt-cache search '^libdb5.3$') ]]; then # Jessie or Stretch
# Dependencies: netatalk 2.2.4
sudo apt-get -y install libdb5.3
else
break
fi
if [[ $(apt-cache search '^libssl1.0.0$') ]]; then # Wheezy or Jessie
# Dependencies: netatalk 2.2.4
sudo apt-get -y install libssl1.0.0
elif [[ $(apt-cache search '^libssl1.0.2$') ]]; then # Stretch
# Dependencies: netatalk 2.2.4
sudo apt-get -y install libssl1.0.2
else
break
fi
if [[ $(apt-cache search '^libgcrypt11$') ]]; then # Wheezy
# Dependencies: netatalk 2.2.4
sudo apt-get -y install libgcrypt11
elif [[ $(apt-cache search '^libgcrypt20$') ]]; then # Jessie or Stretch
# Dependencies: netatalk 2.2.4
sudo apt-get -y install libgcrypt20
else
break
fi
# install Netatalk
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${a2sBinaryURL}/picopkg/netatalk224-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
fi
sudo mandb &> /dev/null
[[ -f /usr/local/sbin/atalkd ]] && compileFromSource=
break
done
if [[ $compileFromSource ]]; then
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install build-essential
if [[ $(apt-cache search '^libssl1.0-dev$') ]]; then # Stretch
if [[ $(dpkg -l | grep libssl-dev | tr -s ' ' | cut -d ' ' -f 3 | cut -c 1-3) == "1.1" ]]; then
echo "A2SERVER: WARNING: libssl-dev will be removed to install libssl1.0-dev"
fi
# Note the libssl1.0-dev package will go away; we need a 1.1 patch
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libssl1.0-dev libssl-dev-
else # probably Jessie or Wheezy
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libssl-dev
fi
if [[ $(apt-cache search '^libdb5.1-dev$') ]]; then # Wheezy
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libdb5.1-dev
elif [[ $(apt-cache search '^libdb5.3-dev$') ]]; then # Jessie or Stretch
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libdb5.3-dev
else
echo "A2SERVER: WARNING: unknown version of libdb-dev is being installed."
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libdb-dev
fi
if [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then # Wheezy, Jessie, Stretch
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libgcrypt11-dev
else
echo "A2SERVER: WARNING: unknown version of libgcrypt-dev is being installed."
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install $(apt-cache search '^libgcrypt.*dev$' | sort -r | head -1 | cut -d ' ' -f 1)
fi
sudo apt-get clean
# get Netatalk
rm -rf /tmp/netatalk &> /dev/null
mkdir /tmp/netatalk
cd /tmp/netatalk
if [[ $useExternalURL ]]; then
wget -qO netatalk-2.2.4.tar.gz "http://downloads.sourceforge.net/project/netatalk/netatalk/2.2.4/netatalk-2.2.4.tar.gz"
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
fi
if [[ ! -d netatalk-2.2.4 ]]; then
wget -O netatalk-2.2.4.tar.gz "${a2sBinaryURL}/source/netatalk-2.2.4.tar.gz"
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
fi
cd netatalk-2.2.4
# Patch the source so file dates are preserved during a GS/OS folder copy,
# and the AsanteTalk bridge consistently starts up in AppleTalk Phase 2
# and the Dayna bridge doesn't crash GS/OS
# props to Steven Hirsch for these
# FIXME do this as a patch file
sed -i ':a;N;$!ba;s/case FILPBIT_ATTR :\n *change_mdate = 1;\n/case FILPBIT_ATTR :\n/g' etc/afpd/file.c
sed -i 's/rtmp->rt_iface == iface/rtmp->rt_iface != iface/g' etc/atalkd/main.c
# prepare to build Netatalk
./configure --enable-debian --enable-ddp --enable-a2boot
# uninstall Netatalk if already installed
if [[ -f /usr/local/sbin/afpd ]]; then
sudo make uninstall
fi
# compile and install Netatalk
make
sudo make install
# to remove the Netatalk source code (optional), type:
cd
rm -rf /tmp/netatalk
fi
else
echo "A2SERVER: Netatalk is already installed."
fi
unset a2sVersion
# --- Install MacIPgw
if ! hash macipgw &>/dev/null; then
echo "A2SERVER: Installing TCP over AppleTalk (MacIP)..."
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${a2sBinaryURL}/picopkg/macipgw-${arch}.tgz" | sudo tar Pzx; } 2> /dev/null
fi
if ! hash macipgw &> /dev/null; then
wd="$PWD"
sudo apt-get -y install build-essential
rm -rf /tmp/macipgw &> /dev/null
mkdir /tmp/macipgw
cd /tmp/macipgw
# macipgw has no releases, so use the hash of HEAD to auto-generate a zipball
# note: topdir will be macipgw-<full hash>, EEK!
# note: .tar.gz also works
if [[ $useExternalURL ]]; then
wget -qO macipgw.zip "https://github.com/zero2sixd/macipgw/archive/4f77c09.zip"
unzip macipgw.zip 2> /dev/null
rm macipgw.zip &> /dev/null
fi
if [[ ! -d macipgw-* ]]; then
wget -qO macipgw.zip "${a2sBinaryURL}/source/macipgw-4f77c09.zip"
unzip macipgw.zip 2> /dev/null
rm macipgw.zip &> /dev/null
fi
cd macipgw-*
make
sudo make install
cd "$wd"
rm -rf /tmp/macipgw
fi
else
echo "A2SERVER: TCP over AppleTalk (MacIP) has already been installed."
fi
# --- Configuring Netatalk
echo "A2SERVER: Configuring Netatalk..."
# if missing Netatalk startup file, download a fresh one
if [ ! -f /etc/init.d/netatalk ]; then
echo "A2SERVER: Downloading new Netatalk startup script..."
sudo wget -qO /etc/init.d/netatalk "${a2sBinaryURL}/a2server/netatalk-init.d-clean.txt"
fi
# make the Netatalk startup script work correctly
sudo sed -i 's/bin\/sh/bin\/bash/' /etc/init.d/netatalk
# enable AppleTalk networking support in Netatalk, and run in background
sudo sed -i 's/#ATALKD_RUN=no/ATALKD_RUN=yes/' /etc/default/netatalk
sudo sed -i 's/#ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk
# FIXME do this as a patch file
if [[ ! $(grep 'kernelRelease' /etc/init.d/netatalk) ]]; then
sudo sed -i 's@\(\tif \[ x\"$ATALKD_RUN\)@\n\t# check for valid AppleTalk kernel module\n\t[[ $ATALKD_RUN == "yes" ]] \&\& { kernelRelease=$(uname -r); kernelMajor=$(cut -d "." -f 1 <<< $kernelRelease); kernelMinor=$(cut -d "." -f 2 <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); kernelPatch=$(cut -d "." -f 3- <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); [[ ( $kernelMajor -eq 3 \&\& $kernelMinor -ge 12 \&\& $kernelMinor -le 15 ) \&\& ( ! ( -f /usr/bin/raspi-config \&\& $kernelMinor -eq 12 \&\& $kernelPatch -ge 25 ) ) \&\& ( ( ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ) || $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d " ") != "ecb239fc084c36de93f6926e7749b80f6024f269" ) ]] \&\& { ATALKD_RUN=no; echo "[AppleTalk networking is not available.]" 1>\&2; } }\n\n\1@' /etc/init.d/netatalk
fi
sudo sed -i 's/Starting Netatalk services (this will take a while): /Starting Netatalk services"\n\t\t\t[[ $ATALKD_RUN == "yes" ]] \&\& echo -n " (this will take 45 seconds)"\n\t\t\techo -n ":/' /etc/init.d/netatalk
sudo sed -i 's/Starting Netatalk services in the background./Netatalk services will be available in 45 seconds./' /etc/init.d/netatalk
sudo sed -i 's/-n "Restarting Netatalk Daemons (this will take a while)"/"Restarting Netatalk Daemons."/' /etc/init.d/netatalk
# enable MacIPgw support after launching atalkd
if ! grep -q -i 'macipgw' /etc/init.d/netatalk; then
# FIXME do this as a patch file
sudo sed -i ':a;N;$!ba;s@\(echo -n " atalkd"\)\(.*# prepare\)@\1\n\n\t\t# start MacIPgw (TCP over AppleTalk) service\n\t\tps aux | grep -q "[m]acipgw" \&\& sudo killall macipgw 2> /dev/null || :\n\t\tatalkd_interface=$(grep "^[^ #]" /etc/netatalk/atalkd.conf | tail -1 | cut -d " " -f 1)\n\t\tsysctl -w net.ipv4.ip_forward=1 > /dev/null\n\t\tmacipgw -n 8.8.8.8 192.168.151.0 255.255.255.0\n\t\t/sbin/iptables -t nat -A POSTROUTING -o ${atalkd_interface} -j MASQUERADE\n\t\t/sbin/iptables -A FORWARD -i ${atalkd_interface} -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n\t\t/sbin/iptables -A FORWARD -i tun1 -o ${atalkd_interface} -j ACCEPT\n\n\t\techo -n " macipgw"\n\2@' /etc/init.d/netatalk
sudo sed -i 's@\(start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd.*$\)@\1\n echo -n " macipgw"\n sudo killall macipgw 2> /dev/null@' /etc/init.d/netatalk
fi
# enable network boot support in netatalk
sudo sed -i 's/timelord/a2boot/g' /etc/init.d/netatalk
sudo sed -i 's/TIMELORD/A2BOOT/g' /etc/init.d/netatalk
sudo sed -i 's/#A2BOOT_RUN=no/A2BOOT_RUN=yes/' /etc/default/netatalk
# allow Guest users to be able to network boot
sudo sed -i "s/#AFPD_GUEST=nobody/AFPD_GUEST=$USER/" /etc/default/netatalk
# (For a Guest user with different permissions than the compile-time user, create a
# Linux user, and then specify that user for AFPD_GUEST instead.)
# create a symbolic link to the startup configuration file in netatalk configuration folder
[[ -L /usr/local/etc/netatalk/netatalk.conf ]] \
|| sudo ln -s /etc/default/netatalk /usr/local/etc/netatalk/netatalk.conf
# create a symbolic link to the netatalk configuration folder in /etc
[[ -L /etc/netatalk ]] || sudo ln -s /usr/local/etc/netatalk /etc/netatalk
if [[ ! $(grep '^- -ddp.*uams_randnum.so' /usr/local/etc/netatalk/afpd.conf) ]]; then
# set up to allow Guest, Cleartext, RandNum, DHX, and DHX2 login
# disable DHX (DHCAST128) on Raspberry Pi, which refuses uams if the config string is too long
dhx=
if [[ ! -f /usr/bin/raspi-config ]]; then
dhx="uams_dhx.so,"
fi
sudo tee -a /usr/local/etc/netatalk/afpd.conf >/dev/null <<EOF
- -ddp -tcp -uamlist uams_guest.so,uams_clrtxt.so,uams_randnum.so",${dhx}uams_dhx2.so
EOF
fi
# replace home folder share and end of file mark with share placeholders
sudo sed -i 's/^~/#share1\n\n#share2/' \
/usr/local/etc/netatalk/AppleVolumes.default
# disable default volume options for Mac OS X clients
sudo sed -i 's/^:DEFAULT/#:DEFAULT/' \
/usr/local/etc/netatalk/AppleVolumes.default
if [[ $(tac /usr/local/etc/netatalk/atalkd.conf | sed '/./,$!d' | head -1 | cut -c 1) == "#" ]]; then
# enable netatalk on the default network interface
# needs -router and -zone to prevent GS/OS AppleShare CDEV crash when used
# with Dayna or Asante bridges
echo -e 'eth0 -router -phase 2 -net 1 -zone "A2SERVER"' | sudo tee -a /usr/local/etc/netatalk/atalkd.conf > /dev/null
fi
# Raspberry Pi
if [[ $isRpi ]]; then
# blink LED upon netatalk startup
if [[ ! $(grep 'led0' /etc/init.d/netatalk) ]]; then
# FIXME Do this ... readably.
sudo sed -i ':a;N;$!ba;s/fi\n}/fi\n\n # blink LED on Raspberry Pi\n ([[ -e \/sys\/class\/leds\/ACT ]] \&\& led=ACT || led=led0; echo none > \/sys\/class\/leds\/$led\/trigger; for i in {1..20}; do echo 1 > \/sys\/class\/leds\/$led\/brightness; sleep 0.25; echo 0 > \/sys\/class\/leds\/$led\/brightness; sleep 0.25; done; echo mmc0 > \/sys\/class\/leds\/$led\/trigger) \&\n}/' /etc/init.d/netatalk
fi
fi
# 1.3.0: we are no longer setting up new GSFILES
# set up GSFILES share (for GS data files, not GSOS system)
# classic Mac OS file names are allowed (31 chars, mixed case, everything but colons)
#sudo sed -i \
# 's/^#share1/\/media\/A2SHARED\/GSFILES\ GSFILES ea:ad/' \
# /usr/local/etc/netatalk/AppleVolumes.default
# 1.3.0: if GSFILES is being shared, make directory if not there
if grep -q '^/srv/A2SERVER/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then
mkdir -p /srv/A2SERVER/GSFILES
fi
# prior to 1.3.0:
# file names must be ProDOS 8 compliant (all caps, 15 chars, letters/numbers/periods only)
# lowercase filenames will be converted to upper automatically
# need for GS/OS system because it may refer to files by either upper or lower
# 1.3.0+:
# see if shared already uses ciopfs (case-insensitive file system), and convert if not
# restore known GS/OS file paths to mixed case
# set up ciopfs (case insensitive file system) for share
if [[ -d /srv/A2SERVER/A2FILES && ! -d /srv/A2SERVER/.a2files ]]; then
echo "A2SERVER: Converting A2FILES to support mixed case..."
sudo /etc/init.d/netatalk stop &> /dev/null
sudo /etc/init.d/samba stop &> /dev/null
if ! hash getfattr &> /dev/null; then
# Dependency: for ciopfs conversion (setfattr)
sudo apt-get -y install attr &> /dev/null
sudo apt-get clean
fi
rm /srv/A2SERVER/A2FILES/.APPLEDESKTOP 2> /dev/null
mkdir -p /tmp/netboot
wget -qO /tmp/A2FILES-list.txt "${a2sBinaryURL}/a2server/A2FILES-list.txt"
find /srv/A2SERVER/A2FILES -name '*' | tail -n +2 | tac > /tmp/filelist.txt
while read thisFile; do
mixedCase="${thisFile##*/}"
gsosPath=$(grep -i -m 1 "^${thisFile}$" /tmp/A2FILES-list.txt)
[[ $gsosPath ]] && mixedCase="${gsosPath##*/}"
sudo setfattr -n "user.filename" -v "$mixedCase" "$thisFile"
if [[ ${thisFile##*/} != $mixedCase ]]; then
echo -e " renaming $thisFile to ${mixedCase}\n"
else
echo -e " processing $thisFile\n"
fi
sudo mv "$thisFile" "${thisFile%/*}/${mixedCase,,}" 2> /dev/null
done < /tmp/filelist.txt
mv /srv/A2SERVER/A2FILES /srv/A2SERVER/.a2files
mkdir /srv/A2SERVER/A2FILES
sudo sed -i 's/casefold:toupper //' /usr/local/etc/netatalk/AppleVolumes.default 2> /dev/null
sudo sed -i 's/^VOLCASEFOLD:.*/VOLCASEFOLD:/' /srv/A2SERVER/.a2files/.appledesktop/.volinfo 2> /dev/null
sudo sed -i 's|/media/A2SHARED/A2FILES|/srv/A2SERVER/A2FILES|' /srv/A2SERVER/.a2files/.appledesktop/.volinfo 2> /dev/null
fi
# 1.3.0: remove GSFILES if empty
if grep -q '^/srv/A2SERVER/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then
gsFilesContents=
if [[ -d /srv/A2SERVER/GSFILES ]]; then
gsFilesContents="$(find /srv/A2SERVER/GSFILES -not -path '*/\.*' | grep -v '^/srv/A2SERVER/GSFILES$' | grep -v '^/srv/A2SERVER/GSFILES/Network Trash Folder$' | grep -v '^/srv/A2SERVER/GSFILES/Temporary Items$')"
if [[ ! $gsFilesContents ]]; then
echo "A2SERVER: Removing empty GSFILES shared volume..."
sudo /etc/init.d/netatalk stop &> /dev/null
sudo /etc/init.d/samba stop &> /dev/null
sudo sed -i 's|^/srv/A2SERVER/GSFILES.*$|#share1|' /usr/local/etc/netatalk/AppleVolumes.default
sudo rm -r /srv/A2SERVER/GSFILES
else
echo "A2SERVER: GSFILES shared volume has files, leaving as is."
fi
fi
fi
# set up A2FILES case-insensitive share (for ProDOS 8 files, and GS/OS system)
sudo sed -i \
's/^#share2/\/srv\/A2SERVER\/A2FILES\ A2FILES options:prodos\ ea:ad/' \
/usr/local/etc/netatalk/AppleVolumes.default
mkdir -p /srv/A2SERVER/A2FILES
mkdir -p /srv/A2SERVER/.a2files
# set up ciopfs
if ! hash ciopfs &> /dev/null; then
echo "A2SERVER: Installing ciopfs (case insensitive file system)..."
cd /tmp
# Dependency: For ciopfs
sudo apt-get -y install fuse libglib2.0-0 libattr1 libfuse2
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${a2sBinaryURL}/pickpkg/ciopfs-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
fi
if [[ -f /etc/fuse.conf ]] && sudo grep -q user_allow_other /etc/fuse.conf; then
sudo sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
else
echo "user_allow_other" | sudo tee /etc/fuse.conf > /dev/null
fi
if ! hash ciopfs &> /dev/null; then
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
# Dependency: build-dep for ciopfs
sudo apt-get -y install build-essential libfuse-dev libglib2.0-dev libattr1-dev
sudo apt-get -y clean
cd /tmp
rm -rf /tmp/ciopfs &> /dev/null
mkdir /tmp/ciopfs
cd /tmp/ciopfs
if [[ $useExternalURL ]]; then
wget -q -O ciopfs-0.4.tar.gz "http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz"
if (( $? != 0 )); then
wget -q -O ciopfs-0.4.tar.gz http://web.archive.org/web/20160911102924/http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz
fi
tar zxf ciopfs-0.4.tar.gz &> /dev/null
fi
if [ ! -f ciopfs*/ciopfs.c ]; then # single brackets required for glob
wget -q -O ciopfs-0.4.tar.gz "${a2sBinaryURL}/source/ciopfs-0.4.tar.gz"
tar zxf ciopfs-0.4.tar.gz &> /dev/null
fi
cd ciopfs*
make
sudo mv ciopfs /usr/local/bin
cd
rm -rf /tmp/ciopfs
fi
if ! grep -q '^ciopfs' /etc/fstab; then
# http://www.brain-dump.org/projects/ciopfs/ recommends:
# /data/projects/ciopfs/data /data/projects/ciopfs/mnt ciopfs allow_other,default_permissions,use_ino,attr_timeout=0 0 0
# Really should check the docs on that
echo "ciopfs#/srv/A2SERVER/.a2files /srv/A2SERVER/A2FILES fuse allow_other 0 0" | sudo tee -a /etc/fstab > /dev/null
fi
if ! mount | grep '^ciopfs.*A2FILES'; then
sudo ciopfs /srv/A2SERVER/.a2files /srv/A2SERVER/A2FILES -o allow_other
fi
else
echo "A2SERVER: ciopfs (case insensitive file system) has already been installed."
fi
if [[ ! -d /srv/A2SERVER/A2FILES/.AppleDesktop ]]; then
cd /srv/A2SERVER/A2FILES
mkdir .AppleDesktop
fi
# set up ADTDISKS share (ADTPro disk image folder, if A2CLOUD is installed)
# classic Mac OS file names are allowed (31 chars, mixed case, everything but colons)
if [[ -d /usr/local/adtpro/disks ]]; then # A2CLOUD/ADTPro installed
if [[ ! -d /srv/A2SERVER/ADTDISKS ]]; then
ln -s /usr/local/adtpro/disks /srv/A2SERVER/ADTDISKS
fi
if [[ ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then
sudo sed -i 's@^# End of File@/srv/A2SERVER/ADTDISKS ADTDISKS ea:ad\n\n# End of File@' /usr/local/etc/netatalk/AppleVolumes.default
fi
fi
# to make Netatalk start up when the server boots:
sudo update-rc.d netatalk defaults &> /dev/null
# prepare shared volumes for use
afpsync -v < /dev/null
# --- Setting up users
# At this point, the server is usable for Guest access.
# skip if we've already done this
if [[ -f /usr/local/etc/netatalk/afppasswd ]]; then
echo "A2SERVER: Netatalk user logins have already been set up."
else
echo
echo "A2SERVER: Setting up AFP password 'apple2' for Apple II and Mac clients..."
# echo "A2SERVER: Enter 'apple2' or another password of up to eight characters."
echo
# set registered user login using RandNum authentication
sudo afppasswd -c
sudo sed -i "s/^\(${USER}\).*$/\1:6170706C65320000:****************:********/" /usr/local/etc/netatalk/afppasswd
# (The afppasswd -c only needs to ever be done once. You can repeat
# the afppasswd -a to make Netatalk randnum logins for other Linux users.)
fi
# Check AppleTalk kernel module for existence and validity
# get Kernel release (e.g. 3.6.11+) and version (e.g. #557)
kernelRelease=$(uname -r)
kernelMajor=$(cut -d '.' -f 1 <<< $kernelRelease)
kernelMinor=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
kernelPatch=$(cut -d '.' -f 3- <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
kernelMajorMinor=$(cut -d '.' -f 1-2 <<< $kernelRelease)
# if on kernel 3.12 through 3.15, check if we need to delete AppleTalk module to prevent kernel panics
if [[ $kernelMajor -eq 3 && $kernelMinor -ge 12 && $kernelMinor -le 15 ]]; then
# if not RPi, or RPi without ivanx-fixed AppleTalk module, delete the module
if [[ ! ( $isRpi && $kernelMinor -eq 12 && $kernelPatch -ge 25 ) ]]; then
if [[ -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then
if [[ $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d ' ') != "ecb239fc084c36de93f6926e7749b80f6024f269" ]]; then
# stop Netatalk
sudo /etc/init.d/netatalk stop &> /dev/null
echo "A2SERVER: Deleting defective AppleTalk kernel module..."
sudo rmmod appletalk 2> /dev/null
sudo rm -r /lib/modules/$kernelRelease/kernel/net/appletalk
# disable single-user mode on Pi (other Linux can use Recovery boot)
if [[ $isRpi && $(grep ' single' /boot/cmdline.txt 2> /dev/null) ]]; then
echo "A2SERVER: Disabling single-user mode for next boot..."
sudo sed -i 's/ single//' /boot/cmdline.txt
touch /tmp/singleUser # so note to restart can display following install
fi
fi
fi
fi
fi
# if IPDDP module exists (e.g. Debian, but not Raspbian),
# AppleTalk kernel module has been compiled to support it and can't work with MacIP
if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]]; then
sudo /etc/init.d/netatalk stop &> /dev/null
sudo rmmod ipddp 2> /dev/null
sudo rmmod appletalk 2> /dev/null
echo "A2SERVER: Replacing AppleTalk kernel module (IPDDP disabled) for MacIP use..."
sudo mv /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko /tmp 2> /dev/null
if [[ ${arch%_*} == "debian" ]]; then
echo "A2SERVER: Fetching AppleTalk kernel module for Debian..."
wget -qO /tmp/appletalk.tgz "${a2sBinaryURL}/picopkg/appletalk-${kernelRelease}-${arch}.tgz"
if [[ $? -eq 0 ]]; then
# if we found a prebuilt one on a2server site, install it and load it
sudo tar Pxf /tmp/appletalk.tgz &> /dev/null
sudo depmod
sudo modprobe appletalk
if [[ $(lsmod | grep appletalk) ]]; then
# if it loaded, restart netatalk
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk
sudo /etc/init.d/netatalk restart &> /dev/null
else
# if we didn't load it successfully, remove it
sudo rm /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko 2> /dev/null
echo "A2SERVER: failed to load AppleTalk kernel module"
fi
fi
fi
if ! lsmod | grep -q appletalk; then
# we don't have a prebuilt AppleTalk module, try to build from source
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
# kernel module compile adapted from from: http://askubuntu.com/a/338403/288003
for i in 1; do
echo "A2SERVER: Building AppleTalk kernel module..."
[[ -f /boot/config-$kernelRelease ]] || break
sudo apt-get -y install linux-headers-$kernelRelease linux-source-$kernelMajorMinor || break
sudo apt-get -y install build-essential
cd /usr/src
kernelSrc=$(find linux-source-${kernelMajorMinor}*)
if [[ ${kernelSrc##*.} == "xz" ]]; then
{ xzcat $kernelSrc | sudo tar x; } &> /dev/null
elif [[ ${kernelSrc##*.} == "bz2" ]]; then
sudo tar jxf $kernelSrc &> /dev/null
elif [[ ${kernelSrc##*.} == "gz" || ${kernelSrc##*.} == "tgz" ]]; then
sudo tar zxf $kernelSrc &> /dev/null
fi
cd linux-source-$kernelMajorMinor
sudo make mrproper
sudo cp ../linux-headers-$kernelRelease/Module.symvers .
yes '' | sudo make oldconfig
sudo sed -i 's:^.*IPDDP.*$:# CONFIG_IPDDP is not set:gI' .config # disable IPDDP in kernel config
sudo sed -i '$!N; /^\(# CONFIG_IPDDP is not set\)\n\1$/!P; D' .config # delete repeated entries
sudo make prepare
sudo make modules_prepare
sudo make SUBDIRS=scripts/mod
sudo make SUBDIRS=net/appletalk modules
sudo cp net/appletalk/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk
sudo depmod
sudo modprobe appletalk
sudo rm -r /lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko
sudo rmdir /lib/modules/$kernelRelease/kernel/drivers/net/appletalk 2> /dev/null
# clean up
cd
sudo rm /usr/src/$kernelSrc
sudo rm -r /usr/src/linux-source-$kernelMajorMinor
sudo apt-get -y purge linux-source-$kernelMajorMinor
done
fi
if [[ $(lsmod | grep appletalk) ]]; then
# if it loaded, make permanent and restart netatalk
sudo rm /lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko 2> /dev/null
sudo sed -i 's:^.*IPDDP.*$:# CONFIG_IPDDP is not set:gI' /boot/config-$kernelRelease
sudo sed -i '$!N; /^\(# CONFIG_IPDDP is not set\)\n\1$/!P; D' /boot/config-$kernelRelease
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart &> /dev/null
else
# if we didn't load it successfully, put back the one that was there
echo "A2SERVER: Unable to replace AppleTalk module, replacing original."
sudo mv /tmp/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk 2> /dev/null
sudo depmod
touch /tmp/noMacIP # to notify at end of install
fi
fi
# --- Start Netatalk (if not running)
bground=
if [[ $(grep 'ATALK_BGROUND=yes' /etc/default/netatalk) ]]; then
bground=1
sudo sed -i 's/ATALK_BGROUND=yes/ATALK_BGROUND=no/' /etc/default/netatalk
fi
[[ $(ps --no-headers -C afpd) ]] || sudo /etc/init.d/netatalk start 2> /dev/null
echo
echo "A2SERVER: Netatalk is installed, configured, and running."
echo
# if atalkd isn't running (no AppleTalk), and this is a Rasbperry Pi:
if [[ ( ! $(pgrep atalkd) ) && $isRpi ]]; then
# if AppleTalk module exists, try to load it
if [[ -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # module present, but not loaded?
sudo depmod
sudo modprobe appletalk
if [[ $(lsmod | grep appletalk) ]]; then
# if it loaded, restart netatalk
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart
else
# if we didn't load it successfully, delete it
sudo rm -r /lib/modules/$kernelRelease/kernel/net/appletalk
fi
fi
# if no AppleTalk module, try to download it from a2server site
if [[ ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # check for rpi kernel module
echo "A2SERVER: Installing AppleTalk kernel module for Raspbian..."
wget -qO /tmp/appletalk.ko.gz "${a2sBinaryURL}/picopkg/appletalk-${kernelRelease}-rpi.ko.gz"
if [[ $? -eq 0 ]]; then
# if we found a prebuilt one on a2server site, install it and load it
gunzip -f /tmp/appletalk.ko.gz &> /dev/null
sudo mkdir -p /lib/modules/$kernelRelease/kernel/net/appletalk
sudo mv /tmp/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk
sudo depmod
sudo modprobe appletalk
if [[ $(lsmod | grep appletalk) ]]; then
# if it loaded, restart netatalk
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart
else
# if we didn't load it successfully, remove it
sudo rm -r /lib/modules/$kernelRelease/kernel/net/appletalk 2> /dev/null
fi
fi
# if we still don't have AppleTalk, try to use rpi-update
rm /tmp/rpiUpdate 2> /dev/null
if [[ ! $(ps aux | grep [a]talkd) ]]; then
# use specific rpi-update commit (at https://github.com/Hexxeh/rpi-firmware/)
# from when AppleTalk was fixed, so we have a consistent firmware that
# we're loading until the next proper release of Raspbian that includes it
# 07-23-14: when AppleTalk was fixed after kernel panics in Raspbian 2014-06-20 (kernel 3.12.22+)
sudo rm /boot/.firmware_revision
sudo rpi-update cfd9a203590737f9536de70a1e01db25a3e8e069
touch /tmp/rpiUpdate # so note to restart can display following install
fi
if [[ ! $(ps aux | grep [a]talkd) ]]; then
if [[ -f /tmp/rpiUpdate ]]; then
echo
echo "AppleTalk networking is installed but not yet active."
echo "When installation is complete, please restart your Raspberry Pi"
echo "when asked or by typing 'system-restart' at the Linux prompt"
echo "to allow Apple II computers to connect."
echo
else
echo
echo "AppleTalk networking could not be activated"
echo "for your Raspbian kernel version ($kernelRelease)."
echo "Please try restarting with 'system-restart'. If that doesn't work,"
echo "you're not going to be able to connect from an Apple II."
echo "See http://appleii.ivanx.com/a2server for help."
echo
fi
fi
fi
fi
if [[ $bground ]]; then
sudo sed -i 's/ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk
fi
# --- Set up Avahi-Daemon (Bonjour/mDNS)
# thanks to: http://missingreadme.wordpress.com/2010/05/08/how-to-set-up-afp-filesharing-on-ubuntu
if [[ ! $(dpkg -l avahi-daemon 2> /dev/null | grep ^ii) || ! $(dpkg -l libnss-mdns 2> /dev/null | grep ^ii) ]]; then
echo "A2SERVER: Installing Avahi-Daemon (Bonjour/mDNS)..."
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
# Dependency: Bonjour for netatalk
sudo apt-get -y install avahi-daemon libnss-mdns &> /dev/null
fi
sudo sed -i 's/^\(hosts.*\)$/\1 mdns/' /etc/nsswitch.conf
if [[ ! -f /etc/avahi/services/afpd.service && ! -f /etc/avahi/services/afpd.service_disabled ]]; then
sudo tee /etc/avahi/services/afpd.service >/dev/null <<EOF
<?xml version="1.0" standalone="no"?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_afpovertcp._tcp</type>
<port>548</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=MacPro</txt-record>
</service>
</service-group>
EOF
fi
sudo /etc/init.d/avahi-daemon restart &> /dev/null