#! /bin/bash # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: version="1.9.0" adtProVersion="2.0.1" # Ensure URL we'll use ends in a / case "$A2CLOUD_SCRIPT_URL" in */) scriptURL="$A2CLOUD_SCRIPT_URL" ;; *) scriptURL="${A2CLOUD_SCRIPT_URL:-https://rawgit.com/RasppleII/a2cloud/current}/" ;; esac case "$A2CLOUD_BINARY_URL" in */) binaryURL="$A2CLOUD_BINARY_URL" ;; *) binaryURL="${A2CLOUD_BINARY_URL:-http://ivanx.com/a2cloud/files}/" ;; esac useExternalURL=1 [[ $A2CLOUD_NO_EXTERNAL ]] && useExternalURL= debianVersion=$(cat /etc/debian_version 2>/dev/null) isRpi= isDebian= arch= if [[ -f /usr/bin/raspi-config ]]; then isRpi=1 arch='rpi' me="Pi" fullme="Raspberry Pi" elif lsb_release -a 2>/dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then isDebian=1 uname_m="$(uname -m)" if [[ $uname_m == "i686" ]]; then arch='debian_x86' elif [[ $uname_m == "x86_64" ]]; then arch='debian_x64' fi me="computer" fullme="computer" fi debianName= if [[ $debianVersion ]]; then debianMajor=$(cut -d . -f 1 <<< $debianVersion) if [[ $debianMajor == "8" ]]; then debianName="jessie" elif [[ $debianMajor == "7" ]]; then debianName="wheezy" else debianName="unknown" fi fi if [[ -f /usr/local/etc/A2CLOUD-version ]]; then installedVersion="$(cat /usr/local/etc/A2CLOUD-version)" if [[ $installedVersion != *.*.* ]]; then installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}" fi fi echo "A2CLOUD version available: $version" echo "A2CLOUD version installed: ${installedVersion:-None}" buildA2CloudDisk= downloadBinaries=1 skipRepoUpdate= restartPrompt= autoAnswerYes= updateRasppleII= slot6= noSetGroups= while [[ $1 ]]; do if [[ $1 == "-b" ]]; then shift buildA2CloudDisk=1 elif [[ $1 == "-c" ]]; then shift downloadBinaries= elif [[ $1 == "-r" ]]; then shift skipRepoUpdate="-r" elif [[ $1 == "-s" ]]; then shift restartPrompt=1 elif [[ $1 == "-y" ]]; then shift autoAnswerYes="-y" elif [[ $1 == "-6" ]]; then shift slot6=1 elif [[ $1 == "-os" || $1 == "os" ]]; then shift updateRasppleII=1 elif [[ $1 == "-v" ]]; then shift # Version was already printed [[ $0 == "-bash" ]] && return 1 || exit 1 elif [[ $1 == "noSetGroups" ]]; then shift noSetGroups=1 elif [[ $1 ]]; then echo "options:" echo "-v: display installed and available versions, then exit" echo "-y: auto-answer yes to all prompts" echo "-r: don't update package lists" echo "-s: prompt for restart after installation" echo "-6: put blank 140K disk images in GSport slot 6" echo "-b: build A2CLOUD disks, rather than downloading premade images" echo "-c: compile non-package items, rather than downloading binaries" if [[ $isRpi ]]; then echo "-os: update Raspbian OS, A2CLOUD, A2SERVER, and Apple II Pi" fi [[ $0 == "-bash" ]] && return 1 || exit 1 fi done if [[ $updateRasppleII ]]; then echo "A2CLOUD: Updating Raspple II (takes up to an hour)..." wget -qO /tmp/raspbian-update ${scriptURL}setup/raspbian-update.txt source /tmp/raspbian-update a2cloud a2server $autoAnswerYes $skipRepoUpdate [[ $0 == "-bash" ]] && return 0 || exit 0 fi echo echo "Your $fullme will be set up for A2CLOUD, providing you" echo " with mass storage and online access for your Apple II!" echo echo "Answer yes to all prompts if you want to be able to do all the" echo " stuff mentioned on the A2CLOUD web site." echo echo "If you already have A2CLOUD installed, you will be updated to the" echo " latest version. Check out http://ivanx.com/a2cloud for details." echo echo "Full installation may take an hour or longer. Updates are usually" echo " much quicker. Type 'a2cloud-setup -h' for installation options." echo echo "Some actions will be performed as the root user." if [[ ! $autoAnswerYes ]]; then echo echo -n "Continue? " read if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then [[ $0 == "-bash" ]] && return 2 || exit 2 fi fi echo installAllFeatures= if [[ ! $autoAnswerYes ]]; then echo echo -n "Do you want to install all A2CLOUD features? " read fi [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installAllFeatures=1 if [[ $installAllFeatures ]]; then installADTPro=1 createBootDisk=1 setupSerialPortLogin=1 installCommTools=1 installArchiveTools=1 installEmulators=1 else installADTPro= echo echo -n "Install ADTPro server, for virtual drives and floppy disk transfers" if ! hash X 2>/dev/null; then echo echo -n "(the X Window System and LXDE desktop environment will be installed)" fi echo -n "? " read [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installADTPro=1 createBootDisk= installArchiveTools= newImageName= imageSize= if [[ $installADTPro ]]; then echo echo -n "Do you want to create A2CLOUD 140K and 800K boot disk images? " read if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then createBootDisk=1 installArchiveTools=1 fi if [[ ! -f /usr/local/adtpro/disks/Virtual.po || ( -f /usr/local/adtpro/adtpro.sh && -f /usr/local/adtpro/disks/Virtual.po && $(sha1sum /usr/local/adtpro/disks/Virtual.po | cut -f 1 -d ' ') == "a209a8b3a485c95c57bc691a8a58867a6c0ec628" ) ]]; then while (( 1 )); do echo echo "The default blank disk in S2,D1 will be 800K. If you want a different size," echo -n " enter it in K (larger is slower when writing; max 8192): " read if (( ${REPLY}0 >= 1400 )); then imageSize=$REPLY echo -n "Enter new image file name: " read if [[ $REPLY ]]; then reply="$REPLY" [[ $(tr [:lower:] [:upper:] <<< ${reply:(-3)}) != ".PO" ]] && reply="$REPLY.PO" if [[ ! -f /usr/local/adtpro/disks/"$reply" ]]; then newImageName="$reply" prodosVolName='0' # test ProDOS name legality while [[ ${#prodosVolName} -gt 15 || ! $(grep ^[A-Z][0-9A-Z\.]*$ <<< $prodosVolName) ]]; do echo -n "Enter new image ProDOS volume name (or return for 'UNTITLED'): " read [[ $REPLY ]] && prodosVolName="$REPLY" || prodosVolName="UNTITLED" prodosVolName=$(tr [:lower:] [:upper:] <<< $prodosVolName) done break else echo "A2CLOUD: Disk image already exists. Not creating." fi fi else break fi done fi fi setupSerialPortLogin= echo echo -n "Do you want to set up your $me for serial port login? " read [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && setupSerialPortLogin=1 installCommTools= echo echo -n "Install internet access and file transfer tools on your $me? " read [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installCommTools=1 if [[ ! $installArchiveTools ]]; then echo echo -n "Install utilities for Apple II archives and disk images? " read [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installArchiveTools=1 fi installEmulators= echo echo -n "Install Apple IIgs and IIe emulators? " read [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installEmulators=1 fi echo userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') [[ $userPw == "$(echo 'apple2' | perl -e '$_ = ; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw= [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = ; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw= if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2CLOUD-version ]]; then if [[ ! $autoAnswerYes ]]; then echo "To make A2CLOUD work smoothly, you are recommended" echo "to change your password to 'apple2'." echo echo -n "Do you want to change the password for user '$USER' to 'apple2' now? " read fi if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then echo "A2CLOUD: changing password for user '$USER' to 'apple2'..." echo "$USER:apple2" | sudo chpasswd isApple2Pw=1 fi fi thePassword="your password" [[ $isApple2Pw ]] && thePassword="'apple2'" [[ $isRaspberryPw ]] && thePassword="'raspberry'" echo echo "During this installation, enter ${thePassword}" echo "if prompted for passwords." echo if [[ ! $autoAnswerYes ]]; then echo -n "Press return to continue..." read fi origDir="$PWD" rm -rf /tmp/a2cloud-install &>/dev/null mkdir -p /tmp/a2cloud-install cd /tmp/a2cloud-install echo if [[ ! $skipRepoUpdate ]]; then echo "A2CLOUD: Updating package lists..." sudo apt-get -y update > /dev/null else echo "A2CLOUD: Not updating package lists..." fi # general commands and configuration echo "A2CLOUD: Adding udev trigger to /etc/rc.local..." grep udevadm /etc/rc.local > /dev/null || sudo sed -i 's/^exit 0$/[ -e \/dev\/ttyUSBupper ] \&\& ! [ -f \/tmp\/udev-ttyUSBupper-added ] \&\& udevadm trigger --action=change\n[ -e \/dev\/ttyUSBlower ] \&\& ! [ -f \/tmp\/udev-ttyUSBlower-added ] \&\& udevadm trigger --action=change\n\nexit 0/' /etc/rc.local echo "A2CLOUD: Setting up dopo command..." sudo wget -qO /usr/local/bin/dopo ${scriptURL}setup/dopo.txt sudo chmod ugo+x /usr/local/bin/dopo echo "A2CLOUD: Setting up cppo command..." sudo wget -qO /usr/local/bin/cppo ${scriptURL}setup/cppo.txt sudo chmod ugo+x /usr/local/bin/cppo echo "A2CLOUD: Setting up a2cloud-help..." sudo wget -qO /usr/local/etc/a2cloud-help.txt ${scriptURL}setup/a2cloud-help.txt if [[ $isRpi ]]; then sudo sed -i 's/^gsport.*$/gsport : GSport Apple IIgs emulator (or log in with user "apple2user")/' /usr/local/etc/a2cloud-help.txt fi # FIXME: We have "three" MOTD files in the A2CLOUD tree but we only use # one. The other two come from the Raspple II tree. We should clean # this up at some point. # FIXME#2: All of these MOTDs live in the A2CLOUD tree, so we'll get them from there. echo "A2CLOUD: Setting up motd..." if [[ $(grep Raspple /etc/motd) ]]; then wget -qO- "${scriptURL}setup/motd-rasppleii.txt" | sudo tee /etc/motd > /dev/null elif [[ $(grep A2SERVER /etc/motd) ]]; then wget -qO- "${scriptURL}setup/motd-vm.txt" | sudo tee /etc/motd > /dev/null else wget -qO- "${scriptURL}setup/motd.txt" | sudo tee /etc/motd > /dev/null fi if lspci 2>/dev/null | grep -q VirtualBox; then echo "A2CLOUD: Disabling VirtualBox console screen blanking..." sudo sed -i 's/^BLANK_DPMS=off/BLANK_DPMS=on/' /etc/kbd/config sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config sudo /etc/init.d/kbd restart &>/dev/null sudo /etc/init.d/console-setup restart &>/dev/null fi echo "A2CLOUD: Setting up control commands and environment variables..." sudo wget -qO /usr/local/etc/a2cloud-aliases ${scriptURL}setup/a2cloud-aliases.txt echo "A2CLOUD: Setting up login script..." sudo sed -i "s/a2cloud-aliases/a2cloudrc/" /etc/bash.bashrc sudo sed -i '/ttyUSB/d' /etc/bash.bashrc [[ ! $(grep a2cloudrc /etc/bash.bashrc) ]] && echo "source /usr/local/etc/a2cloudrc" | sudo tee -a /etc/bash.bashrc > /dev/null sudo wget -qO /usr/local/etc/a2cloudrc ${scriptURL}setup/a2cloudrc.txt source /usr/local/etc/a2cloudrc echo "A2CLOUD: Saving installer version..." echo "$version" | sudo tee /usr/local/etc/A2CLOUD-version &>/dev/null if ! dpkg-query -l avahi-daemon &>/dev/null || ! dpkg-query -l libnss-mdns &>/dev/null; then echo "A2CLOUD: Installing avahi-daemon (mDNS)..." sudo apt-get -y install avahi-daemon &>/dev/null sudo apt-get -y clean sudo sed -i 's/^\(hosts.*\)$/\1 mdns/' /etc/nsswitch.conf else echo "A2CLOUD: avahi-daemon (mDNS) is already installed." fi if [[ $installADTPro ]]; then freeSpace=$(df / | tail -1 | awk '{ print $4 }') java -version &>/dev/null if (( $? == 127 && $freeSpace < 350000 )); then echo "You do not have enough free space to install" echo "Java, which is needed for ADTPro server." if [[ $isRpi ]]; then echo "If you haven't" echo "yet expanded the file system to use the full capacity" echo "of your SD card, type \"sudo raspi-config\" and do that." else echo "Free up some space." fi echo "Then try this installer again." echo [[ $0 == "-bash" ]] && return 3 || exit 3 fi if ! hash X 2>/dev/null; then echo "A2CLOUD: Installing X Window System and LXDE..." sudo apt-get -y install xorg lxde sudo apt-get -y clean # prevent automatically running at startup # FIXME: JESSIE/RPI: Not how this is done for systemd/RPi/etc sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT="text"/' /etc/default/grub sudo update-grub else echo "A2CLOUD: X Window System and LXDE are already installed." fi if lspci 2>/dev/null | grep -q VirtualBox; then if ! grep -q default /etc/xdg/lxsession/LXDE/autostart; then echo "A2CLOUD: Setting desktop to 800x600 in VirtualBox console (no Additions)..." echo -e "\nxrandr --output default --mode 800x600" | sudo tee -a /etc/xdg/lxsession/LXDE/autostart > /dev/null else echo "A2CLOUD: Desktop already set to 800x600 in VirtualBox console (no Additions)." fi if ! grep -q VBOX0 /etc/xdg/lxsession/LXDE/autostart; then echo "A2CLOUD: Setting desktop to 800x600 in VirtualBox console (with Additions)..." echo -e "\nxrandr --output VBOX0 --mode 800x600" | sudo tee -a /etc/xdg/lxsession/LXDE/autostart > /dev/null else echo "A2CLOUD: Desktop already set to 800x600 in VirtualBox console (with Additions)." fi echo "A2CLOUD: Disabling screensaver and screen blanking in VirtualBox LXDE..." sudo sed -i 's/^\(@xscreensaver.*\)$/#\1\n\nxset s noblank\nxset s off\nxset -dpms\n/' /etc/xdg/lxsession/LXDE/autostart fi if [[ $isRpi ]]; then sudo sed -i 's/^.*VBOX0.*$//' /etc/xdg/lxsession/LXDE/autostart 2>/dev/null sudo sed -i 's/^.*VBOX0.*$//' /etc/xdg/lxsession/LXDE-pi/autostart 2>/dev/null fi # install or update java javaVersion=$(java -version 2>&1) if [[ ( $? -eq 127 ) || ( $(head -1 <<< "$javaVersion" | cut -f 2 -d '.') -lt 8 ) ]]; then echo "A2CLOUD: Installing Java (takes a while)..." if [[ $isRpi ]]; then if [[ $(apt-cache search '^oracle-java8-jdk$') ]]; then sudo apt-get -y install oracle-java8-jdk else sudo apt-get -y install oracle-java7-jdk fi sudo apt-get -y clean else # from http://www.webupd8.org/2012/06/how-to-install-oracle-java-7-in-debian.html if ! grep -q webupd8team /etc/apt/sources.list; then { echo; echo "# Oracle Java JDK"; echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main"; echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu precise main"; } | sudo tee -a /etc/apt/sources.list > /dev/null fi sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 sudo apt-get -y update echo debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections sudo apt-get -y install oracle-java8-installer sudo apt-get -y clean fi source /usr/local/etc/a2cloudrc else echo "A2CLOUD: Java is already installed." fi updateADTPro= # check if update needed if [ -f /usr/local/adtpro/lib/ADTPro-* ]; then if [[ $(ls -1 /usr/local/adtpro/lib/ADTPro-*.jar | cut -f 6 -d '/') != "ADTPro-$adtProVersion.jar" ]]; then echo echo "ADTPro server should be updated. If you have made any customizations" echo " to any of the files in /usr/local/adtpro, other than the 'disks' folder," echo " they will be lost. If you don't know what this means, then you don't" echo -n " need to worry. Update now? " read if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then updateADTPro=1 echo "A2CLOUD: removing old version of ADTPro server..." sudo pkill -f [A]DTPro sudo rm /usr/local/adtpro/disks/ADTPRO*.DSK &>/dev/null sudo rm /usr/local/adtpro/disks/ADTPRO*.PO &>/dev/null sudo rm /usr/local/adtpro/disks/VDRIVE*.DSK &>/dev/null sudo rm -r /tmp/a2cloud-install/disks &>/dev/null sudo mv /usr/local/adtpro/disks /tmp/a2cloud-install sudo rm -r /usr/local/adtpro/ac.bat \ /usr/local/adtpro/ac.sh \ /usr/local/adtpro/adtpro.bat \ /usr/local/adtpro/adtpro.cmd \ /usr/local/adtpro/ADTPro.html \ /usr/local/adtpro/adtpro.sh \ /usr/local/adtpro/lib \ /usr/local/adtpro/LICENSE \ /usr/local/adtpro/README \ &>/dev/null fi else echo "A2CLOUD: ADTPro server does not need updating." fi fi if [[ ! -f /usr/local/adtpro/adtpro.sh || ! -f /usr/local/adtpro/ADTPro.html ]]; then echo "A2CLOUD: installing ADTPro server..." sudo pkill -f [A]DTPro wget -qO /tmp/a2cloud-install/adtpro.tar.gz downloads.sourceforge.net/project/adtpro/adtpro/ADTPro-$adtProVersion/ADTPro-$adtProVersion.tar.gz sudo mkdir -p /usr/local/adtpro sudo tar --strip-components=1 -C /usr/local/adtpro -zxf /tmp/a2cloud-install/adtpro.tar.gz sudo chmod -R ugo+w /usr/local/adtpro sudo ln -s /usr/local/adtpro/lib/ADTPro*jar /usr/local/adtpro/lib/ADTPro.jar sudo ln -s /usr/local/adtpro/lib/AppleCommander/AppleCommander*ac.jar /usr/local/adtpro/lib/AppleCommander/AppleCommander-ac.jar echo "sudo /usr/local/adtpro/adtpro.sh \$@" | sudo tee /usr/local/bin/adtpro.sh > /dev/null sudo chmod ugo+x /usr/local/bin/adtpro.sh sudo usermod -a -G uucp $USER sudo usermod -a -G uucp root else echo "A2CLOUD: ADTPro server is already installed." fi if [[ ! -f /usr/local/adtpro/lib/AppleCommander/AppleCommander-1.3.5.13id-ac.jar ]]; then echo "A2CLOUD: Installing AppleCommander-1.3.5.13id..." sudo mkdir -p /usr/local/adtpro/lib/AppleCommander wget -qO /usr/local/adtpro/lib/AppleCommander/AppleCommander-1.3.5.13id-ac.jar http://downloads.sourceforge.net/project/applecommander/AppleCommander%20-%20Interim/testcase/AppleCommander-1.3.5.13id-ac.jar rm /usr/local/adtpro/lib/AppleCommander/AppleCommander-ac.jar &>/dev/null ln -s AppleCommander-1.3.5.13id-ac.jar /usr/local/adtpro/lib/AppleCommander/AppleCommander-ac.jar else echo "A2CLOUD: AppleCommander-1.3.5.13id is already installed." fi echo "A2CLOUD: Setting up customized adtpro.sh..." wget -qO /usr/local/adtpro/adtpro.sh "${scriptURL}setup/adtpro.sh.txt" sudo chmod ugo+rwx /usr/local/adtpro/adtpro.sh if [[ $updateADTPro ]]; then echo "A2CLOUD: Replacing disks folder..." sudo mv /tmp/a2cloud-install/disks/* /usr/local/adtpro/disks sudo rmdir /tmp/a2cloud-install/disks fi if [[ ! -f /usr/lib/jni/librxtxSerial.so ]]; then echo "A2CLOUD: Installing serial port libraries..." sudo apt-get -y install librxtx-java sudo apt-get -y clean else echo "A2CLOUD: Serial port libraries are already installed." fi [[ ! -f /usr/lib/RXTXcomm.jar ]] && sudo ln -s /usr/share/java/RXTXcomm.jar /usr/lib &>/dev/null [[ ! -d /usr/local/adtpro/lib/rxtx/rxtx-2.2pre2-local/arm ]] && ln -s /usr/lib/jni /usr/local/adtpro/lib/rxtx/rxtx-2.2pre2-local/arm &>/dev/null if ! hash xvfb-run 2>/dev/null; then echo "A2CLOUD: Installing xvfb for headless operation..." sudo apt-get -y install xvfb sudo apt-get -y clean else echo "A2CLOUD: xvfb is already installed." fi if hash afpd 2>/dev/null; then # A2SERVER/netatalk installed if [[ ! -d /media/A2SHARED/ADTDISKS || ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then echo "A2CLOUD: Setting up /usr/local/adtpro/disks for Apple file sharing..." if [[ ! -d /media/A2SHARED/ADTDISKS ]]; then ln -s /usr/local/adtpro/disks /media/A2SHARED/ADTDISKS 2>/dev/null fi if [[ ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then sudo sed -i 's@^# End of File@/media/A2SHARED/ADTDISKS ADTDISKS ea:ad\n\n# End of File@' /usr/local/etc/netatalk/AppleVolumes.default fi sudo /etc/init.d/netatalk restart else echo "A2CLOUD: /usr/local/adtpro/disks is already set up for Apple file sharing." fi if grep -q A2SHARED /etc/samba/smb.conf 2>/dev/null; then # SMB already enabled by A2SERVER if grep -q ADTDISKS /etc/samba/smb.conf 2>/dev/null; then echo "A2CLOUD: /usr/local/adtpro/disks is already set up for Windows file sharing." else echo "A2CLOUD: Setting up /usr/local/adtpro/disks for Windows file sharing..." echo "[ADTDISKS]" | sudo tee -a /etc/samba/smb.conf > /dev/null echo " path = /media/A2SHARED/ADTDISKS" | sudo tee -a /etc/samba/smb.conf > /dev/null echo " browsable = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null echo " guest ok = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null echo " read only = no" | sudo tee -a /etc/samba/smb.conf > /dev/null echo " create mask = 0666" | sudo tee -a /etc/samba/smb.conf > /dev/null echo " force user = $(whoami)" | sudo tee -a /etc/samba/smb.conf > /dev/null fi else echo "A2CLOUD: Windows file sharing not in use." fi fi echo "A2CLOUD: Setting up adtpro-start command..." sudo wget -qO /usr/local/bin/adtpro-start ${scriptURL}setup/adtpro-start.txt sudo chmod ugo+x /usr/local/bin/adtpro-start echo "A2CLOUD: Setting up vsd1/vsd2 commands..." sudo wget -qO /usr/local/bin/vsd ${scriptURL}setup/vsd.txt sudo chmod ugo+x /usr/local/bin/vsd echo "A2CLOUD: Setting up acmd command..." sudo wget -qO /usr/local/bin/acmd ${scriptURL}setup/acmd.txt sudo chmod ugo+x /usr/local/bin/acmd echo "A2CLOUD: Setting up mkpo command..." sudo wget -qO /usr/local/bin/mkpo ${scriptURL}setup/mkpo.txt sudo chmod ugo+x /usr/local/bin/mkpo echo "A2CLOUD: Setting up dos2pro command..." sudo wget -qO /usr/local/bin/dos2pro ${scriptURL}setup/dos2pro.txt sudo chmod ugo+x /usr/local/bin/dos2pro fi if hash X 2>/dev/null; then if dpkg-query -l xrdp; then echo "A2CLOUD: Installing xrdp/tightvncserver..." sudo apt-get -y install xrdp sudo apt-get -y clean else echo "A2CLOUD: xrdp/tightvncserver is already installed." fi else echo "A2CLOUD: X11 not found; not installing xrdp/tightvncserver." fi if [[ $setupSerialPortLogin ]]; then echo "A2CLOUD: Setting GPIO serial login to 4800 bps, and disabling..." # set console port login to 4800 bps (using RPi console cable) and comment it out sudo sed -i 's/^\(T.*\)ttyAMA0 .* /#\1ttyAMA0 4800 /' /etc/inittab sudo sed -i 's/ttyAMA0,[0-9]*/ttyAMA0,4800/g' /boot/cmdline.txt 2>/dev/null if ! hash screen 2>/dev/null; then echo "A2CLOUD: Installing Screen for multiple terminals..." sudo apt-get -y install screen sudo apt-get -y clean else echo "A2CLOUD: Screen is already installed." fi echo "A2CLOUD: Disabling Screen welcome message..." sudo sed -i 's/^#startup_message/startup_message/' /etc/screenrc # use 8-bit (non-Unicode) character set for proper emulation in Apple II term programs IFS='' defaultLang=$(grep ^LANG= /etc/default/locale | cut -f 2 -d '=') langLatin1=${defaultLang%%.*} if [[ ! $(grep "^$langLatin1.ISO" /usr/share/i18n/SUPPORTED) ]]; then langLatin1="en_US" fi if [[ $(cat /usr/local/etc/a2cloud-lang 2>/dev/null) != $langLatin1 ]]; then echo "A2CLOUD: Setting serial port login to use 8-bit character set..." if [[ ! $(grep "^$langLatin1.ISO" /etc/locale.gen) ]]; then echo "A2CLOUD: Generating locales..." locs=$(IFS='' grep "^[^#]" /etc/locale.gen | while read -r thisLoc; do echo -n "$thisLoc, " ; done) locISO=$(grep "$langLatin1.ISO" /usr/share/i18n/SUPPORTED | sort | head -1) echo "locales locales/locales_to_be_generated multiselect $locs$locISO" | sudo debconf-set-selections sudo rm /etc/locale.gen &>/dev/null sudo dpkg-reconfigure -f noninteractive locales else echo "A2CLOUD: Locales have already been generated." fi # set LANG to ISO-8859 (8-bit) character set on TTY login echo "${locISO%% *}" | sudo tee /usr/local/etc/a2cloud-lang > /dev/null source /usr/local/etc/a2cloudrc else echo "A2CLOUD: Serial port login is already using 8-bit character set." fi echo "A2CLOUD: Setting up baud command..." sudo wget -qO /usr/local/bin/baud ${scriptURL}setup/baud.txt sudo chmod ugo+x /usr/local/bin/baud echo "A2CLOUD: Setting up term command..." sudo wget -qO /usr/local/bin/term ${scriptURL}setup/term.txt sudo chmod ugo+x /usr/local/bin/term echo "A2CLOUD: Setting up usbgetty command..." sudo wget -qO /usr/local/sbin/usbgetty ${scriptURL}setup/usbgetty.txt sudo chmod ugo+x /usr/local/sbin/usbgetty echo "A2CLOUD: Removing ttyUSB0 shell login..." sudo sed -i "s/^\([^#].*ttyUSB0.*\)$//" /etc/inittab if [[ ! $(grep -e '-scanttyUSB' /etc/inittab) ]]; then echo "A2CLOUD: Adding USB port shell login at 4800 bps..." echo -e "\n\n#for USB-to-serial adapter\nT1:23:respawn:/usr/local/sbin/usbgetty -h -L -scanttyUSB 4800 vt100" | sudo tee -a /etc/inittab > /dev/null sudo init q sudo pkill -f "[g]etty.*ttyUSB" else echo "A2CLOUD: USB port shell login already added." fi fi echo "A2CLOUD: Setting up USB port serial adapter handler..." sudo wget -qO /usr/local/sbin/ttyusbhandler ${scriptURL}setup/ttyusbhandler.txt sudo chmod ugo+x /usr/local/sbin/ttyusbhandler if [[ ! -f /etc/udev/rules.d/50-usb.rules ]]; then echo "A2CLOUD: Creating device rules for USB ports..." udevLines= if [[ $isRpi ]]; then # assign ttyUSBupper, or ttyUSBupper_hubXX, for shell usb-to-serial adapter # assign ttyUSBlower, or ttyUSBlower_hubXX, for ADTPro usb-to-serial adapter # (A/A+ direct attach is always ttyUSBlower; # hub attached to A/A+ will be ttyUSBupper on port 2, and ttyUSBlower on port 3) udevLines+='KERNEL=="ttyUSB*", KERNELS=="1-1:1.0", SYMLINK+="ttyUSBlower", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBlower"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*1-1:1.0*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBlower"\n' udevLines+='KERNEL=="ttyUSB*", KERNELS=="1-1.2:1.0", SYMLINK+="ttyUSBupper", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBupper"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*1-1.2:1.0*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBupper"\n' udevLines+='KERNEL=="ttyUSB*", KERNELS=="1-1.3:1.0", SYMLINK+="ttyUSBlower", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBlower"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*1-1.3:1.0*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBlower"\n' for i in {1..25}; do ii=$(printf %02d $i) udevLines+='KERNEL=="ttyUSB*", KERNELS=="1-1.2.'$i':1.0", SYMLINK+="ttyUSBupper_hub'$ii'", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBupper_hub'$ii'"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*1-1.2.'$i':1.0*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBupper_hub'$ii'"\n' udevLines+='KERNEL=="ttyUSB*", KERNELS=="1-1.3.'$i':1.0", SYMLINK+="ttyUSBlower_hub'$ii'", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBlower_hub'$ii'"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*1-1.3.'$i':1.0*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBlower_hub'$ii'"\n' done else # on non-Pi installations, assign ttyUSBupper to ttyUSB0 and ttyUSBlower to ttyUSB1 udevLines+='KERNEL=="ttyUSB0", SYMLINK+="ttyUSBupper", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBupper"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*ttyUSB0*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBupper"\n' udevLines+='KERNEL=="ttyUSB1", SYMLINK+="ttyUSBlower", RUN+="/usr/local/sbin/ttyusbhandler add ttyUSBlower"\n' udevLines+='ACTION=="remove", ENV{DEVPATH}=="*ttyUSB1*", RUN+="/usr/local/sbin/ttyusbhandler remove ttyUSBlower"\n' fi echo -e "$udevLines" | sudo tee /etc/udev/rules.d/50-usb.rules > /dev/null else echo "A2CLOUD: Device rules for USB ports already exist." fi if [[ $installCommTools ]]; then if ! hash curl 2>/dev/null; then echo "A2CLOUD: Installing curl..." sudo apt-get -y install curl sudo apt-get -y clean else echo "A2CLOUD: curl is already installed." fi if ! hash sz 2>/dev/null; then echo "A2CLOUD: Installing rzsz for X/Y/Zmodem transfers..." sudo apt-get -y install lrzsz sudo apt-get -y clean else echo "A2CLOUD: rzsz is already installed." fi if ! hash ftp 2>/dev/null; then echo "A2CLOUD: Installing ftp..." sudo apt-get -y install ftp sudo apt-get -y clean else echo "A2CLOUD: ftp is already installed." fi if ! hash cftp 2>/dev/null; then echo "A2CLOUD: Installing cftp..." cd /tmp/a2cloud-install if [[ $downloadBinaries ]]; then wget -qO- "${binaryURL}precompiled/cftp-${arch}_${debianName}.tgz" | sudo tar Pzx fi if ! hash cftp 2>/dev/null; then sudo apt-get -y install build-essential sudo apt-get -y install ncurses-dev sudo apt-get -y clean rm -rf /tmp/a2cloud-install/cftp* &>/dev/null mkdir -p /tmp/a2cloud-install/cftp cd /tmp/a2cloud-install/cftp wget -q -O cftp.tgz http://nih.at/cftp/cftp-0.12.tar.gz tar zxf cftp.tgz cd cftp-0.12 ./configure make sudo make install cd /tmp/a2cloud-install rm -rf cftp fi else echo "A2CLOUD: cftp is already installed." fi if ! hash lynx 2>/dev/null; then echo "A2CLOUD: Installing lynx..." sudo apt-get -y install lynx sudo apt-get -y clean else echo "A2CLOUD: lynx is already installed." fi if ! hash links 2>/dev/null; then echo "A2CLOUD: Installing links..." sudo apt-get -y --force-yes install links sudo apt-get -y clean else echo "A2CLOUD: links is already installed." fi sudo wget -qO /usr/local/bin/a2news ${scriptURL}setup/a2news.txt sudo chmod ugo+x /usr/local/bin/a2news if ! hash tin 2>/dev/null; then echo "A2CLOUD: Installing a2news/tin..." sudo apt-get -y install tin sudo apt-get -y clean else echo "A2CLOUD: a2news/tin is already installed." fi # have exim4 use IPv4 only to prevent log errors (IPv6 is off by default in Raspbian) if [[ $(grep ' ; ::1' /etc/exim4/update-exim4.conf.conf) ]]; then echo "A2CLOUD: Setting exim4 to use only IPv4 to prevent startup error messages..." sudo sed -i 's/ ; ::1//' /etc/exim4/update-exim4.conf.conf sudo update-exim4.conf sudo rm /var/log/exim4/mainlog /var/log/exim4/paniclog &>/dev/null fi # restore exim4 log directory if occupied by a file put there by earlier A2CLOUD versions if [[ -f /var/log/exim4 ]]; then echo "A2CLOUD: Restoring exim4 log directory..." sudo rm /var/log/exim4 sudo mkdir /var/log/exim4 sudo chown Debian-exim:adm /var/log/exim4 sudo chmod 2750 /var/log/exim4 fi sudo wget -qO /usr/local/bin/a2chat ${scriptURL}setup/a2chat.txt sudo chmod ugo+x /usr/local/bin/a2chat if ! hash irssi 2>/dev/null; then echo "A2CLOUD: Installing a2chat/irssi..." sudo apt-get -y install irssi sudo apt-get -y clean else echo "A2CLOUD: a2chat/irssi is already installed." fi if ! hash telnet 2>/dev/null; then echo "A2CLOUD: Installing telnet..." sudo apt-get -y install telnet sudo apt-get -y clean else echo "A2CLOUD: telnet is already installed." fi # Do we need to check for the readline module here as well? #if [[ ( ! -f /usr/bin/ttytter && ! -f /usr/local/bin/ttytter ) || ! -f "/usr/local/share/perl/5.14.2/Term/ReadLine/TTYtter.pm" ]]; then if ! hash ttyter 2>/dev/null; then echo "A2CLOUD: Installing TTYtter..." sudo wget -qO /usr/local/bin/ttytter http://www.floodgap.com/software/ttytter/dist2/2.1.00.txt sudo chmod ugo+x /usr/local/bin/ttytter perlVersion=$(perl -e 'print $^V' | cut -c 2-) if [[ ! -f "/usr/local/share/perl/$perlVersion/Term/ReadLine/TTYtter.pm" ]]; then echo "A2CLOUD: Installing TTYtter readline module..." if [[ $downloadBinaries && $perlVersion == "5.14.2" ]]; then wget -qO- "${binaryURL}precompiled/ttytter_readline-${arch}_${debianName}.tgz" | sudo tar Pzx fi if [[ ! -f "/usr/local/share/perl/$perlVersion/Term/ReadLine/TTYtter.pm" ]]; then if [[ ! -f "/usr/local/lib/perl/$perlVersion/Term/ReadKey.pm" ]]; then cd /tmp/a2cloud-install wget -qO TermReadKey-2.31.tar.gz http://www.cpan.org/authors/id/J/JS/JSTOWE/TermReadKey-2.31.tar.gz tar zxf TermReadKey-2.31.tar.gz cd TermReadKey-2.31 perl Makefile.PL &>/dev/null make &>/dev/null sudo make install &>/dev/null cd /tmp/a2cloud-install rm -rf TermReadKey-2.31 fi cd /tmp/a2cloud-install wget -qO Term-ReadLine-TTYtter-1.4.tar.gz http://www.cpan.org/authors/id/C/CK/CKAISER/Term-ReadLine-TTYtter-1.4.tar.gz tar zxf Term-ReadLine-TTYtter-1.4.tar.gz cd Term-ReadLine-TTYtter-1.4 perl Makefile.PL &>/dev/null make &>/dev/null sudo make install &>/dev/null cd /tmp/a2cloud-install rm -rf Term-ReadLine-TTYtter-1.4 fi else echo "A2CLOUD: TTYtter readline module is already installed." fi else echo "A2CLOUD: TTYtter is already installed." fi fi if [[ $installEmulators ]]; then ### Emulators: GSport if ! hash gsport 2>/dev/null; then # FIXME: This is a _TERRIBLE_ name/place for this... gsportConfigFile='/usr/local/lib/config.txt' echo "A2CLOUD: Installing GSport..." cd /tmp/a2cloud-install if [[ $downloadBinaries ]]; then ### Emulators: GSport: Install pre-built binaries sudo apt-get -y install libpcap0.8 &>/dev/null sudo apt-get -y clean wget -qO- "${binaryURL}precompiled/gsport-${arch}_${debianName}.tgz" | sudo tar Pzx 2>/dev/null fi if ! hash gsport 2>/dev/null; then ### Emulators: GSport: Install from source echo "A2CLOUD: Building GSport from source..." sudo apt-get -y install build-essential &>/dev/null sudo apt-get -y install libx11-dev libxext-dev xfonts-base libpcap0.8-dev &>/dev/null sudo apt-get -y clean > /dev/null mkdir -p /tmp/a2cloud-install/gsport cd /tmp/a2cloud-install/gsport wget -q -O gsport.tgz http://downloads.sourceforge.net/project/gsport/GSport-0.31/gsport_0.31.tar.gz tar zxf gsport.tgz cd gsport*/src rm vars 2>/dev/null ln -s vars_x86linux vars make &>/dev/null gcc -o ../to_pro to_pro.c &>/dev/null gcc -o ../partls partls.c &>/dev/null sudo cp -P ../gsportx ../to_pro ../partls /usr/local/bin sudo cp ../config.txt /usr/local/lib sudo chmod ugo+w "$gsportConfigFile" make clean &>/dev/null rm vars cp vars_fbrpilinux vars sed -i 's/-march=armv6/-march=i686/' vars make &>/dev/null sudo cp -P ../gsportfb /usr/local/bin cd /usr/local/lib sudo ln -s config.txt gsport_config.txt 2>/dev/null cd /tmp/a2cloud-install rm -rf gsport fi if [[ $slot6 ]]; then ### Emulators: GSport: Place blank disk images in slot 6 echo "A2CLOUD: Putting blank disks in GSport slot 6..." sudo sed -i 's@^s6d1.*$@s6d1 = /usr/local/share/gsdisks/slot6drive1.po@' "$gsportConfigFile" sudo sed -i 's@^s6d2.*$@s6d2 = /usr/local/share/gsdisks/slot6drive2.po@' "$gsportConfigFile" if [[ ! -f /usr/local/share/gsdisks/slot6drive1.po || ! -f /usr/local/share/gsdisks/slot6drive2.po ]]; then wget -qO- "${binaryURL}slot6.tgz" | sudo tar Pzx 2>/dev/null fi fi if ! grep -q '^g_appletalk_turbo' "$gsportConfigFile"; then ### Emulators: GSport: Enable AppleTalk Turbo support if grep -q 'bram1[00]' "$gsportConfigFile"; then sudo sed -i 's/^\(bram1\[00\]\)/g_appletalk_turbo = 1\n\n\1/' "$gsportConfigFile" else echo -e '\ng_appletalk_turbo = 1' | sudo tee -a "$gsportConfigFile" > /dev/null fi fi sudo sed -i 's/^g_appletalk_turbo = 0/g_appletalk_turbo = 1/' "$gsportConfigFile" if ! grep -q 'g_ethernet[^_]' "$gsportConfigFile"; then ### Emulators: GSport: Enable Uthernet emulation if grep -q 'bram1[00]' "$gsportConfigFile"; then sudo sed -i 's/^\(bram1\[00\]\)/g_ethernet = 1\n\n\1/' "$gsportConfigFile" else echo -e '\ng_ethernet = 1' | sudo tee -a "$gsportConfigFile" > /dev/null fi fi sudo sed -i 's/g_ethernet = 0/g_ethernet = 1/' "$gsportConfigFile" ### Emulators: GSport: Setup groups and wrapper scripts echo "A2CLOUD: Updating GSport launch and setup files..." sudo addgroup gsport &>/dev/null sudo chgrp gsport /usr/local/bin/gsportfb sudo chmod u+s /usr/local/bin/gsportfb sudo chgrp gsport /usr/local/bin/gsportx sudo chmod u+s /usr/local/bin/gsportx sudo wget -qO /usr/local/bin/gsport ${scriptURL}setup/gsport.txt sudo chmod ugo+x /usr/local/bin/gsport sudo wget -qO /usr/local/bin/gsport-setup ${scriptURL}setup/gsport-setup-shell.txt sudo chmod ugo+x /usr/local/bin/gsport-setup else echo "A2CLOUD: GSport is already installed." fi ### Emulators: LinApple if ! hash linapple 2>/dev/null; then echo "A2CLOUD: Installing LinApple..." cd /tmp/a2cloud-install if [[ $downloadBinaries ]]; then ### Emulators: LinApple: Install pre-built binaries wget -qO- "${binaryURL}linapple-${arch}_${debianName}.tgz" | sudo tar Pzx fi if ! hash linapple 2>/dev/null; then ### Emulators: LinApple: Install from source sudo apt-get -y install build-essential sudo apt-get -y install libsdl1.2-dev libcurl4-openssl-dev zlib1g-dev libzip-dev sudo apt-get -y clean rm -rf /tmp/a2cloud-install/linapple* &>/dev/null mkdir -p /tmp/a2cloud-install/linapple cd /tmp/a2cloud-install/linapple wget -q -O linapple.tar.bz2 http://downloads.sourceforge.net/project/linapple/linapple/linapple-2a/linapple-src_2a.tar.bz2 tar jxf linapple.tar.bz2 cd linapple-src_2a/src # doesn't compile with gcc 4.7, so use older version if (( $(g++ --version | head -1 | rev | cut -f 1 -d ' ' | rev | tr -d '.') >= 470 )); then sudo apt-get -y install g++-4.6 sudo apt-get -y clean sed -i 's@CXX ?= c++@CXX = /usr/bin/g++-4.6@' Makefile fi make sudo make install cd /tmp/a2cloud-install rm -rf linapple fi else echo "A2CLOUD: LinApple is already installed." fi echo "A2CLOUD: Updating LinApple launch file..." sudo wget -qO /usr/local/bin/linapple ${scriptURL}setup/linapple.txt sudo chmod ugo+x /usr/local/bin/linapple ### Emulators: Set Groups sudo usermod -a -G audio,video,netdev,fuse,gsport,plugdev $USER &>/dev/null [[ ! $noSetGroups ]] && { groups | grep -q 'gsport' || exec sudo su -l $USER; } fi if [[ $installArchiveTools ]]; then if ! hash nulib2 2>/dev/null; then echo "A2CLOUD: Installing nulib2..." cd /tmp/a2cloud-install if [[ $downloadBinaries ]]; then wget -qO- "${binaryURL}precompiled/nulib2-${arch}_${debianName}.tgz" | sudo tar Pzx fi if ! hash nulib2 2>/dev/null; then sudo apt-get -y install build-essential sudo apt-get -y install zlib1g-dev sudo apt-get -y clean # install nulib2 rm -rf nulib &>/dev/null mkdir -p nulib cd nulib wget -qO nulib.tgz http://web.archive.org/web/20131031160750/http://www.nulib.com/downloads/nulibdist.tar.gz tar zxf nulib.tgz cd nufxlib* ./configure make sudo make install cd ../nulib2* ./configure make sudo make install cd /tmp/a2cloud-install rm -rf nulib fi else echo "A2CLOUD: nulib2 is already installed." fi if ! hash sciibin 2>/dev/null; then echo "A2CLOUD: Installing sciibin, unblu, unbit, unexec, usq..." sudo apt-get -y install build-essential sudo apt-get -y clean rm -rf undoit &>/dev/null mkdir -p undoit cd undoit wget -q http://web.archive.org/web/20110619163030/http://fadden.com/dl-apple2/undoit.zip unzip undoit.zip make sudo mv sciibin unbit unblu unexec usq /usr/local/bin cd /tmp/a2cloud-install rm -rf undoit else echo "A2CLOUD: sciibin, unblu, unbit, unexec, usq are already installed." fi echo "A2CLOUD: Setting up shk2image command..." sudo wget -qO /usr/local/bin/shk2image ${scriptURL}setup/shk2image.txt sudo chmod ugo+x /usr/local/bin/shk2image # download and install The Unarchiver, for expanding apple.com disk images # http://wakaba.c3.cx/s/apps/unarchiver.html if ! hash unar 2>/dev/null; then echo "A2CLOUD: Installing The Unarchiver..." # jessie and later: Just use the unar package if [[ $debianMajor -ge 8 ]]; then sudo apt-get -y install unar sudo apt-get clean fi if ! hash unar 2>/dev/null; then if [[ $downloadBinaries && "$(apt-cache search '^libgnustep-base1.22$')" ]]; then # Dependencies: for unar sudo apt-get -y install libgnustep-base1.22 sudo apt-get clean wget -qO- "${binaryURL}precompiled/unar-${arch}_${debianName}.tgz" | sudo tar Pzx &>/dev/null fi # If all else fails, compile from source. if ! hash unar 2>/dev/null; then # Dependencies: build-deps for unar sudo apt-get -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip sudo apt-get clean rm -rf /tmp/unar &>/dev/null mkdir /tmp/unar cd /tmp/unar if [[ $useExternalURL ]]; then wget -O unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip unzip -o unar-1.8.1.zip &>/dev/null fi if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob wget -O unar-1.8.1.zip ${binaryURL}external/source/unar-1.8.1.zip unzip -o unar-1.8.1.zip &>/dev/null fi cd *Unarchiver*/XADMaster make -f Makefile.linux sudo mv lsar unar /usr/local/bin cd ../Extra sudo mkdir -p /usr/local/man/man1 sudo mv lsar.1 unar.1 /usr/local/man/man1 cd rm -rf /tmp/unar fi sudo mandb &>/dev/null fi else echo "A2CLOUD: The Unarchiver has already been installed." fi fi # add shortcuts to LXDE desktop and menu if hash X 2>/dev/null; then [[ -d /etc/xdg/lxsession/LXDE-pi ]] && lxde="lxde-pi" || lxde="lxde" echo "A2CLOUD: Creating LXDE desktop and menu shortcuts..." # remove auto-open Terminal window from pre-1.8.0 echo "A2CLOUD: removing auto-open LXDE terminal window (if present)..." sudo rm /etc/xdg/autostart/lxterminal.desktop 2>/dev/null # create "AppleII" category mkdir -p ~/.config/menus if [[ ! -f ~/.config/menus/${lxde}-applications.menu ]]; then mkdir -p ~/.config/menus echo -e "\n\n A2CLOUD menu extension\n /etc/xdg/menus/${lxde}-applications.menu\n \n Apple II\n lxde-appleii.directory\n \n AppleII\n \n \n\n" > ~/.config/menus/${lxde}-applications.menu else grep -q AppleII ~/.config/menus/${lxde}-applications.menu || echo "A2CLOUD: LXDE child category file exists, not creating Apple II category." fi # create "Apple II" menu entry sudo mkdir -p /usr/local/share/desktop-directories echo -e "[Desktop Entry]\nName=Apple II\nComment=Programs and utilities related to the Apple II\nIcon=/usr/local/linapple/icon.bmp\nType=Directory\n" | sudo tee /usr/local/share/desktop-directories/lxde-appleii.directory > /dev/null # create menu and desktop shortcuts sudo mkdir -p /usr/local/share/applications # create user desktop items folder mkdir -p ~/Desktop # GSport: GSPORT_PATH="$(command -v gsport)" if [ "$GSPORT_PATH" != "" ]; then echo -e "[Desktop Entry]\nName=GSport\nComment=Apple IIgs Emulator\nExec=lxterminal -e $GSPORT_PATH\nIcon=/usr/local/share/gsport32.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/local/share/applications/gsport.desktop > ~/Desktop/gsport.desktop fi if [[ ! -f /usr/local/share/gsport32.ico ]]; then sudo wget -qO /usr/local/share/gsport32.ico "${binaryURL}gsport32.ico" fi # LinApple: LINAPPLE_PATH="$(command -v linapple)" if [ "LINAPPLE_PATH" != "" ]; then echo -e "[Desktop Entry]\nName=LinApple\nComment=Apple IIe Emulator\nExec=lxterminal -e $LINAPPLE_PATH\nIcon=/usr/local/linapple/icon.bmp\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/local/share/applications/linapple.desktop > ~/Desktop/linapple.desktop fi # ADTPro Server: ADTPRO_PATH="$(command -v adtpro.sh)" if [ "ADTPRO_PATH" != "" ]; then echo -e "[Desktop Entry]\nName=ADTPro Server\nComment=Floppy Transfer Utility\nExec=$ADTPRO_PATH\nIcon=/usr/local/adtpro/lib/ADTPro.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/local/share/applications/adtproserver.desktop > ~/Desktop/adtproserver.desktop fi # LXTerminal: if [[ ! $(grep lxterminal.desktop /etc/xdg/lxpanel/profile/LXDE-pi/panels/panel 2>/dev/null) && ! -f ~/Desktop/lxterminal.desktop ]]; then cp /usr/share/applications/lxterminal.desktop ~/Desktop/lxterminal.desktop fi # prevent PolicyKit error on GUI startup sudo sed -i 's/^NotShowIn=GNOME;KDE;\?$/NotShowIn=GNOME;KDE;LXDE/' /etc/xdg/autostart/lxpolkit.desktop 2>/dev/null sed -i 's/^NotShowIn=GNOME;KDE;\?$/NotShowIn=GNOME;KDE;LXDE/' /home/$USER/.config/autostart/lxpolkit.desktop 2>/dev/null fi # create A2CLOUD disk if [[ $updateADTPro || $createBootDisk ]] && hash acmd 2>/dev/null; then a2CloudDisk=/usr/local/adtpro/disks/A2CLOUD.PO else a2CloudDisk= fi if [[ $a2CloudDisk ]]; then echo echo "A2CLOUD: Preparing A2CLOUD disk images..." cd /tmp/a2cloud-install a2CloudDisk140=${a2CloudDisk%%.*}.DSK if [[ ! -f $a2CloudDisk && ! -f $a2CloudDisk140 ]]; then makeA2CloudDisk=1 else [[ -f $a2CloudDisk ]] && echo "A2CLOUD: $a2CloudDisk already exists." [[ -f $a2CloudDisk140 ]] && echo "A2CLOUD: $a2CloudDisk140 already exists." echo " If you want a fresh copy, please move or delete as needed." makeA2CloudDisk= fi if [[ ! $makeA2CloudDisk ]]; then # not getting/building disks a2CloudDiskUpdated= if [[ $updateADTPro && -f "$a2CloudDisk" ]]; then # does existing 800K disk need updating? sudo pkill -f [A]DTPro echo "A2CLOUD: Updating ADTPro and VDrive on 800K A2CLOUD disk..." acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VEDRIVE - | acmd -p "$a2CloudDisk" VEDRIVE SYS acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPROAUD - | acmd -p "$a2CloudDisk" ADTPROAUD SYS acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPROETH - | acmd -p "$a2CloudDisk" ADTPROETH SYS acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO.BIN - | acmd -p "$a2CloudDisk" ADTPRO.BIN BIN \$0800 acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPROAUD.BIN - | acmd -p "$a2CloudDisk" ADTPROAUD.BIN SYS \$0800 acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPROETH.BIN - | acmd -p "$a2CloudDisk" ADTPROETH.BIN SYS \$0800 acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VEDRIVE.CONFIG - | acmd -p "$a2CloudDisk" VEDRIVE.CONFIG BAS acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO - | acmd -p "$a2CloudDisk" ADTPRO SYS acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VSDRIVE - | acmd -p "$a2CloudDisk" VSDRIVE SYS acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VSDRIVE.LOW - | acmd -p "$a2CloudDisk" VSDRIVE.LOW SYS a2CloudDiskUpdated=1 fi if [[ $updateADTPro && -f "$a2CloudDisk140" ]]; then # does existing 140K disk need updating? sudo pkill -f [A]DTPro echo "A2CLOUD: Updating ADTPro and VDrive on 140K A2CLOUD disk..." acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO.BIN - | acmd -p "$a2CloudDisk140" ADTPRO.BIN BIN \$0800 acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO - | acmd -p "$a2CloudDisk140" ADTPRO SYS acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VSDRIVE - | acmd -p "$a2CloudDisk140" VSDRIVE SYS acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VSDRIVE.LOW - | acmd -p "$a2CloudDisk140" VSDRIVE.LOW SYS a2CloudDiskUpdated=1 fi if [[ $a2CloudDiskUpdated ]]; then echo echo "Your A2CLOUD boot disk images have been updated. You may want" echo " to update your boot floppy with their current contents using ADTPro." fi echo else # building or downloading disks sudo pkill -f [A]DTPro if [[ ! $buildA2CloudDisk ]]; then echo "A2CLOUD: Downloading 800K disk image..." wget -qO $a2CloudDisk "${binaryURL}A2CLOUD.PO" echo "A2CLOUD: Downloading 140K disk image..." wget -qO $a2CloudDisk140 "${binaryURL}A2CLOUD.DSK" fi # build if we don't have a disk image # (because download failed or -b argument was used) if [[ ! -f $a2CloudDisk || ( $(wc -c $a2CloudDisk | cut -f 1 -d ' ') != "819200" ) ]]; then # start with a disk image echo "A2CLOUD: Creating 800K disk image..." cp /usr/local/adtpro/disks/ADTPRO-*PO $a2CloudDisk acmd -n $a2CloudDisk A2CLOUD # ADTPro echo "A2CLOUD: Preparing ADTPro..." acmd -d "$a2CloudDisk" BASIC acmd -d "$a2CloudDisk" STARTUP.SYSTEM acmd -d "$a2CloudDisk" ADTPRO gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/" gsosBackupURL="http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_IIGS_System_6.0.1%2F" # start from ADTPro distribution image and replace BASIC.SYSTEM 1.4.1 with 1.5 wget --max-redirect 0 -qO Disk_3_of_7-SystemTools1.sea.bin ${gsosURL}Disk_3_of_7-SystemTools1.sea.bin if (( $? != 0 )); then wget -qO Disk_3_of_7-SystemTools1.sea.bin ${gsosBackupURL}Disk_3_of_7-SystemTools1.sea.bin fi unar -k skip Disk_3_of_7-SystemTools1.sea.bin &>/dev/null mv 'Disk 3 of 7-SystemTools1.sea' SystemTools1.dc42 acmd -g SystemTools1.dc42 BASIC.SYSTEM - | acmd -p "$a2CloudDisk" BASIC.SYSTEM SYS # use our startup program wget -qO- "${binaryURL}STARTUP.BAS" | acmd -p "$a2CloudDisk" STARTUP BAS # VEDRIVE echo "A2CLOUD: Copying VEDRIVE..." acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VEDRIVE - | acmd -p "$a2CloudDisk" VEDRIVE SYS acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VEDRIVE.CONFIG - | acmd -p "$a2CloudDisk" VEDRIVE.CONFIG BAS sysutilsURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_II_Supplemental/" sysutilsBackupURL="http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_II_Supplemental%2F" # Apple System Utilities 3.1 support files if hash unar 2>/dev/null; then echo "A2CLOUD: Downloading and copying System Utilities support files..." cd /tmp/a2cloud-install wget --max-redirect 0 -qO Apple_II_System_Disk_3.2.sea.bin ${sysutilsURL}Apple_II_System_Disk_3.2.sea.bin if (( $? != 0 )); then wget -qO Apple_II_System_Disk_3.2.sea.bin ${sysutilsBackupURL}Apple_II_System_Disk_3.2.sea.bin fi unar -k skip Apple_II_System_Disk_3.2.sea.bin &>/dev/null dd if='Apple II System Disk 3.2.sea' of=A2SYSDISK32.PO bs=1 skip=84 count=819200 2>/dev/null acmd -g A2SYSDISK32.PO UTIL.0 - | acmd -p "$a2CloudDisk" UTIL.0 BIN \$0900 acmd -g A2SYSDISK32.PO UTIL.1 - | acmd -p "$a2CloudDisk" UTIL.1 BIN \$0E00 acmd -g A2SYSDISK32.PO UTIL.2 - | acmd -p "$a2CloudDisk" UTIL.2 BIN \$B400 else echo "A2CLOUD: unar is not available; not installing System Utilities support files." fi # ProTERM echo "A2CLOUD: Downloading ProTERM..." wget --user-agent="Mozilla/5.0 (wget_A2CLOUD; rv:1.13.4) Gecko/20100101 Firefox/4.0.1" -qO /tmp/a2cloud-install/pt31.shk http://lostclassics.apple2.info/download/InTrec/PT31A2GM2K9.SHK mkdir -p /tmp/a2cloud-install/pt31 cd /tmp/a2cloud-install/pt31 nulib2 -xse ../pt31.shk > /dev/null # IIc slot 1 patch for ProTERM from Hugh Hood echo "A2CLOUD: Patching ProTERM for IIc printer port use..." echo -n -e "\x41\x70\x70\x6C\x65\x20\x49\x49\x63\x2F\x49\x49\x63\x2B\x20\x50\x72\x69\x6E\x74\x65\x72\x20\x50\x6F\x72\x74\x20\x20\x20\x20\x20\x06\x07\x10\x41\x70\x70\x6C\x65\x20\x49\x49\x63\x2F\x49\x49\x63\x2B\x20\x4D\x6F\x64\x65\x6D\x20\x50\x6F\x72\x74\x20\x20\x20\x20\x20\x20\x20\x06\x07\x20" | dd of="PT3.CODE0#060000" seek=1638 bs=1 conv=notrunc echo "A2CLOUD: Copying ProTERM..." for thisFile in /tmp/a2cloud-install/pt31/*; do filenameUnix="${thisFile##*/}" filename="${filenameUnix%%#*}" filetype="${filenameUnix##*#}" if [[ $filename != "PT3.DIAL" && $filename != "ProDOS" && $filename != "PT3.BACKUP" && $filename != "PT3.SYSTEM" ]]; then acmd -p "$a2CloudDisk" $filename \$${filetype:0:2} \$${filetype:2:4} < $thisFile fi done acmd -p "$a2CloudDisk" PT3.DIAL/PTD.SPACEBAR COM \$8002 < /tmp/a2cloud-install/pt31/PT3.DIAL/"PTD.SPACEBAR#598002" echo "A2CLOUD: Adding 115200 baud macros for ProTERM..." wget -qO PT3.IIC.MACRO "${binaryURL}PT3.IIC.MACRO.txt" cat "PT3.GLOBAL#040000" | tr '\r' '\n' | sed ':a;N;$!ba;s/\n\*\nOPTION-f : Unused & available.\n\*/~~~/' | sed -e '/~~~/r PT3.IIC.MACRO' -e 's///' | tr '\n' '\r' | acmd -p "$a2CloudDisk" PT3.IIC.GLOBAL TXT wget -qO PT3.IIE.MACRO "${binaryURL}PT3.IIE.MACRO.txt" cat "PT3.GLOBAL#040000" | tr '\r' '\n' | sed ':a;N;$!ba;s/\n\*\nOPTION-f : Unused & available.\n\*/~~~/' | sed -e '/~~~/r PT3.IIE.MACRO' -e 's///' | tr '\n' '\r' | acmd -p "$a2CloudDisk" PT3.IIE.GLOBAL TXT wget -qO PT3.IIGS.MACRO "${binaryURL}PT3.IIGS.MACRO.txt" cat "PT3.GLOBAL#040000" | tr '\r' '\n' | sed ':a;N;$!ba;s/\n\*\nOPTION-h : Unused & available.\n\*\n\n\*\nOPTION-H : Unused & available.\n\*/~~~/' | sed -e '/~~~/r PT3.IIGS.MACRO' -e 's///' | tr '\n' '\r' | acmd -p "$a2CloudDisk" PT3.IIGS.GLOBAL TXT acmd -p "$a2CloudDisk" PROTERM SYS < /tmp/a2cloud-install/pt31/"PT3.SYSTEM#ff2000" cd /tmp/a2cloud-install rm -rf /tmp/a2cloud-install/pt31 # Z-Link echo "A2CLOUD: Downloading and copying Z-Link..." cd /tmp/a2cloud-install wget -qO /tmp/a2cloud-install/zlink.shk "ftp://ftp.gno.org/pub/apple2/prodos/comm/term/zLink91.shk" nulib2 -p zlink.shk z.link.system | acmd -p "$a2CloudDisk" Z.LINK SYS # ShrinkIt echo "A2CLOUD: Downloading and copying ShrinkIt..." cd /tmp/a2cloud-install wget -qO shrinkit.sdk http://web.archive.org/web/20131031160750/http://www.nulib.com/library/shrinkit.sdk [[ ! -f shrinkit.sdk ]] && wget -qO shrinkit.sdk "${binaryURL}shrinkit.sdk" nulib2 -xs shrinkit.sdk > /dev/null acmd -g /tmp/a2cloud-install/SHRINKIT SHRINKIT - | acmd -p "$a2CloudDisk" SHRINKIT SYS acmd -g /tmp/a2cloud-install/SHRINKIT SHRINKIT.SYSTEM - | acmd -p "$a2CloudDisk" SHRINKIT.SYS SYS acmd -g /tmp/a2cloud-install/SHRINKIT IIPLUS.SHRINKIT - | acmd -p "$a2CloudDisk" IIPLUS.SHRINKIT SYS acmd -g /tmp/a2cloud-install/SHRINKIT IIPLUS.UNSHRINK - | acmd -p "$a2CloudDisk" IIPLUS.UNSHRINK SYS # DSK2FILE echo "A2CLOUD: Downloading and copying DSK2FILE..." cd /tmp/a2cloud-install wget -q -O dsk2file.shk http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip nulib2 -p dsk2file.shk dsk2file58 | acmd -p "$a2CloudDisk" DSK2FILE SYS # Apple System Utilities 3.1 launch file if hash unar 2>/dev/null; then echo "A2CLOUD: Copying System Utilities launch file..." acmd -g A2SYSDISK32.PO SYSUTIL.SYSTEM - | acmd -p "$a2CloudDisk" SYSUTIL SYS else echo "A2CLOUD: unar is not available; not installing System Utilities." fi # Filer echo "A2CLOUD: Downloading and copying Filer..." wget -qO /tmp/a2cloud-install/mmgr.prutil.sdk ftp://ftp.gno.org/pub/apple2/prodos/comm/term/modem.mgr/mmgr.prutil.sdk cd /tmp/a2cloud-install nulib2 -xs mmgr.prutil.sdk > /dev/null acmd -g /tmp/a2cloud-install/MMGR FILER - | acmd -p "$a2CloudDisk" FILER SYS # ADTPRO launch echo "A2CLOUD: Copying ADTPro launch file..." acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO - | acmd -p "$a2CloudDisk" ADTPRO SYS # VSDRIVE if [[ ! $(acmd -ls "$a2CloudDisk" | grep '^VSDRIVE BIN') ]]; then echo "A2CLOUD: Copying VSDRIVE..." acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VSDRIVE - | acmd -p "$a2CloudDisk" VSDRIVE SYS acmd -g /usr/local/adtpro/disks/VDRIVE-*DSK VSDRIVE.LOW - | acmd -p "$a2CloudDisk" VSDRIVE.LOW BIN \$2000 else echo "A2CLOUD: VSDRIVE is already on the target disk image." fi fi if [[ ! -f $a2CloudDisk140 || ( $(wc -c $a2CloudDisk140 | cut -f 1 -d ' ') != "143360" ) ]]; then echo "A2CLOUD: Creating 140K disk image..." mkpo "$a2CloudDisk140" A2CLOUD dd bs=256 count=1 of="$a2CloudDisk140" conv=notrunc 2>/dev/null < /usr/local/adtpro/disks/ADTPRO-*DSK dd bs=256 count=1 of="$a2CloudDisk140" skip=14 seek=14 conv=notrunc 2>/dev/null < /usr/local/adtpro/disks/ADTPRO-*DSK acmd -g $a2CloudDisk BASIC.SYSTEM - | acmd -p $a2CloudDisk140 BASIC.SYSTEM SYS acmd -g $a2CloudDisk PRODOS - | acmd -p $a2CloudDisk140 PRODOS SYS acmd -g $a2CloudDisk STARTUP - | acmd -p $a2CloudDisk140 STARTUP BAS acmd -g $a2CloudDisk ADTPRO.BIN - | acmd -p $a2CloudDisk140 ADTPRO.BIN BIN \$0800 acmd -g $a2CloudDisk Z.LINK - | acmd -p $a2CloudDisk140 Z.LINK SYS acmd -g $a2CloudDisk IIPLUS.SHRINKIT - | acmd -p $a2CloudDisk140 IIPLUS.SHRINKIT SYS acmd -g $a2CloudDisk IIPLUS.UNSHRINK - | acmd -p $a2CloudDisk140 IIPLUS.UNSHRINK SYS acmd -g $a2CloudDisk FILER - | acmd -p $a2CloudDisk140 FILER SYS acmd -g $a2CloudDisk ADTPRO - | acmd -p $a2CloudDisk140 ADTPRO SYS acmd -g $a2CloudDisk VSDRIVE - | acmd -p $a2CloudDisk140 VSDRIVE SYS acmd -g $a2CloudDisk VSDRIVE.LOW - | acmd -p $a2CloudDisk140 VSDRIVE.LOW BIN \$2000 fi if [[ -f /usr/local/adtpro/disks/Virtual.po && ! -L /usr/local/adtpro/disks/Virtual.po ]]; then mv /usr/local/adtpro/disks/Virtual.po /usr/local/adtpro/disks/defaultVirtual.po &>/dev/null vsd1 -f /usr/local/adtpro/disks/defaultVirtual.po fi if [[ -f /usr/local/adtpro/disks/Virtual2.po && ! -L /usr/local/adtpro/disks/Virtual2.po ]]; then if [[ $(sha1sum /usr/local/adtpro/disks/Virtual2.po | cut -d ' ' -f 1) == "41c178f9f596f94ea7607624672552137dccade2" ]]; then rm /usr/local/adtpro/disks/Virtual2.po else mv /usr/local/adtpro/disks/Virtual2.po /usr/local/adtpro/disks/defaultVirtual2.po &>/dev/null fi fi vsd2 -f $a2CloudDisk # for compatibility with pre-1.6.7 ln -s /usr/local/adtpro/disks/A2CLOUD.PO /usr/local/adtpro/disks/A2CLOUD.HDV echo echo "Your A2CLOUD disk images are ready. They are called" echo "A2CLOUD.DSK (140K) and A2CLOUD.PO (800K), and are stored in" echo "/usr/local/adtpro/disks" echo echo "You can transfer to a floppy with ADTPro, or access" echo "the 800K image with VSDRIVE at S2,D2." echo echo "See http://ivanx.com/a2cloud for more info." echo fi fi # make new blank disk of specified size if [[ $newImageName ]]; then echo "A2CLOUD: Creating new ${imageSize}K image for virtual drive 1 at" echo " /usr/local/adtpro/disks/$newImageName..." sudo pkill -f [A]DTPro rm /usr/local/adtpro/disks/Virtual.po &>/dev/null mkpo -b $(( $imageSize * 2 )) /usr/local/adtpro/disks/"$newImageName" $prodosVolName vsd1 -f /usr/local/adtpro/disks/"$newImageName" fi echo 'wget -q -O /tmp/a2cloud-setup ${A2CLOUD_SCRIPT_URL:-https://rawgit.com/RasppleII/a2cloud/current/}setup/setup.txt || { echo "Can'"'"'t download A2CLOUD setup scripts. Do you has internet?"; false; } && source /tmp/a2cloud-setup' | sudo tee /usr/local/bin/a2cloud-setup > /dev/null sudo chmod ugo+x /usr/local/bin/a2cloud-setup if [[ ! $restartPrompt ]]; then adtpro-start 2>/dev/null #start ADTPro if not running and USB adapter attached fi echo echo "A2CLOUD is now ready!" echo "See http://ivanx.com/a2cloud for instructions." sudo apt-get -y clean if [[ $restartPrompt ]]; then echo echo -n "Restart your $me now (not required, but recommended)? " read if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then doRestart=1 fi fi cd "$origDir" rm setup &>/dev/null rm a2cloud-setup &>/dev/null rm -rf /tmp/a2cloud-install &>/dev/null [[ $doRestart ]] && sudo shutdown -r now # version history: # future -- local links for everything # email # chromium # version history: # 1.8.1 -- set JAVA_HOME correctly for Java 8 (Pi, webupd8, Ubuntu for Pi 2B) # A2PI 1.5 (PiDrive update) on A2CLOUD disk # ADTPro 2.0.1 server, and 2.0.1 client on A2CLOUD disk # 1.8.0d-- * creates shortcuts on desktop for GSport, KEGS, LinApple, ADTPro server on x86 # * adds LXTerminal to desktop for non-A2Pi version # * ProDOS instruction screen on GSOS install # * provide via downloaded program that is dd notrunc'd over PRODOS (instead of writeCharsHex) # * figure out why lines in autostart are supposed to start with @ (daemon; restarts command on crash) # * install AppleCommander-1.3.5.13id (so Spectrum installer will work) # * fix mouse not working in VirtualBox framebuffer # * requires uninstalling (or temporarily disabling, if possible) VirtualBox guest additions # * can be activated if vboxguest module is unloaded *while gsport is running* # * offer to uninstall vboxguestmodule if gsport is in run console # * rename slot6drive1 and 2 to not contain "-blank" in slot6.tgz and gsport and kegs (x86) archives # * add links browser # * fix webupd8team getting added twice to sources.list # * install GSport for non-Pi # * figure out how to replace Raspbian entry in OS json dynamically # * command "a2cloud-update rasppleii" to update raspple ii # * prevent samba update causing dialog to come up # * create rasppleii-update # * make rasppleii-update universal even for non-Raspple II installs -- it's just raspbian-update + a2cloud-update + a2server-update # * creates shortcuts on desktop for GSport, KEGS, LinApple, ADTPro server on Pi # * download gsport and kegs icons # * no longer opens terminal window (since icons exist) # * (remove /etc/xdg/autostart/lxterminal.desktop) # * create aliases for raspbian-update and rasppleii-update # * update A2CLOUD help file and aliases for GSport # * create raspbian-update # * update a2cloud-help # * update motd (vm, raspple ii/a2cloud-pi) for gsport # * see if shortcuts work in Raspple II 110 # * check for /etc/xdg/lxsession/LXDE-pi; if so: # * create ~/.config/menus/lxde-pi-applications.menu, with reference to /etc/xdg/menus/lxde-pi-applications.menu # * no xrandr VBOX0 on the Pi; remove it if present (a2cloud 1.7.x may have put it there) # * user groups for pi user not only apple2 # * gsport-setup and kegs post install text to say ctrl-F12 for reboot # * add "links" to motd and help # * put a -Xmx128m in acmd so gsport and kegs setup work on Pi A/A+ (256 MB) # * added 'disablesafemode' to NOOBS recovery.cmdline (also in raspbian-update) to make it work on (at least) my A+ # * option for GISK rather than clean setup for GSport on x86 # * provide actual command for clean GSOS + Spectrum install, which is what gsport runs if no HD available # * provide command for clean GSOS install for KEGS # * add Dave's preflight/postflight stuff (groups, ownership permissions) for gsport # * install libpcap0.8-dev as part of Apple II Pi, GSport install, and GSport launcher # * make kegs-setup # * make kegs splash text # * doesn't add VirtualBox 800x600 if installing on Pi # * stop xrandr from being added multiple times to autostart in VirtualBox # * only install vbox 800x600 if running in VirtualBox # * disable screen blanking in vbox console # * disable screensaver in vbox LXDE # * disable screen blanking in vbox LXDE # * don't create LXTerminal desktop shortcut if RPi # * -6 arg provides empty ProDOS disks in S6D1 and S6D2 to GSport to speed things up # * -6 arg provides empty ProDOS disks in S6D1 and S6D2 to KEGS to speed things up # * can test if password is "raspberry" or "apple2" and advise accordingly # * enable Uthernet by default in gsport-setup # * enable AppleTalk Turbo by default in gsport-setup # * make kegs run as root # * consolidate gsport-setup and kegs-setup # * gsport-setup is gsport, gsport-setup -k is kegs # * clean up KEGS/GSport installer sections to be consistent # * create kegs-setup placeholders that call gsport-setup -k # * gsport-setup only offer system disks/GSport if java/acmd are available # * suppress policykit error that appears after upgrade: # * http://www.raspberrypi.org/forums/viewtopic.php?t=98617 # * see if uninstalling vbox additions is really necessary (nope) # * A2SERVER: creates symlink to /usr/local/etc/netatalk in /etc # * A2SERVER: -r no repo update option # * A2SERVER: can test if password is "raspberry" or "apple2" and advise accordingly # * A2SERVER: set AFP password to "apple2" # * A2SERVER: automated Windows Sharing install option -w # * A2SERVER: automate SMB password set # * A2SERVER: fix bug where turning off windows sharing then on again made it not restart at startup # * A2SERVER: turnkey (non-prompting) updater # * A2SERVER: show current and available versions on run # * A2SERVER: -v option to show version and exit # * A2SERVER: -h shows help # * A2SERVER: prefix status messages with A2SERVER: # * A2SERVER: fixed OS X connection problems by adding dhx2 uams files to rpi and x86 tarballs # * A2SERVER: set user password to "apple2" # * A2SERVER: support a2server-update rasppleii # * A2SERVER: automated netboot install option -b # * A2SERVER: deletes /tmp/a2server-packageReposUpdated at end # * A2SERVER: update help and aliases for raspbian-update # * A2SERVER: update a2server-setup rasppleii # * A2SERVER: add "a2server-update rasppleii" # * A2SERVER: disable screen blanking in Debian VM console # * A2SERVER: add raspbian-update and rasppleii-update # NOOBS: # * get photo B slide into all NOOBS slides (even non-a version) and also upload to online # * make NOOBS default to US keyboard (recovery.cmdline append lang=en keyboard=us) # * make NOOBS-lite 1.4.0+ that can install Raspple II from net, use for upgrade # * (change URL and default OS in noobs-master/recovery/config.h # * change "raspple" option to 'os' or '-os' # * remove silentinstall in raspbian-update # * add 'disablesafemode' to recovery.cmdline in Raspple II and Raspple II Lite # * make raspbian-update NOOBS-aware, both for standard NOOBS and Raspple II # 1.7.2 -- manually triggers udev rules during startup if ttyusbhandler script didn't execute (which it doesn't in Raspbian 31-Jan-2015/Kernel 3.18) # doesn't provide Java space warning if java is already installed # A/A+ support (vsdrive on direct attach or hub port 3, console on hub port 2) # 1.7.1 -- full undoit (unblu/unexec/unbit/usq/sciibin) # debian7_x86 and rpi binaries # perl version for ttytter not hardcoded # KEGS and LinApple support on debian_x86 # kegs launch script creates additional symlink called ROM # linapple launch script sets up framebuffer and udev mouse rule # apt-get clean after all installs # installer option to compile all rather than download binaries # login message mentions A2SERVER if it is installed # LXDE terminal window now in global autostart (opens for any user) # LXDE desktop defaults to 800x600 if running in VirtualBox VM # 1.7.0 -- Java 8 # 1.6.9 -- ADTPro 2.0.0 # new A2CLOUD disks with A2PI client 1.8 # 1.6.8 -- ADTPro 1.3.0 # tests for adtpro existence with either adtpro.sh or ADTPro.html # installs ttytter from its home page, not via apt-get (because it's in non-free, which is not enabled by default in debian) # 1.6.7 -- cppo installed from a2cloud directory on web server (a2server has symlink) # fixed cppo -e bug that always created a resource fork file even if there is no resource fork # shk2image leaves nothing behind in /tmp # wildcard copy all files on A2PI disk except PRODOS/BASIC.SYSTEM/*A3* to A2CLOUD disks when building # @ - new A2CLOUD disks with A2PI client 1.4 # % update before install for a2chat/a2news/kegs/kegs-setup/linapple/gsport/gsport-setup # disables IPv6 for exim4 to properly prevent startup error messages; restores log folder if not there # ^@ A2CLOUD.HDV is now A2CLOUD.PO (with symlink to A2CLOUD.HDV) # - renamed MACRO files on server to be .txt and moved to files # ^@ - new startup app on disk to make it easier to get to A2PI # a2cloud-setup updates a2news/a2chat/kegs/kegs-setup/linapple wrappers # added screen to a2cloud-help # 1.6.6 -- installs Screen # installs curl if not installed (for ttytter) # ttytter alias works correctly if run under Screen # a2cloudrc is now downloaded rather than created by script # LANG is now set in /usr/local/etc/a2cloud-lang rather than in a2cloudrc # fixed bug which checked for nulib2 instead of unar when seeing if needing to compile # opens terminal window in lxde on startup # setup -v displays available and installed versions # setup -y now bypasses all prompts; -n removed # % setup exits properly whether run via source or shell # moved cftp to files # support for x86 Debian/Ubuntu: # compiles binaries rather than downloads if not running on Pi # gets and supports Oracle x86 Java if not on Pi # installs X11 and LXDE if not installed # ttyUSBupper is always ttyUSB0, ttyUSBlower is always ttyUSB1 # adtpro.sh supports USB-to-serial on all architectures # 1.6.5 -- term command accepts mono/color/none as synonyms for vt100/pcansi/dumb # minor reorganization of configuration of a2cloudrc and screenrc # 1.6.4 -- term command has -f argument to force action # bash.bashrc now calls /usr/local/etc/a2cloudrc, which calls a2cloud-aliases # support for screen command (preserves TERM environment variable in new screen) # 1.6.3 -- sets ttytter to use ssl, and also 7-bit on serial port login, and ansi # if using TERM=pcansi. Also provides Term::ReadLine::TTYtter for -readline option # revised command line options and prompt for installing all or selective # added appleiipi-update command # 1.6.2 -- installs ISO-8859 (8-bit) character set for serial port login # adds 'term' command for setting vt100 or ANSI emulation # apt-get clean at end of A2CLOUD install # installs sciibin and unblu # a2cloud-update alias to a2cloud-setup # 300 baud support by 'baud' # prevents gsport (A2PI) from running when invoked from serial port # cmd line option and prompt to install either all, or select individual # revised intro language # 1.6.1 -- installs telnet and ttytter # prevents exim4 error messages after Tin installation # 1.6.0 -- checks for ADTPro update # updates ADTPro server and client software # put adtpro version number into variable and removed hardcoding elsewhere # asks for prodos volume name for new disk image; 8192 max # fixed order of files on 140K disk to be consistent with 800K disk # adtpro-start start now checks for USB adapter before starting # restarts ADTPro server on vsd1/vsd2 after prompting # created vsdsync alias to adtpro-restart; acmd warns if neeed # acmd warns if vsd1/vsd2 changes, and advises vsdsync if so # acmd now provides acmd help even on AppleCommander error # 1.6.0 beta #(unreleased) # 1.5.3 -- gets motd from web # prevents /var/log/exim4/paniclog from filling up # sets password to apple2 # shares /usr/local/adtpro/disks to AFP & SMB # don't prompt for restart after install by default # avahi-daemon installed # backup server for shrinkit # 1.5.2 -- cleans up at end, downloads disks, full A2PI including extras, # bug fixes, -h for options # 1.5.1 -- added dos2pro # 1.5 -- provides a2chat, a2news, kegs, linapple, a2pi # 1.23 -- support for new A2PI client # 1.22 -- downloads base gnustep library for unar/lsar, not full dev packages; # will still download those and build if binary isn't available for some reason # same goes for nulib2 and cftp. Should make for speedier install. # adds A2PI client software to A2CLOUD disk # disables console getty # installs xrdp # adds DSK2FILE to A2CLOUD disk # 1.7.2 -- manually triggers udev rules during startup if ttyusbhandler script didn't execute (which it doesn't in Raspbian 31-Jan-2015/Kernel 3.18) # doesn't provide Java space warning if java is already installed # A/A+ support (vsdrive on direct attach or hub port 3, console on hub port 2) # 1.7.1 -- full undoit (unblu/unexec/unbit/usq/sciibin) # debian7_x86 and rpi binaries # perl version for ttytter not hardcoded # KEGS and LinApple support on debian_x86 # kegs launch script creates additional symlink called ROM # linapple launch script sets up framebuffer and udev mouse rule # apt-get clean after all installs # installer option to compile all rather than download binaries # login message mentions A2SERVER if it is installed # LXDE terminal window now in global autostart (opens for any user) # LXDE desktop defaults to 800x600 if running in VirtualBox VM # 1.7.0 -- Java 8 # 1.6.9 -- ADTPro 2.0.0 # new A2CLOUD disks with A2PI client 1.8 # 1.6.8 -- ADTPro 1.3.0 # tests for adtpro existence with either adtpro.sh or ADTPro.html # installs ttytter from its home page, not via apt-get (because it's in non-free, which is not enabled by default in debian) # 1.6.7 -- cppo installed from a2cloud directory on web server (a2server has symlink) # fixed cppo -e bug that always created a resource fork file even if there is no resource fork # shk2image leaves nothing behind in /tmp # wildcard copy all files on A2PI disk except PRODOS/BASIC.SYSTEM/*A3* to A2CLOUD disks when building # @ - new A2CLOUD disks with A2PI client 1.4 # % update before install for a2chat/a2news/kegs/kegs-setup/linapple/gsport/gsport-setup # disables IPv6 for exim4 to properly prevent startup error messages; restores log folder if not there # ^@ A2CLOUD.HDV is now A2CLOUD.PO (with symlink to A2CLOUD.HDV) # - renamed MACRO files on server to be .txt and moved to files # ^@ - new startup app on disk to make it easier to get to A2PI # a2cloud-setup updates a2news/a2chat/kegs/kegs-setup/linapple wrappers # added screen to a2cloud-help # 1.6.6 -- installs Screen # installs curl if not installed (for ttytter) # ttytter alias works correctly if run under Screen # a2cloudrc is now downloaded rather than created by script # LANG is now set in /usr/local/etc/a2cloud-lang rather than in a2cloudrc # fixed bug which checked for nulib2 instead of unar when seeing if needing to compile # opens terminal window in lxde on startup # setup -v displays available and installed versions # setup -y now bypasses all prompts; -n removed # % setup exits properly whether run via source or shell # moved cftp to files # support for x86 Debian/Ubuntu: # compiles binaries rather than downloads if not running on Pi # gets and supports Oracle x86 Java if not on Pi # installs X11 and LXDE if not installed # ttyUSBupper is always ttyUSB0, ttyUSBlower is always ttyUSB1 # adtpro.sh supports USB-to-serial on all architectures # 1.6.5 -- term command accepts mono/color/none as synonyms for vt100/pcansi/dumb # minor reorganization of configuration of a2cloudrc and screenrc # 1.6.4 -- term command has -f argument to force action # bash.bashrc now calls /usr/local/etc/a2cloudrc, which calls a2cloud-aliases # support for screen command (preserves TERM environment variable in new screen) # 1.6.3 -- sets ttytter to use ssl, and also 7-bit on serial port login, and ansi # if using TERM=pcansi. Also provides Term::ReadLine::TTYtter for -readline option # revised command line options and prompt for installing all or selective # added appleiipi-update command # 1.6.2 -- installs ISO-8859 (8-bit) character set for serial port login # adds 'term' command for setting vt100 or ANSI emulation # apt-get clean at end of A2CLOUD install # installs sciibin and unblu # a2cloud-update alias to a2cloud-setup # 300 baud support by 'baud' # prevents gsport (A2PI) from running when invoked from serial port # cmd line option and prompt to install either all, or select individual # revised intro language # 1.6.1 -- installs telnet and ttytter # prevents exim4 error messages after Tin installation # 1.6.0 -- checks for ADTPro update # updates ADTPro server and client software # put adtpro version number into variable and removed hardcoding elsewhere # asks for prodos volume name for new disk image; 8192 max # fixed order of files on 140K disk to be consistent with 800K disk # adtpro-start start now checks for USB adapter before starting # restarts ADTPro server on vsd1/vsd2 after prompting # created vsdsync alias to adtpro-restart; acmd warns if neeed # acmd warns if vsd1/vsd2 changes, and advises vsdsync if so # acmd now provides acmd help even on AppleCommander error # 1.6.0 beta #(unreleased) # 1.5.3 -- gets motd from web # prevents /var/log/exim4/paniclog from filling up # sets password to apple2 # shares /usr/local/adtpro/disks to AFP & SMB # don't prompt for restart after install by default # avahi-daemon installed # backup server for shrinkit # 1.5.2 -- cleans up at end, downloads disks, full A2PI including extras, # bug fixes, -h for options # 1.5.1 -- added dos2pro # 1.5 -- provides a2chat, a2news, kegs, linapple, a2pi # 1.23 -- support for new A2PI client # 1.22 -- downloads base gnustep library for unar/lsar, not full dev packages; # will still download those and build if binary isn't available for some reason # same goes for nulib2 and cftp. Should make for speedier install. # adds A2PI client software to A2CLOUD disk # disables console getty # installs xrdp # adds DSK2FILE to A2CLOUD disk # FIXME: Redo this as its own top-level project later #= APPLE2PI BEGIN #noA2PiExtras= #while [[ $1 ]]; do # if [[ $1 == "-p" ]]; then # shift # noA2PiExtras=1 # elif [[ $1 ]]; then # echo "options:" # if [[ $isRpi ]]; then # echo "-p: don't install Apple II Pi extras" # fi # [[ $0 == "-bash" ]] && return 1 || exit 1 # fi #done #installA2Pi= #if [[ $isRpi ]]; then # echo # echo -n "Install Apple II Pi? " # read # [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installA2Pi=1 #fi #if [[ $installA2Pi ]]; then # if dpkg-query -l a2pi &>/dev/null; then # echo "A2CLOUD: Installing Apple II Pi..." # cd /tmp/a2cloud-install # if ! grep 'schmenk.is-a-geek.com' /etc/apt/sources.list; then # echo "deb http://schmenk.is-a-geek.com/raspbian wheezy contrib" | sudo tee -a /etc/apt/sources.list > /dev/null # sudo apt-get -y update > /dev/null # fi # sudo apt-get -y --force-yes install a2pi # sudo apt-get -y clean # else # echo "A2CLOUD: Apple II Pi is already installed." # fi # if [[ ! $noA2PiExtras ]]; then # if [[ ! $(dpkg -l | grep libpcap0.8-dev) ]]; then # sudo apt-get -y install libpcap0.8-dev # sudo apt-get -y clean # fi # if ! command -v gsport >/dev/null; then # # echo "A2CLOUD: Updating package repositories to include Apple II Pi..." # # sudo apt-get -y update > /dev/null # echo "A2CLOUD: Installing Apple II Pi extras (GSport)..." # sudo apt-get -y --force-yes install apple2user # sudo apt-get -y clean # else # echo "A2CLOUD: Apple II Pi extras (GSport) are already installed." # fi # fi # sudo sed -i 's/( $SSH_CLIENT || $REMOTEHOST )/( $(tty | grep ttyUSB) || $(tty | grep ttyAMA) || $SSH_CLIENT || $REMOTEHOST )/' /usr/bin/gsport # if [[ $slot6 ]]; then # echo "A2CLOUD: Putting blank disks in GSport slot 6..." # sudo sed -i 's@^s6d1.*$@s6d1 = /usr/share/gsport/disks/slot6drive1.po@' /usr/share/gsport/config.txt # sudo sed -i 's@^s6d2.*$@s6d2 = /usr/share/gsport/disks/slot6drive2.po@' /usr/share/gsport/config.txt # sudo sed -i 's@^s6d1.*$@s6d1 = /usr/share/gsport/disks/slot6drive1.po@' /home/apple2/config.txt # sudo sed -i 's@^s6d2.*$@s6d2 = /usr/share/gsport/disks/slot6drive2.po@' /home/apple2/config.txt # if [[ ! -f /usr/share/gsport/disks/slot6drive1.po || ! -f /usr/share/gsport/disks/slot6drive2.po ]]; then # wget -qO- "${binaryURL}slot6-gsport-rpi.tgz" | sudo tar Pzx 2>/dev/null # fi # fi # # # set AppleTalk to turbo # if ! grep -q 'g_appletalk_turbo' /usr/share/gsport/config.txt; then # if grep -q 'bram1[00]' /usr/share/gsport/config.txt; then # sudo sed -i 's/^\(bram1\[00\]\)/g_appletalk_turbo = 1\n\n\1/' /usr/share/gsport/config.txt # else # echo -e '\ng_appletalk_turbo = 1' | sudo tee -a /usr/share/gsport/config.txt > /dev/null # fi # fi # sudo sed -i 's/^g_appletalk_turbo = 0/g_appletalk_turbo = 1/' /usr/share/gsport/config.txt # # # enable Uthernet # if ! grep -q 'g_ethernet[^_]' /usr/share/gsport/config.txt; then # if grep -q 'bram1[00]' /usr/share/gsport/config.txt; then # sudo sed -i 's/^\(bram1\[00\]\)/g_ethernet = 1\n\n\1/' /usr/share/gsport/config.txt # else # echo -e '\ng_ethernet = 1' | sudo tee -a /usr/share/gsport/config.txt > /dev/null # fi # fi # sudo sed -i 's/^g_ethernet = 0/g_ethernet = 1/' /usr/share/gsport/config.txt # #fi #= APPLE2PI END #= APPLE2PI BEGIN # This was part of building the A2CLOUD disk image # # A2PI # if [[ ! $(acmd -ls "$a2CloudDisk" | grep '^ A2PI BIN') ]]; then # echo "A2CLOUD: Downloading and copying A2PI client..." # mkdir -p /tmp/a2cloud-install/a2pi # cd /tmp/a2cloud-install/a2pi # wget -qO a2pi.deb http://schmenk.is-a-geek.com/tarfiles/a2pi_armhf.deb # # dpkg-deb --fsys-tarfile a2pi.deb | tar --strip-components=4 --wildcards -O -x ./usr/share/a2pi/A2PI*.PO > A2PI.PO # dpkg-deb --fsys-tarfile a2pi.deb | tar --strip-components=4 --wildcards -x ./usr/share/a2pi/A2PI*.PO # a2piImage=$(ls -1r A2PI*.PO | head -1) # mkdir a2pidisk # cppo -e "$a2piImage" a2pidisk &>/dev/null # mv a2pidisk/A2PI* a2pidisk/A2PI # cd a2pidisk/A2PI # rm PRODOS* *A3* BASIC.SYSTEM* # cd .. # nulib2 -a -r -e ../a2pi.shk A2PI &>/dev/null # cd .. # shk2image a2pi.shk $a2CloudDisk &>/dev/null # shk2image a2pi.shk $a2CloudDisk140 &>/dev/null # cd /tmp/a2cloud-install # rm -rf a2pi # else # echo "A2CLOUD: A2PI client is already on the target disk image." # fi #= APPLE2PI END