From 1824c4aa439bee0b3d6ba72f02098d73d0acee7e Mon Sep 17 00:00:00 2001 From: "T. Joseph Carter" Date: Tue, 25 Oct 2016 10:42:29 -0700 Subject: [PATCH] Re-indent scripts (tabs) --- setup/a2chat.txt | 64 +- setup/a2cloudrc.txt | 28 +- setup/a2news.txt | 64 +- setup/acmd.txt | 690 ++++----- setup/adtpro-start.txt | 46 +- setup/adtpro.sh.txt | 152 +- setup/baud.txt | 40 +- setup/cppo.txt | 2088 +++++++++++++------------- setup/dopo.txt | 74 +- setup/dos2pro.txt | 148 +- setup/gsport-setup-shell.txt | 6 +- setup/gsport-setup.txt | 1000 ++++++------- setup/gsport.txt | 176 +-- setup/linapple.txt | 86 +- setup/mkpo.txt | 210 +-- setup/raspbian-update.txt | 346 ++--- setup/setup.txt | 2740 +++++++++++++++++----------------- setup/shk2image.txt | 14 +- setup/term.txt | 66 +- setup/ttyusbhandler.txt | 74 +- setup/usbgetty.txt | 58 +- setup/vsd.txt | 60 +- 22 files changed, 4115 insertions(+), 4115 deletions(-) mode change 100644 => 100755 setup/a2chat.txt mode change 100644 => 100755 setup/a2cloudrc.txt mode change 100644 => 100755 setup/a2news.txt mode change 100644 => 100755 setup/acmd.txt mode change 100644 => 100755 setup/adtpro-start.txt mode change 100644 => 100755 setup/adtpro.sh.txt mode change 100644 => 100755 setup/baud.txt mode change 100644 => 100755 setup/cppo.txt mode change 100644 => 100755 setup/dopo.txt mode change 100644 => 100755 setup/dos2pro.txt mode change 100644 => 100755 setup/gsport-setup-shell.txt mode change 100644 => 100755 setup/gsport.txt mode change 100644 => 100755 setup/linapple.txt mode change 100644 => 100755 setup/mkpo.txt mode change 100644 => 100755 setup/raspbian-update.txt mode change 100644 => 100755 setup/shk2image.txt mode change 100644 => 100755 setup/term.txt mode change 100644 => 100755 setup/ttyusbhandler.txt mode change 100644 => 100755 setup/usbgetty.txt mode change 100644 => 100755 setup/vsd.txt diff --git a/setup/a2chat.txt b/setup/a2chat.txt old mode 100644 new mode 100755 index 0ad58aa..f2127d0 --- a/setup/a2chat.txt +++ b/setup/a2chat.txt @@ -1,65 +1,65 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: if [[ ! $(dpkg -l irssi 2> /dev/null | grep '^ii') ]]; then - echo "Installing irssi..." - supo apt-get -y update - sudo apt-get -y install irssi &> /dev/null - sudo apt-get -y clean + echo "Installing irssi..." + supo apt-get -y update + sudo apt-get -y install irssi &> /dev/null + sudo apt-get -y clean fi if [[ $1 == "-n" && $2 ]]; then - nickname=$2 + nickname=$2 elif [[ $1 == "-n" ]]; then - nickname="0" + nickname="0" elif [[ -f ~/.irssi/a2c.nickname ]]; then - nickname=$(cat ~/.irssi/a2c.nickname) + nickname=$(cat ~/.irssi/a2c.nickname) else - nickname= + nickname= fi while [[ ! $nickname || ! $(grep -i '^[a-z_\-\\^{}|`][a-z0-9_\-\\^{}|`]*$' <<< $nickname) ]]; do - echo "Choosing a nickname" - echo - echo "A nickname on irc is how you are known to other people. It can" - echo "consist of letters, numbers, and punctuation symbols such as -, _, and ^." - echo "Some older IRC servers will cut your nickname to eight characters, but" - echo "more modern ones like A2Central do not." - echo - echo "Aliases are fine on irc, but really common names like James or Mark or" - echo "AppleIIGuy are likely to be used by someone else already. A guy named" - echo "Joseph might use some variation of their name (such as JosephC or" - echo "tjcarter) or come up with something else entirely." - echo - echo "You can change your nickname once you're online by typing a command" - echo "like \"/nick \", and you can rerun this script with the -n" - echo "parameter to have this script save your choice for future use." - echo - echo -n "Enter a nickname (use 'a2chat -n' to change it later): " - read - nickname=$REPLY + echo "Choosing a nickname" + echo + echo "A nickname on irc is how you are known to other people. It can" + echo "consist of letters, numbers, and punctuation symbols such as -, _, and ^." + echo "Some older IRC servers will cut your nickname to eight characters, but" + echo "more modern ones like A2Central do not." + echo + echo "Aliases are fine on irc, but really common names like James or Mark or" + echo "AppleIIGuy are likely to be used by someone else already. A guy named" + echo "Joseph might use some variation of their name (such as JosephC or" + echo "tjcarter) or come up with something else entirely." + echo + echo "You can change your nickname once you're online by typing a command" + echo "like \"/nick \", and you can rerun this script with the -n" + echo "parameter to have this script save your choice for future use." + echo + echo -n "Enter a nickname (use 'a2chat -n' to change it later): " + read + nickname=$REPLY done mkdir -p ~/.irssi echo $nickname > ~/.irssi/a2c.nickname if [[ -f ~/.irssi/startup ]]; then - mv ~/.irssi/startup ~/.irssi/startup.orig + mv ~/.irssi/startup ~/.irssi/startup.orig fi echo -e "/network add -autosendcmd '/join #a2c.chat' Palomino.A2\n/server add -auto -network Palomino.A2 irc.a2central.com\n" > ~/.irssi/startup if [[ -f ~/.irssi/config ]]; then - cp ~/.irssi/config ~/.irssi/config.orig + cp ~/.irssi/config ~/.irssi/config.orig fi irssi -n $nickname rm ~/.irssi/startup &> /dev/null if [[ -f ~/.irssi/startup.orig ]]; then - mv ~/.irssi/startup.orig ~/.irssi/startup + mv ~/.irssi/startup.orig ~/.irssi/startup fi rm ~/.irssi/config &> /dev/null if [[ -f ~/.irssi/config.orig ]]; then - mv ~/.irssi/config.orig ~/.irssi/config + mv ~/.irssi/config.orig ~/.irssi/config fi diff --git a/setup/a2cloudrc.txt b/setup/a2cloudrc.txt old mode 100644 new mode 100755 index 9a609d2..3d70ff7 --- a/setup/a2cloudrc.txt +++ b/setup/a2cloudrc.txt @@ -1,37 +1,37 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: source /usr/local/etc/a2cloud-aliases if [[ -f /usr/local/java/bin/java ]]; then - export JAVA_HOME=/usr/local/java + export JAVA_HOME=/usr/local/java elif [[ -f /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/bin/java ]]; then # RPi - export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt + export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt elif [[ -f /usr/lib/jvm/java-8-oracle/bin/java ]]; then # webupd8 - export JAVA_HOME=/usr/lib/jvm/java-8-oracle + export JAVA_HOME=/usr/lib/jvm/java-8-oracle elif [[ -f /usr/lib/jvm/java-8-oracle/jre/bin/java ]]; then # Ubuntu 14.04 RPi2 - export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre + export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre elif [[ -f /usr/lib/jvm/jdk-7-oracle-armhf/bin/java ]]; then # RPi - export JAVA_HOME=/usr/lib/jvm/jdk-7-oracle-armhf + export JAVA_HOME=/usr/lib/jvm/jdk-7-oracle-armhf elif [[ -f /usr/lib/jvm/jdk-7-oracle/bin/java ]]; then # webupd8 - export JAVA_HOME=/usr/lib/jvm/jdk-7-oracle + export JAVA_HOME=/usr/lib/jvm/jdk-7-oracle fi [[ ! $(grep java <<< $PATH) ]] && PATH=$PATH:$JAVA_HOME/bin if [[ -f /usr/local/etc/a2cloud-lang ]]; then - lang8bit=$(cat /usr/local/etc/a2cloud-lang) + lang8bit=$(cat /usr/local/etc/a2cloud-lang) else - lang8bit=C + lang8bit=C fi if [[ ${TERM:0:6} == "screen" ]]; then - myTTY=$(ps hp $(ps hp $(ps hp $$ -o ppid) -o ppid) -o tty) + myTTY=$(ps hp $(ps hp $(ps hp $$ -o ppid) -o ppid) -o tty) else - myTTY=$(tty) - export ttyTERM="$TERM" + myTTY=$(tty) + export ttyTERM="$TERM" fi if [[ $(grep ttyUSB <<< $myTTY) || $(grep ttyAMA <<< $myTTY) ]]; then - LANG=$lang8bit + LANG=$lang8bit fi if [[ ${TERM:0:6} == "screen" ]]; then - TERM=$ttyTERM + TERM=$ttyTERM fi diff --git a/setup/a2news.txt b/setup/a2news.txt old mode 100644 new mode 100755 index 463ed32..654d587 --- a/setup/a2news.txt +++ b/setup/a2news.txt @@ -1,60 +1,60 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: defaultNNTP="news.aioe.org" defaultGroups="comp.emulators.apple2:\ncomp.sys.apple2:\ncomp.sys.apple2.comm:\ncomp.sys.apple2.marketplace:\ncomp.sys.apple2.programmer:\ncomp.sys.apple2.usergroups:" if [[ ! $(dpkg -l tin 2> /dev/null | grep '^ii') ]]; then - echo "Installing Tin newsreader..." - sudo apt-get -y update - sudo apt-get -y install tin &> /dev/null - sudo apt-get -y clean + echo "Installing Tin newsreader..." + sudo apt-get -y update + sudo apt-get -y install tin &> /dev/null + sudo apt-get -y clean fi if [[ $1 == "-h" || $1 == "--help" ]]; then - echo "Usage: a2news [-s nntpServerAddress] [-m postingEmailAddress] [otherTinOptions]" - echo " note: for full options, instead use 'tin'" - exit 1 + echo "Usage: a2news [-s nntpServerAddress] [-m postingEmailAddress] [otherTinOptions]" + echo " note: for full options, instead use 'tin'" + exit 1 fi while [[ $1 == "-s" || $1 == "-m" ]]; do - if [[ $1 == "-s" && $2 ]]; then - nntpServer=$2 - shift - shift - fi + if [[ $1 == "-s" && $2 ]]; then + nntpServer=$2 + shift + shift + fi - if [[ $1 == "-m" && $2 ]]; then - emailAddress=$2 - shift - shift - fi + if [[ $1 == "-m" && $2 ]]; then + emailAddress=$2 + shift + shift + fi done mkdir -p ~/.tin if [[ ! -f ~/.newsrc ]]; then - IFS=''; echo -e "$defaultGroups" > ~/.newsrc + IFS=''; echo -e "$defaultGroups" > ~/.newsrc fi if [[ $nntpServer || ! -f ~/.tin/nntp.server ]]; then - [[ ! $nntpServer ]] && nntpServer="$defaultNNTP" - echo "$nntpServer" > ~/.tin/nntp.server + [[ ! $nntpServer ]] && nntpServer="$defaultNNTP" + echo "$nntpServer" > ~/.tin/nntp.server else - nntpServer=$(cat ~/.tin/nntp.server) + nntpServer=$(cat ~/.tin/nntp.server) fi if [[ $emailAddress || ! -f ~/.tin/tinrc ]]; then - while [[ ! $emailAddress || ! $(grep "@" <<< $emailAddress) || ! $(grep "\." <<< $emailAddress) ]]; do - echo -n "Enter the email address you want to post as: " - read - emailAddress=$REPLY - done - if [[ -f ~/.tin/tinrc ]]; then - sed -i "s/^mail_address=.*$/mail_address=$emailAddress/" ~/.tin/tinrc - else - echo "mail_address=$emailAddress" > ~/.tin/tinrc - fi + while [[ ! $emailAddress || ! $(grep "@" <<< $emailAddress) || ! $(grep "\." <<< $emailAddress) ]]; do + echo -n "Enter the email address you want to post as: " + read + emailAddress=$REPLY + done + if [[ -f ~/.tin/tinrc ]]; then + sed -i "s/^mail_address=.*$/mail_address=$emailAddress/" ~/.tin/tinrc + else + echo "mail_address=$emailAddress" > ~/.tin/tinrc + fi fi NNTPSERVER=$nntpServer tin -r "$@" diff --git a/setup/acmd.txt b/setup/acmd.txt old mode 100644 new mode 100755 index 0b5cde0..ee898ac --- a/setup/acmd.txt +++ b/setup/acmd.txt @@ -1,64 +1,64 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # set default AppleCommander location if ADTPro is not installed defaultAcPath=$(echo -n /usr/local/bin/AppleCommander-*-ac.jar) echoerr() { - echo "$@" 1>&2; + echo "$@" 1>&2; } helpExit () { - if [[ -s $acmdStdErr ]]; then - if [[ $(grep CommandLineHelp $acmdStdErr) ]]; then - grep -v ^-[pge][[:space:]] $acmdStdErr | grep -v '^ or' | grep -v 0x2000 1>&2 - echoerr "-g [] copy filename out of any" - echoerr " disk image. Using - for outputFilename will copy to stdout." - echoerr "-e [] like -g, with conversion" - echoerr " to modern file format if possible." - echoerr "-p [[$|0x]] [[$|0x]] copy filename" - echoerr " into ProDOS disk image. is either three-letter or numeric" - echoerr " ProDOS file type (BIN if omitted). Will read from stdin if supplied." - echoerr " ProDOS subdirectories in will be created if needed." - echoerr " If an AppleDouble file or Nulib2 extended filename is detected," - echoerr " and are automatically set, and resource forks are kept." - if hash cppo &> /dev/null; then - echoerr " (To extract these from a ProDOS image file, use cppo -ad or cppo -e.)" - fi - echoerr "-c [[$|0x]] [[$|0x]] synonym for -p" - echoerr " with filename and imagename reversed." - #echoerr "-cd |" - #echoerr " set creation date and time of file in ProDOS disk image" - #echoerr "-md |" - #echoerr " set modified date and time of file in ProDOS disk image" - else - cat $acmdStdErr - fi - if [[ $arg1 == "-h" ]]; then - exitVal=0 - else - exitVal=1 - fi - else - if [[ $vsd1_md5 && ( "$vsd1_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual.po)" || "$vsd2_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual2.po)" ) ]]; then - if [[ "$vsd1_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual.po)" || "$vsd2_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual2.po)" ]]; then - echoerr "One of the virtual drive image files has changed while ADTPro server is active." - echoerr " If using VSDRIVE, type 'vsdsync' now to see changes and prevent corruption." - fi - fi - exitval=0 - fi - rm $acmdStdErr &> /dev/null - exit $exitVal + if [[ -s $acmdStdErr ]]; then + if [[ $(grep CommandLineHelp $acmdStdErr) ]]; then + grep -v ^-[pge][[:space:]] $acmdStdErr | grep -v '^ or' | grep -v 0x2000 1>&2 + echoerr "-g [] copy filename out of any" + echoerr " disk image. Using - for outputFilename will copy to stdout." + echoerr "-e [] like -g, with conversion" + echoerr " to modern file format if possible." + echoerr "-p [[$|0x]] [[$|0x]] copy filename" + echoerr " into ProDOS disk image. is either three-letter or numeric" + echoerr " ProDOS file type (BIN if omitted). Will read from stdin if supplied." + echoerr " ProDOS subdirectories in will be created if needed." + echoerr " If an AppleDouble file or Nulib2 extended filename is detected," + echoerr " and are automatically set, and resource forks are kept." + if hash cppo &> /dev/null; then + echoerr " (To extract these from a ProDOS image file, use cppo -ad or cppo -e.)" + fi + echoerr "-c [[$|0x]] [[$|0x]] synonym for -p" + echoerr " with filename and imagename reversed." + #echoerr "-cd |" + #echoerr " set creation date and time of file in ProDOS disk image" + #echoerr "-md |" + #echoerr " set modified date and time of file in ProDOS disk image" + else + cat $acmdStdErr + fi + if [[ $arg1 == "-h" ]]; then + exitVal=0 + else + exitVal=1 + fi + else + if [[ $vsd1_md5 && ( "$vsd1_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual.po)" || "$vsd2_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual2.po)" ) ]]; then + if [[ "$vsd1_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual.po)" || "$vsd2_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual2.po)" ]]; then + echoerr "One of the virtual drive image files has changed while ADTPro server is active." + echoerr " If using VSDRIVE, type 'vsdsync' now to see changes and prevent corruption." + fi + fi + exitval=0 + fi + rm $acmdStdErr &> /dev/null + exit $exitVal } decToBin () { - dec="$(( 10#$1 ))" - bits="" - for i in 7 6 5 4 3 2 1 0; do - bits+=$(( (dec & (2**i)) >> i )) - done - echo -n "$(( 10#$bits ))" + dec="$(( 10#$1 ))" + bits="" + for i in 7 6 5 4 3 2 1 0; do + bits+=$(( (dec & (2**i)) >> i )) + done + echo -n "$(( 10#$bits ))" } arg1=$1 @@ -68,350 +68,350 @@ acmdStdErr="/tmp/acmd_$RANDOM$RANDOM" [[ -f /usr/libexec/java_home ]] && osx=1 || osx= if [[ $osx ]]; then - if ! /usr/libexec/java_home &> /dev/null; then - echo -n "AppleCommander requires the Java JDK. Do you want to install it now? " - read - if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then - # install Oracle Java for OS X - echo "Downloading Java JDK..." - mkdir -p /tmp/jdk - curl -L --cookie oraclelicense=accept-securebackup-cookie $(curl -L "http://www.oracle.com/"$(curl -L "http://www.oracle.com/technetwork/java/javase/downloads/" 2> /dev/null | grep -o -m 1 '/technetwork/java/javase/downloads/jdk.-downloads-[0-9]*\.html') 2> /dev/null | grep -o 'http://.*macosx-x64.dmg' | sort | tail -1) 2> /dev/null > /tmp/jdk/jdk.dmg - echo "Installing Java JDK..." - hdiutil attach /tmp/jdk/jdk.dmg &> /dev/null - sudo installer -pkg /Volumes/JDK*/JDK*.pkg -target / - diskutil unmountDisk /Volumes/JDK* - rm -r /tmp/jdk 2> /dev/null - if ! /usr/libexec/java_home &> /dev/null; then - echo "The Java JDK could not be installed." - echo "Type \"java\" and then click \"More Info...\" to download and install it manually." - exit 1 - fi - else - exit 1 - fi - fi + if ! /usr/libexec/java_home &> /dev/null; then + echo -n "AppleCommander requires the Java JDK. Do you want to install it now? " + read + if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then + # install Oracle Java for OS X + echo "Downloading Java JDK..." + mkdir -p /tmp/jdk + curl -L --cookie oraclelicense=accept-securebackup-cookie $(curl -L "http://www.oracle.com/"$(curl -L "http://www.oracle.com/technetwork/java/javase/downloads/" 2> /dev/null | grep -o -m 1 '/technetwork/java/javase/downloads/jdk.-downloads-[0-9]*\.html') 2> /dev/null | grep -o 'http://.*macosx-x64.dmg' | sort | tail -1) 2> /dev/null > /tmp/jdk/jdk.dmg + echo "Installing Java JDK..." + hdiutil attach /tmp/jdk/jdk.dmg &> /dev/null + sudo installer -pkg /Volumes/JDK*/JDK*.pkg -target / + diskutil unmountDisk /Volumes/JDK* + rm -r /tmp/jdk 2> /dev/null + if ! /usr/libexec/java_home &> /dev/null; then + echo "The Java JDK could not be installed." + echo "Type \"java\" and then click \"More Info...\" to download and install it manually." + exit 1 + fi + else + exit 1 + fi + fi else # not OS X, so presumably Linux - if ! hash java &> /dev/null; then - echo -n "AppleCommander requires the Java JDK. " - if hash apt-get; then - echo -n "Do you want to install it now? " - read - if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then - # 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 - else - exit 1 - fi - fi - fi - if ! hash java &> /dev/null; then - echo - echo "Get it from http://www.oracle.com/technetwork/java/javase/downloads/" - exit 1 - fi + if ! hash java &> /dev/null; then + echo -n "AppleCommander requires the Java JDK. " + if hash apt-get; then + echo -n "Do you want to install it now? " + read + if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then + # 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 + else + exit 1 + fi + fi + fi + if ! hash java &> /dev/null; then + echo + echo "Get it from http://www.oracle.com/technetwork/java/javase/downloads/" + exit 1 + fi fi setAcPath () { - acPath=$defaultAcPath - adtPath= - if [[ ! -f $acPath ]]; then - if [[ -f /usr/local/adtpro/adtpro.sh ]]; then - adtPath="/usr/local/adtpro" - elif [[ $osx ]]; then - adtPath=$(echo -n /Applications/ADTPro* | tr ' ' '\n' | sort | head -1); - fi - if [[ -d "$adtPath" ]]; then - acPath="$adtPath"/lib/AppleCommander/AppleCommander-ac.jar - [[ ! -f $acPath ]] && acPath=$(echo -n "$adtPath"/lib/AppleCommander/AppleCommander-*-ac.jar) - fi - fi - acPath=$(echo -n $acPath) + acPath=$defaultAcPath + adtPath= + if [[ ! -f $acPath ]]; then + if [[ -f /usr/local/adtpro/adtpro.sh ]]; then + adtPath="/usr/local/adtpro" + elif [[ $osx ]]; then + adtPath=$(echo -n /Applications/ADTPro* | tr ' ' '\n' | sort | head -1); + fi + if [[ -d "$adtPath" ]]; then + acPath="$adtPath"/lib/AppleCommander/AppleCommander-ac.jar + [[ ! -f $acPath ]] && acPath=$(echo -n "$adtPath"/lib/AppleCommander/AppleCommander-*-ac.jar) + fi + fi + acPath=$(echo -n $acPath) } setAcPath if [[ ! -f $acPath ]]; then - echo "Installing AppleCommander..." - sudo mkdir -p /usr/local/bin - acUrl="http://sourceforge.net/projects/applecommander/files/AppleCommander%20-%20Interim/testcase/AppleCommander-1.3.5.13id-ac.jar/download" - if [[ $osx ]]; then - curl -L "$acUrl" 2> /dev/null | sudo tee /usr/local/bin/AppleCommander-1.3.5.13id-ac.jar > /dev/null - else - sudo wget -qO /usr/local/bin/AppleCommander-1.3.5.13id-ac.jar "$acUrl" - fi - setAcPath - if [[ ! -f "$acPath" ]]; then - echo "AppleCommander couldn't be installed. Download it from" - echo "http://applecommander.sourceforge.net and put it in /usr/local/bin." - exit 1 - fi + echo "Installing AppleCommander..." + sudo mkdir -p /usr/local/bin + acUrl="http://sourceforge.net/projects/applecommander/files/AppleCommander%20-%20Interim/testcase/AppleCommander-1.3.5.13id-ac.jar/download" + if [[ $osx ]]; then + curl -L "$acUrl" 2> /dev/null | sudo tee /usr/local/bin/AppleCommander-1.3.5.13id-ac.jar > /dev/null + else + sudo wget -qO /usr/local/bin/AppleCommander-1.3.5.13id-ac.jar "$acUrl" + fi + setAcPath + if [[ ! -f "$acPath" ]]; then + echo "AppleCommander couldn't be installed. Download it from" + echo "http://applecommander.sourceforge.net and put it in /usr/local/bin." + exit 1 + fi fi ac="java -Xmx128m -jar $acPath" if [[ ! $2 || $arg1 == "-h" ]]; then - java -jar "$acPath" 2> $acmdStdErr - [[ $? -eq 127 ]] && exit 127 || helpExit $arg1 + java -jar "$acPath" 2> $acmdStdErr + [[ $? -eq 127 ]] && exit 127 || helpExit $arg1 fi if [[ $arg1 != "-i" && $arg1 != "-ls" && $arg1 != "-l" && $arg1 != "-ll" && $arg1 != "-x" && $arg1 != "-g" && $arg1 != "-e" && $(ps aux | grep [A]DTPro) ]]; then - vsd1_md5="$(md5sum /usr/local/adtpro/disks/Virtual.po)" - vsd2_md5="$(md5sum /usr/local/adtpro/disks/Virtual2.po)" + vsd1_md5="$(md5sum /usr/local/adtpro/disks/Virtual.po)" + vsd2_md5="$(md5sum /usr/local/adtpro/disks/Virtual2.po)" fi if [[ ( $arg1 == "-p" || $arg1 == "-c" || $arg1 == "-g" || $arg1 == "-e" ) && $2 && $3 ]]; then - AD= - EX= - prodosArg= - prodosArgParent= - rFile= - getArg= - if [[ $arg1 == "-c" || $arg1 == "-p" ]]; then - if [[ $arg1 == "-c" ]]; then - prodosArg="$2" - imageArg="$3" - elif [[ $arg1 == "-p" ]]; then - prodosArg="$3" - imageArg="$2" - fi - [[ $prodosArg == *"/"* ]] && prodosArgParent="${prodosArg%/*}/" - rFile="${prodosArgParent}.AppleDouble/${prodosArg##*/}" - if [[ -f "$prodosArg" && -f "$rFile" ]]; then # AppleDouble - AD=1 - elif [ -f "${prodosArg%#*}"#?????? ]; then # Nulib2 ext filename - EX=1 - prodosArg=$(echo -n "${prodosArg%#*}"#??????) - rFile="${prodosArg}"r - fi - if [[ $AD || $EX ]]; then - # if target is not a ProDOS disk, ignore metadata - if ! $ac -i "$imageArg" | grep -q '^Disk Format: ProDOS'; then - AD= - EX= - fi - fi - elif [[ $arg1 == "-g" || $arg1 == "-e" ]]; then - fileArg="$3" - imageArg="$2" - getArg="$arg1" - else - exit 2; - fi + AD= + EX= + prodosArg= + prodosArgParent= + rFile= + getArg= + if [[ $arg1 == "-c" || $arg1 == "-p" ]]; then + if [[ $arg1 == "-c" ]]; then + prodosArg="$2" + imageArg="$3" + elif [[ $arg1 == "-p" ]]; then + prodosArg="$3" + imageArg="$2" + fi + [[ $prodosArg == *"/"* ]] && prodosArgParent="${prodosArg%/*}/" + rFile="${prodosArgParent}.AppleDouble/${prodosArg##*/}" + if [[ -f "$prodosArg" && -f "$rFile" ]]; then # AppleDouble + AD=1 + elif [ -f "${prodosArg%#*}"#?????? ]; then # Nulib2 ext filename + EX=1 + prodosArg=$(echo -n "${prodosArg%#*}"#??????) + rFile="${prodosArg}"r + fi + if [[ $AD || $EX ]]; then + # if target is not a ProDOS disk, ignore metadata + if ! $ac -i "$imageArg" | grep -q '^Disk Format: ProDOS'; then + AD= + EX= + fi + fi + elif [[ $arg1 == "-g" || $arg1 == "-e" ]]; then + fileArg="$3" + imageArg="$2" + getArg="$arg1" + else + exit 2; + fi - shift + shift - if [[ $getArg ]]; then # get file + if [[ $getArg ]]; then # get file - outFile= - [[ $3 && $3 != "-" ]] && outFile="$3" - [[ ! $3 ]] && outFile="${2##*/}" - $ac $getArg "$imageArg" "$fileArg" $outFile 2> $acmdStdErr + outFile= + [[ $3 && $3 != "-" ]] && outFile="$3" + [[ ! $3 ]] && outFile="${2##*/}" + $ac $getArg "$imageArg" "$fileArg" $outFile 2> $acmdStdErr - else # put file + else # put file - # test ProDOS name validity - prodosPath=$(tr [:lower:] [:upper:] <<< "${prodosArg%#*}" ) - IFS_orig="$IFS"; IFS="/"; - prodosPathParts="$prodosPath" - for thisProdosPathPart in $prodosPathParts; do - if [[ ${#thisProdosPathPart} -gt 15 || ! $(grep ^[A-Z][0-9A-Z\.]*$ <<< $thisProdosPathPart) ]]; then - echoerr "Invalid ProDOS name: $prodosPath"; exit 1; - fi - done - IFS="$IFS_orig" + # test ProDOS name validity + prodosPath=$(tr [:lower:] [:upper:] <<< "${prodosArg%#*}" ) + IFS_orig="$IFS"; IFS="/"; + prodosPathParts="$prodosPath" + for thisProdosPathPart in $prodosPathParts; do + if [[ ${#thisProdosPathPart} -gt 15 || ! $(grep ^[A-Z][0-9A-Z\.]*$ <<< $thisProdosPathPart) ]]; then + echoerr "Invalid ProDOS name: $prodosPath"; exit 1; + fi + done + IFS="$IFS_orig" - # filetype to name table - P_00=UNK; P_01=BAD; P_02=PCD; P_03=PTX; P_04=TXT; P_05=PDA; P_06=BIN; P_07=FNT; P_08=FOT; P_09=BA3; P_0a=DA3; P_0b=WPF; P_0c=SOS; P_0f=DIR; P_10=RPD; P_11=RPI; P_12=AFD; P_13=AFM; P_14=AFR; P_15=SCL; P_16=PFS; P_19=ADB; P_1a=AWP; P_1b=ASP; P_20=TDM; P_21=IPS; P_22=UPV; P_29=3SD; P_2a=8SC; P_2b=8OB; P_2c=8IC; P_2d=8LD; P_2e=P8C; P_41=OCR; P_42=FTD; P_50=GWP; P_51=GSS; P_52=GDB; P_53=DRW; P_54=GDP; P_55=HMD; P_56=EDU; P_57=STN; P_58=HLP; P_59=COM; P_5a=CFG; P_5b=ANM; P_5c=MUM; P_5d=ENT; P_5e=DVU; P_60=PRE; P_6b=BIO; P_6d=DVR; P_6e=PRE; P_6f=HDV; P_80=GEZ; P_81=GE1; P_82=GEO; P_83=GE3; P_84=GE4; P_85=GE5; P_86=GE6; P_87=GE7; P_88=GE8; P_89=GE9; P_8a=GEA; P_8b=GEB; P_8c=GEC; P_8d=GED; P_8e=GEE; P_8f=GEF; P_a0=WP_; P_ab=GSB; P_ac=TDF; P_ad=BDF; P_b0=SRC; P_b1=OBJ; P_b2=LIB; P_b3=S16; P_b4=RTL; P_b5=EXE; P_b6=STR; P_b7=TSF; P_b8=NDA; P_b9=CDA; P_ba=TOL; P_bb=DRV; P_bc=LDF; P_bd=FST; P_bf=DOC; P_c0=PNT; P_c1=PIC; P_c2=ANI; P_c3=PAL; P_c5=OOG; P_c6=SCR; P_c7=CDV; P_c8=FON; P_c9=FND; P_ca=ICN; P_d5=MUS; P_d6=INS; P_d7=MDI; P_d8=SND; P_db=DBM; P_e0=SHK; P_e2=DTS; P_ee=R16; P_ef=PAS; P_f0=CMD; P_f9=P16; P_fa=INT; P_fb=IVR; P_fc=BAS; P_fd=VAR; P_fe=REL; P_ff=SYS; + # filetype to name table + P_00=UNK; P_01=BAD; P_02=PCD; P_03=PTX; P_04=TXT; P_05=PDA; P_06=BIN; P_07=FNT; P_08=FOT; P_09=BA3; P_0a=DA3; P_0b=WPF; P_0c=SOS; P_0f=DIR; P_10=RPD; P_11=RPI; P_12=AFD; P_13=AFM; P_14=AFR; P_15=SCL; P_16=PFS; P_19=ADB; P_1a=AWP; P_1b=ASP; P_20=TDM; P_21=IPS; P_22=UPV; P_29=3SD; P_2a=8SC; P_2b=8OB; P_2c=8IC; P_2d=8LD; P_2e=P8C; P_41=OCR; P_42=FTD; P_50=GWP; P_51=GSS; P_52=GDB; P_53=DRW; P_54=GDP; P_55=HMD; P_56=EDU; P_57=STN; P_58=HLP; P_59=COM; P_5a=CFG; P_5b=ANM; P_5c=MUM; P_5d=ENT; P_5e=DVU; P_60=PRE; P_6b=BIO; P_6d=DVR; P_6e=PRE; P_6f=HDV; P_80=GEZ; P_81=GE1; P_82=GEO; P_83=GE3; P_84=GE4; P_85=GE5; P_86=GE6; P_87=GE7; P_88=GE8; P_89=GE9; P_8a=GEA; P_8b=GEB; P_8c=GEC; P_8d=GED; P_8e=GEE; P_8f=GEF; P_a0=WP_; P_ab=GSB; P_ac=TDF; P_ad=BDF; P_b0=SRC; P_b1=OBJ; P_b2=LIB; P_b3=S16; P_b4=RTL; P_b5=EXE; P_b6=STR; P_b7=TSF; P_b8=NDA; P_b9=CDA; P_ba=TOL; P_bb=DRV; P_bc=LDF; P_bd=FST; P_bf=DOC; P_c0=PNT; P_c1=PIC; P_c2=ANI; P_c3=PAL; P_c5=OOG; P_c6=SCR; P_c7=CDV; P_c8=FON; P_c9=FND; P_ca=ICN; P_d5=MUS; P_d6=INS; P_d7=MDI; P_d8=SND; P_db=DBM; P_e0=SHK; P_e2=DTS; P_ee=R16; P_ef=PAS; P_f0=CMD; P_f9=P16; P_fa=INT; P_fb=IVR; P_fc=BAS; P_fd=VAR; P_fe=REL; P_ff=SYS; - # process filetype - if [[ ! $AD && ! $EX ]]; then # no resource fork or metadata - [[ ${3:0:2} == "0x" ]] && ftArg="\$${3:2}" || ftArg="$3" - auxType="$4" + # process filetype + if [[ ! $AD && ! $EX ]]; then # no resource fork or metadata + [[ ${3:0:2} == "0x" ]] && ftArg="\$${3:2}" || ftArg="$3" + auxType="$4" - # assume BIN/$2000 if filetype omitted - if [[ ! $ftArg ]]; then - ft="BIN" - auxType="\$2000" - # accept hex or decimal number for file type - elif [[ ( ${ftArg:0:1} == '$' && ${#ftArg} -eq 3 ) || $(grep [0-9] <<< ${ftArg:0:1}) ]]; then - if [[ ${ftArg:0:1} == '$' ]]; then - fc=$(tr [:upper:] [:lower:] <<< ${ftArg:1:2}) - else - fc=$(printf %02X "$ftArg" | tr [:upper:] [:lower:]) - fi - ftVar="P_$fc"; - [[ ${!ftVar} ]] && ft=${!ftVar} || ft="\$$fc"; - else - ft="$ftArg" - fi + # assume BIN/$2000 if filetype omitted + if [[ ! $ftArg ]]; then + ft="BIN" + auxType="\$2000" + # accept hex or decimal number for file type + elif [[ ( ${ftArg:0:1} == '$' && ${#ftArg} -eq 3 ) || $(grep [0-9] <<< ${ftArg:0:1}) ]]; then + if [[ ${ftArg:0:1} == '$' ]]; then + fc=$(tr [:upper:] [:lower:] <<< ${ftArg:1:2}) + else + fc=$(printf %02X "$ftArg" | tr [:upper:] [:lower:]) + fi + ftVar="P_$fc"; + [[ ${!ftVar} ]] && ft=${!ftVar} || ft="\$$fc"; + else + ft="$ftArg" + fi - # set auxtype to $0801 for Applesoft programs if not specified - [[ $ft == "BAS" && ! $auxType ]] && auxType="\$0801" + # set auxtype to $0801 for Applesoft programs if not specified + [[ $ft == "BAS" && ! $auxType ]] && auxType="\$0801" - # test for absence of stdin [[ -t 0 ]] and if absent use ProDOS name - if [[ -t 0 ]]; then - [[ ! -f $prodosArg ]] && { echoerr "$prodosArg not found."; exit 1; } - $ac -d "$imageArg" $prodosPath &> /dev/null - $ac -p "$imageArg" $prodosPath $ft $auxType < $prodosArg 2> $acmdStdErr - else - $ac -d "$imageArg" $prodosPath &> /dev/null - $ac -p "$imageArg" $prodosPath $ft $auxType 2> $acmdStdErr - fi - else # AppleDouble or nulib extended, get resource fork and file metadata from header file + # test for absence of stdin [[ -t 0 ]] and if absent use ProDOS name + if [[ -t 0 ]]; then + [[ ! -f $prodosArg ]] && { echoerr "$prodosArg not found."; exit 1; } + $ac -d "$imageArg" $prodosPath &> /dev/null + $ac -p "$imageArg" $prodosPath $ft $auxType < $prodosArg 2> $acmdStdErr + else + $ac -d "$imageArg" $prodosPath &> /dev/null + $ac -p "$imageArg" $prodosPath $ft $auxType 2> $acmdStdErr + fi + else # AppleDouble or nulib extended, get resource fork and file metadata from header file - [[ ! -f $prodosArg ]] && { echoerr "$prodosArg not found."; exit 1; } - [[ $AD && ! -f $rFile ]] && { echoerr "Not an AppleDouble file: $rFile"; exit 1; } + [[ ! -f $prodosArg ]] && { echoerr "$prodosArg not found."; exit 1; } + [[ $AD && ! -f $rFile ]] && { echoerr "Not an AppleDouble file: $rFile"; exit 1; } - if [[ $AD ]]; then - # get metadata from AppleDouble header - [[ $(dd if="$rFile" bs=1 count=1 skip=741 2> /dev/null | wc -c) -gt 0 ]] && isExtFile=1 || isExtFile= - fileData=$(dd if="$rFile" bs=1 count=24 skip=637 2> /dev/null | xxd -p | tr -d '\n') - ftVar="P_${fileData:34:2}"; - auxType="\$"${fileData:36:4} - cDateTime=$(printf %d 0x${fileData:0:8}) - mDateTime=$(printf %d 0x${fileData:8:8}) - [[ $(printf %d 0x"${fileData:0:2}") -gt 127 ]] && (( cDateTime-=4294967296 )) # handle negative hex number - [[ $(printf %d 0x"${fileData:8:2}") -gt 127 ]] && (( mDateTime-=4294967296 )) # handle negative hex number - (( cDateTime+=946684800 )) # convert AD timestamp to Unix timestamp - (( mDateTime+=946684800 )) # convert AD timestamp to Unix timestamp - else # EX - # get metadata from file info - [[ -f "$rFile" ]] && isExtFile=1 || isExtFile= - ftVar="P_${prodosArg: -6:2}" - auxType="\$"${prodosArg: -4} - if [[ $osx ]]; then - mDateTime=$(stat -f "%m" "$prodosArg") - else - mDateTime=$(stat -c %Y "$prodosArg") - fi - cDateTime=$mDateTime - fi - [[ ${!ftVar} ]] && ft=${!ftVar} || ft="\$$fc"; # set file type - # convert unix timestamp to ProDOS bitfield yyyyyyymmmmddddd 000hhhhh00mmmmmm - cDateFields=($(date -d @$cDateTime +"%y %m %d %H %M" 2> /dev/null)) - [[ ! $cDateFields ]] && cDateFields=($(date -r $cDateTime +"%y %m %d %H %M")) # OS X/BSD - mDateFields=($(date -d @$mDateTime +"%y %m %d %H %M" 2> /dev/null)) - [[ ! $mDateFields ]] && mDateFields=($(date -r $mDateTime +"%y %m %d %H %M")) # OS X/BSD - cDateTimeHex=$(printf %08X $(( 2#$(printf %07d $(decToBin ${cDateFields[0]}))$(printf %04d $(decToBin ${cDateFields[1]}))$(printf %05d $(decToBin ${cDateFields[2]}))$(printf %08d $(decToBin ${cDateFields[3]}))$(printf %08d $(decToBin ${cDateFields[4]})) ))) - cDateTimeHex=${cDateTimeHex:2:2}${cDateTimeHex:0:2}${cDateTimeHex:6:2}${cDateTimeHex:4:2} - mDateTimeHex=$(printf %08X $(( 2#$(printf %07d $(decToBin ${mDateFields[0]}))$(printf %04d $(decToBin ${mDateFields[1]}))$(printf %05d $(decToBin ${mDateFields[2]}))$(printf %08d $(decToBin ${mDateFields[3]}))$(printf %08d $(decToBin ${mDateFields[4]})) ))) - mDateTimeHex=${mDateTimeHex:2:2}${mDateTimeHex:0:2}${mDateTimeHex:6:2}${mDateTimeHex:4:2} + if [[ $AD ]]; then + # get metadata from AppleDouble header + [[ $(dd if="$rFile" bs=1 count=1 skip=741 2> /dev/null | wc -c) -gt 0 ]] && isExtFile=1 || isExtFile= + fileData=$(dd if="$rFile" bs=1 count=24 skip=637 2> /dev/null | xxd -p | tr -d '\n') + ftVar="P_${fileData:34:2}"; + auxType="\$"${fileData:36:4} + cDateTime=$(printf %d 0x${fileData:0:8}) + mDateTime=$(printf %d 0x${fileData:8:8}) + [[ $(printf %d 0x"${fileData:0:2}") -gt 127 ]] && (( cDateTime-=4294967296 )) # handle negative hex number + [[ $(printf %d 0x"${fileData:8:2}") -gt 127 ]] && (( mDateTime-=4294967296 )) # handle negative hex number + (( cDateTime+=946684800 )) # convert AD timestamp to Unix timestamp + (( mDateTime+=946684800 )) # convert AD timestamp to Unix timestamp + else # EX + # get metadata from file info + [[ -f "$rFile" ]] && isExtFile=1 || isExtFile= + ftVar="P_${prodosArg: -6:2}" + auxType="\$"${prodosArg: -4} + if [[ $osx ]]; then + mDateTime=$(stat -f "%m" "$prodosArg") + else + mDateTime=$(stat -c %Y "$prodosArg") + fi + cDateTime=$mDateTime + fi + [[ ${!ftVar} ]] && ft=${!ftVar} || ft="\$$fc"; # set file type + # convert unix timestamp to ProDOS bitfield yyyyyyymmmmddddd 000hhhhh00mmmmmm + cDateFields=($(date -d @$cDateTime +"%y %m %d %H %M" 2> /dev/null)) + [[ ! $cDateFields ]] && cDateFields=($(date -r $cDateTime +"%y %m %d %H %M")) # OS X/BSD + mDateFields=($(date -d @$mDateTime +"%y %m %d %H %M" 2> /dev/null)) + [[ ! $mDateFields ]] && mDateFields=($(date -r $mDateTime +"%y %m %d %H %M")) # OS X/BSD + cDateTimeHex=$(printf %08X $(( 2#$(printf %07d $(decToBin ${cDateFields[0]}))$(printf %04d $(decToBin ${cDateFields[1]}))$(printf %05d $(decToBin ${cDateFields[2]}))$(printf %08d $(decToBin ${cDateFields[3]}))$(printf %08d $(decToBin ${cDateFields[4]})) ))) + cDateTimeHex=${cDateTimeHex:2:2}${cDateTimeHex:0:2}${cDateTimeHex:6:2}${cDateTimeHex:4:2} + mDateTimeHex=$(printf %08X $(( 2#$(printf %07d $(decToBin ${mDateFields[0]}))$(printf %04d $(decToBin ${mDateFields[1]}))$(printf %05d $(decToBin ${mDateFields[2]}))$(printf %08d $(decToBin ${mDateFields[3]}))$(printf %08d $(decToBin ${mDateFields[4]})) ))) + mDateTimeHex=${mDateTimeHex:2:2}${mDateTimeHex:0:2}${mDateTimeHex:6:2}${mDateTimeHex:4:2} - # create forks and file entry - ### RIGHT HERE PROBLEMS IF #000000 specified and maybe if not - fileName="${prodosPath##*/}" - if [[ $isExtFile ]]; then - dfName=X$(printf %04X $RANDOM $RANDOM $RANDOM) - while [[ ! $rfName || $rfName == $dfName ]]; do - rfName=X$(printf %04X $RANDOM $RANDOM $RANDOM) - done - while [[ $fileName == "${prodosPath##*/}" || $rfName == $fileName || $dfName == $fileName ]]; do - fileName=X$(printf %04X $RANDOM $RANDOM $RANDOM) - done - $ac -d "$imageArg" "${prodosArgParent}$dfName" 2> /dev/null - dd if="$prodosArg" 2> /dev/null | $ac -p "$imageArg" "${prodosArgParent}$dfName" $00 2> $acmdStdErr - $ac -d "$imageArg" "${prodosArgParent}$rfName" 2> /dev/null - dd if="$rFile" bs=1 skip=$(( 0$AD ? 741 : 0 )) 2> /dev/null | $ac -p "$imageArg" "${prodosArgParent}$rfName" $00 2> $acmdStdErr - fi + # create forks and file entry + ### RIGHT HERE PROBLEMS IF #000000 specified and maybe if not + fileName="${prodosPath##*/}" + if [[ $isExtFile ]]; then + dfName=X$(printf %04X $RANDOM $RANDOM $RANDOM) + while [[ ! $rfName || $rfName == $dfName ]]; do + rfName=X$(printf %04X $RANDOM $RANDOM $RANDOM) + done + while [[ $fileName == "${prodosPath##*/}" || $rfName == $fileName || $dfName == $fileName ]]; do + fileName=X$(printf %04X $RANDOM $RANDOM $RANDOM) + done + $ac -d "$imageArg" "${prodosArgParent}$dfName" 2> /dev/null + dd if="$prodosArg" 2> /dev/null | $ac -p "$imageArg" "${prodosArgParent}$dfName" $00 2> $acmdStdErr + $ac -d "$imageArg" "${prodosArgParent}$rfName" 2> /dev/null + dd if="$rFile" bs=1 skip=$(( 0$AD ? 741 : 0 )) 2> /dev/null | $ac -p "$imageArg" "${prodosArgParent}$rfName" $00 2> $acmdStdErr + fi - # create file entry, then find it - $ac -d "$imageArg" "${prodosArgParent}$fileName" 2> /dev/null - [[ $isExtFile ]] && ddsrc="if=/dev/zero bs=512 count=1" || ddsrc="if=$prodosArg" - dd $ddsrc 2> /dev/null | $ac -p "$imageArg" "${prodosArgParent}$fileName" "$ft" "$auxType" 2> $acmdStdErr - # thx to http://unix.stackexchange.com/a/122945/99697 for perl alternative to broken --byte-offset in grep 2.5.1 (e.g. in OS X) - fileEntryOffset=$(perl -n0777e "print pos()-length('.$fileName') while /.$fileName/g" < "$imageArg") - fileEntry=$(dd if="$imageArg" bs=1 count=39 skip=$fileEntryOffset 2> /dev/null | xxd -p | tr -d '\n') + # create file entry, then find it + $ac -d "$imageArg" "${prodosArgParent}$fileName" 2> /dev/null + [[ $isExtFile ]] && ddsrc="if=/dev/zero bs=512 count=1" || ddsrc="if=$prodosArg" + dd $ddsrc 2> /dev/null | $ac -p "$imageArg" "${prodosArgParent}$fileName" "$ft" "$auxType" 2> $acmdStdErr + # thx to http://unix.stackexchange.com/a/122945/99697 for perl alternative to broken --byte-offset in grep 2.5.1 (e.g. in OS X) + fileEntryOffset=$(perl -n0777e "print pos()-length('.$fileName') while /.$fileName/g" < "$imageArg") + fileEntry=$(dd if="$imageArg" bs=1 count=39 skip=$fileEntryOffset 2> /dev/null | xxd -p | tr -d '\n') - if [[ $isExtFile ]]; then - extKeyBlockOffset=$(( ( ( $(printf %d 0x"${fileEntry:36:2}") * 256 ) + $(printf %d 0x"${fileEntry:34:2}") * 512 ) )) + if [[ $isExtFile ]]; then + extKeyBlockOffset=$(( ( ( $(printf %d 0x"${fileEntry:36:2}") * 256 ) + $(printf %d 0x"${fileEntry:34:2}") * 512 ) )) - # find data fork, copy storage type, key block, block size, length to extended key block mini-entry - # then mark as available/deleted - dfOffset=$(perl -n0777e "print pos()-length('.$dfName') while /.$dfName/g" < "$imageArg") - dfEntry=$(dd if="$imageArg" bs=1 count=39 skip=$dfOffset 2> /dev/null | xxd -p | tr -d '\n') - dfStorageType=$(printf %02X $(( $(printf %d 0x${dfEntry:0:2}) >> 4 )) ) - dfBlocksUsed=$(( ( $(printf %d 0x${dfEntry:40:2}) * 256 ) + $(printf %d 0x${dfEntry:38:2}) )) - dfInfo=${dfEntry:34:14} - echo -n -e \\x"$dfStorageType"$(sed 's/../\\x&/g' <<< $dfInfo) \ - | dd of="$imageArg" conv=notrunc bs=1 seek=$(( extKeyBlockOffset+0 )) 2> /dev/null - # mark as deleted - echo -n -e \\x0${dfEntry:1:1} \ - | dd of="$imageArg" conv=notrunc bs=1 seek=$(( dfOffset+0 )) 2> /dev/null + # find data fork, copy storage type, key block, block size, length to extended key block mini-entry + # then mark as available/deleted + dfOffset=$(perl -n0777e "print pos()-length('.$dfName') while /.$dfName/g" < "$imageArg") + dfEntry=$(dd if="$imageArg" bs=1 count=39 skip=$dfOffset 2> /dev/null | xxd -p | tr -d '\n') + dfStorageType=$(printf %02X $(( $(printf %d 0x${dfEntry:0:2}) >> 4 )) ) + dfBlocksUsed=$(( ( $(printf %d 0x${dfEntry:40:2}) * 256 ) + $(printf %d 0x${dfEntry:38:2}) )) + dfInfo=${dfEntry:34:14} + echo -n -e \\x"$dfStorageType"$(sed 's/../\\x&/g' <<< $dfInfo) \ + | dd of="$imageArg" conv=notrunc bs=1 seek=$(( extKeyBlockOffset+0 )) 2> /dev/null + # mark as deleted + echo -n -e \\x0${dfEntry:1:1} \ + | dd of="$imageArg" conv=notrunc bs=1 seek=$(( dfOffset+0 )) 2> /dev/null - # find resource fork, copy storage type, key block, block size, length to extended key block mini-entry - # then mark as available/deleted - rfOffset=$(perl -n0777e "print pos()-length('.$rfName') while /.$rfName/g" < "$imageArg") - rfEntry=$(dd if="$imageArg" bs=1 count=39 skip=$rfOffset 2> /dev/null | xxd -p | tr -d '\n') - rfStorageType=$(printf %02X $(( $(printf %d 0x${rfEntry:0:2}) >> 4 )) ) - rfBlocksUsed=$(( ( $(printf %d 0x${rfEntry:40:2}) * 256 ) + $(printf %d 0x${rfEntry:38:2}) )) - rfInfo=${rfEntry:34:14} - echo -n -e \\x"$rfStorageType"$(sed 's/../\\x&/g' <<< $rfInfo) \ - | dd of="$imageArg" conv=notrunc bs=1 seek=$(( extKeyBlockOffset+256 )) 2> /dev/null - # mark as deleted - echo -n -e \\x0${rfEntry:1:1} \ - | dd of="$imageArg" conv=notrunc bs=1 seek=$(( rfOffset+0 )) 2> /dev/null + # find resource fork, copy storage type, key block, block size, length to extended key block mini-entry + # then mark as available/deleted + rfOffset=$(perl -n0777e "print pos()-length('.$rfName') while /.$rfName/g" < "$imageArg") + rfEntry=$(dd if="$imageArg" bs=1 count=39 skip=$rfOffset 2> /dev/null | xxd -p | tr -d '\n') + rfStorageType=$(printf %02X $(( $(printf %d 0x${rfEntry:0:2}) >> 4 )) ) + rfBlocksUsed=$(( ( $(printf %d 0x${rfEntry:40:2}) * 256 ) + $(printf %d 0x${rfEntry:38:2}) )) + rfInfo=${rfEntry:34:14} + echo -n -e \\x"$rfStorageType"$(sed 's/../\\x&/g' <<< $rfInfo) \ + | dd of="$imageArg" conv=notrunc bs=1 seek=$(( extKeyBlockOffset+256 )) 2> /dev/null + # mark as deleted + echo -n -e \\x0${rfEntry:1:1} \ + | dd of="$imageArg" conv=notrunc bs=1 seek=$(( rfOffset+0 )) 2> /dev/null - # reduce active file count in directory by two - parentDirKeyBlockOffset=$(( ( ( $(printf %d 0x"${fileEntry:76:2}") * 256 ) + $(printf %d 0x"${fileEntry:74:2}") * 512 ) )) - fileCountHex=$(dd if="$imageArg" bs=1 count=2 skip=$((parentDirKeyBlockOffset+4+33)) 2> /dev/null | xxd -p) - fileCount=$(( ( $(printf %d 0x${fileCountHex:2:2}) * 256 ) + $(printf %d 0x${fileCountHex:0:2}) )) - fileCountHex=$(printf %04X $((fileCount - 2))) - echo -n -e \\x${fileCountHex:2:2}\\x${fileCountHex:0:2} \ - | dd of="$imageArg" conv=notrunc bs=1 seek=$((parentDirKeyBlockOffset+4+33)) 2> /dev/null + # reduce active file count in directory by two + parentDirKeyBlockOffset=$(( ( ( $(printf %d 0x"${fileEntry:76:2}") * 256 ) + $(printf %d 0x"${fileEntry:74:2}") * 512 ) )) + fileCountHex=$(dd if="$imageArg" bs=1 count=2 skip=$((parentDirKeyBlockOffset+4+33)) 2> /dev/null | xxd -p) + fileCount=$(( ( $(printf %d 0x${fileCountHex:2:2}) * 256 ) + $(printf %d 0x${fileCountHex:0:2}) )) + fileCountHex=$(printf %04X $((fileCount - 2))) + echo -n -e \\x${fileCountHex:2:2}\\x${fileCountHex:0:2} \ + | dd of="$imageArg" conv=notrunc bs=1 seek=$((parentDirKeyBlockOffset+4+33)) 2> /dev/null - # update extended file metadata + # update extended file metadata - # storage type (5), name length, name - name="${prodosPath##*/}" - nameLen=${#name} - nameHeader=$(printf %02X $((nameLen + 80)) ) - nameField=$(echo -n $name | xxd -p | tr -d '\n' | sed -e :a -e 's/^.\{1,29\}$/&00/;ta') + # storage type (5), name length, name + name="${prodosPath##*/}" + nameLen=${#name} + nameHeader=$(printf %02X $((nameLen + 80)) ) + nameField=$(echo -n $name | xxd -p | tr -d '\n' | sed -e :a -e 's/^.\{1,29\}$/&00/;ta') - # blocks used - blocksUsed=$(( dfBlocksUsed + rfBlocksUsed + 1 )) + # blocks used + blocksUsed=$(( dfBlocksUsed + rfBlocksUsed + 1 )) - # store updated metadata - fileEntry=${nameHeader}${nameField}${fileEntry:32} - fi + # store updated metadata + fileEntry=${nameHeader}${nameField}${fileEntry:32} + fi - # put creation and modified date in file entry - fileEntry=${fileEntry:0:48}${cDateTimeHex}${fileEntry:56:10}${mDateTimeHex}${fileEntry:74:4} + # put creation and modified date in file entry + fileEntry=${fileEntry:0:48}${cDateTimeHex}${fileEntry:56:10}${mDateTimeHex}${fileEntry:74:4} - # put casemask for mixed case filename in file entry - [[ $EX ]] && prodosArg="${prodosArg%#*}" - if [[ "${prodosPath##*/}" != "${prodosArg##*/}" ]]; then # mixed case - caseMaskDec=32768 - mixedName="${prodosArg##*/}" - [[ $EX ]] && mixedName="${mixedName%#*}" - for (( i=0; i<${#mixedName}; i++ )); do - [[ "${mixedName:$i:1}" == $(tr [:lower:] [:upper:] <<< "${mixedName:$i:1}") ]] # $? == 0 means uppercase - (( caseMaskDec+=$(( $? * (2**(14-i)) )) )) - done - caseMaskHex=$(printf %04X $caseMaskDec) - fileEntry=${fileEntry:0:56}${caseMaskHex:2:2}${caseMaskHex:0:2}${fileEntry:60} - fi + # put casemask for mixed case filename in file entry + [[ $EX ]] && prodosArg="${prodosArg%#*}" + if [[ "${prodosPath##*/}" != "${prodosArg##*/}" ]]; then # mixed case + caseMaskDec=32768 + mixedName="${prodosArg##*/}" + [[ $EX ]] && mixedName="${mixedName%#*}" + for (( i=0; i<${#mixedName}; i++ )); do + [[ "${mixedName:$i:1}" == $(tr [:lower:] [:upper:] <<< "${mixedName:$i:1}") ]] # $? == 0 means uppercase + (( caseMaskDec+=$(( $? * (2**(14-i)) )) )) + done + caseMaskHex=$(printf %04X $caseMaskDec) + fileEntry=${fileEntry:0:56}${caseMaskHex:2:2}${caseMaskHex:0:2}${fileEntry:60} + fi - # write updated metadata to file entry - echo -n -e $(sed 's/../\\x&/g' <<< $fileEntry) | dd of="$imageArg" bs=1 conv=notrunc seek=$fileEntryOffset 2> /dev/null - fi - fi + # write updated metadata to file entry + echo -n -e $(sed 's/../\\x&/g' <<< $fileEntry) | dd of="$imageArg" bs=1 conv=notrunc seek=$fileEntryOffset 2> /dev/null + fi + fi else - imageArg="$2" - $ac "$@" 2> $acmdStdErr + imageArg="$2" + $ac "$@" 2> $acmdStdErr fi diff --git a/setup/adtpro-start.txt b/setup/adtpro-start.txt old mode 100644 new mode 100755 index 617b574..46c6294 --- a/setup/adtpro-start.txt +++ b/setup/adtpro-start.txt @@ -1,34 +1,34 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # don't do anything if ADTPro is already running if [[ $(ps aux | grep [A]DTPro) ]]; then - 1&>2 echo "ADTPro server is already running." + 1&>2 echo "ADTPro server is already running." else - # look for eligible USB-to-serial adapter - ttyUSB= - # if lower USB port - if [[ -c /dev/ttyUSBlower ]]; then - ttyUSB=ttyUSBlower - # if hub in lower port, use lowest numbered port on hub - elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 0 ]]; then - ttyUSB=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | head -1 | cut -c 6-) - # if hub in upper port with multiple adapters, use lowest numbered port on hub - elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 1 ]]; then - ttyUSB=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | head -1 | cut -c 6-) - fi + # look for eligible USB-to-serial adapter + ttyUSB= + # if lower USB port + if [[ -c /dev/ttyUSBlower ]]; then + ttyUSB=ttyUSBlower + # if hub in lower port, use lowest numbered port on hub + elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 0 ]]; then + ttyUSB=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | head -1 | cut -c 6-) + # if hub in upper port with multiple adapters, use lowest numbered port on hub + elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 1 ]]; then + ttyUSB=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | head -1 | cut -c 6-) + fi - if [[ $ttyUSB ]]; then - echo -n "Please wait..." - sudo nohup adtpro.sh headless serial &> /dev/null - echo "ok." - else - 1>&2 echo "No USB-to-serial adapter found in the lower USB port, or" - 1>&2 echo " a hub on the lower USB port, or the lowest-numbered port" - 1>&2 echo " of a hub on the upper USB port. Not starting ADTPro server." - fi + if [[ $ttyUSB ]]; then + echo -n "Please wait..." + sudo nohup adtpro.sh headless serial &> /dev/null + echo "ok." + else + 1>&2 echo "No USB-to-serial adapter found in the lower USB port, or" + 1>&2 echo " a hub on the lower USB port, or the lowest-numbered port" + 1>&2 echo " of a hub on the upper USB port. Not starting ADTPro server." + fi fi diff --git a/setup/adtpro.sh.txt b/setup/adtpro.sh.txt old mode 100644 new mode 100755 index 9104643..030b863 --- a/setup/adtpro.sh.txt +++ b/setup/adtpro.sh.txt @@ -1,15 +1,15 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # ADTPro - *nix startup shell script # # Note: -# Invoke with the name of the communications button to push -# in order to start with that mode active (i.e. './adtpro.sh ethernet') +# Invoke with the name of the communications button to push +# in order to start with that mode active (i.e. './adtpro.sh ethernet') # # You can set two variables here: -# 1. $MY_JAVA_HOME - to pick a particular java to run under -# 2. $ADTPRO_HOME - to say where you installed ADTPro +# 1. $MY_JAVA_HOME - to pick a particular java to run under +# 2. $ADTPRO_HOME - to say where you installed ADTPro # # Set default ADTPRO_HOME to be the fully qualified # current working directory. @@ -26,9 +26,9 @@ # export ADTPRO_HOME=~/myuser/adtpro usageExit () { - echo "usage:" 1>&2 - echo "adtpro.sh [headless] [serial|ethernet|audio|localhost] [serialPortName]" 1>&2 - exit 1 + echo "usage:" 1>&2 + echo "adtpro.sh [headless] [serial|ethernet|audio|localhost] [serialPortName]" 1>&2 + exit 1 } export ADTPRO_HOME=/usr/local/adtpro @@ -40,75 +40,75 @@ OS_ARCH=`uname -m` [[ $1 == "headless" ]] && { headless=1; shift; } || headless= if [[ $1 && ( $1 != "serial" && $1 != "ethernet" && $1 != "audio" && $1 != "localhost" ) ]]; then - usageExit + usageExit fi # For Linux, use this: if [ "$OS" = "Linux" ]; then - serialPortName= - if [[ $1 == "serial" ]]; then - if [[ $2 ]]; then - serialPortName="$2" - [[ ${serialPortName:0:5} == "/dev/" ]] && serialPortName=${serialPortName:5} - if [[ ! -c /dev/$serialPortName ]]; then - echo "Serial port $serialPortName not found." 1>&2 - usageExit - fi - elif [[ -c /dev/ttyUSBlower ]]; then - serialPortName=ttyUSBlower - elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 0 ]]; then - serialPortName=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | head -1 | cut -c 6-) - elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 1 ]]; then - serialPortName=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | head -1 | cut -c 6-) - else - echo "No eligible USB-to-serial adapter found." 1>&2 - echo "Possible ports:" 1>&2 - echo " lower USB port" - echo " any port on lower USB hub with no other adapters" - echo " lowest port on USB hub on upper or lower USB port with multiple adapters" - usageExit - fi - fi + serialPortName= + if [[ $1 == "serial" ]]; then + if [[ $2 ]]; then + serialPortName="$2" + [[ ${serialPortName:0:5} == "/dev/" ]] && serialPortName=${serialPortName:5} + if [[ ! -c /dev/$serialPortName ]]; then + echo "Serial port $serialPortName not found." 1>&2 + usageExit + fi + elif [[ -c /dev/ttyUSBlower ]]; then + serialPortName=ttyUSBlower + elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 0 ]]; then + serialPortName=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | head -1 | cut -c 6-) + elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 1 ]]; then + serialPortName=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | head -1 | cut -c 6-) + else + echo "No eligible USB-to-serial adapter found." 1>&2 + echo "Possible ports:" 1>&2 + echo " lower USB port" + echo " any port on lower USB hub with no other adapters" + echo " lowest port on USB hub on upper or lower USB port with multiple adapters" + usageExit + fi + fi - if [[ $(grep CommPort= /usr/local/adtpro/disks/ADTPro.properties) ]]; then - if [[ $serialPortName ]]; then - sed -i "s/^CommPort=.*$/CommPort=\/dev\/$serialPortName/" /usr/local/adtpro/disks/ADTPro.properties &> /dev/null - else - serialPortName=$(grep 'CommPort=/dev/' /usr/local/adtpro/disks/ADTPro.properties 2> /dev/null | cut -f 3 -d '/') - fi - else - echo -e "#ADTPro.properties\n#$(date)\nCommPortSpeed=115200\nCommPortBootstrapSpeed=2400\nCommPort=/dev/$serialPortName\nCommPortBootstrapPacing=250\nHardwareHandshaking=false\nSerialIPHost=localhost\nSerialIPPort=1977" > /usr/local/adtpro/disks/ADTPro.properties - chmod ugo+w /usr/local/adtpro/disks/ADTPro.properties - fi + if [[ $(grep CommPort= /usr/local/adtpro/disks/ADTPro.properties) ]]; then + if [[ $serialPortName ]]; then + sed -i "s/^CommPort=.*$/CommPort=\/dev\/$serialPortName/" /usr/local/adtpro/disks/ADTPro.properties &> /dev/null + else + serialPortName=$(grep 'CommPort=/dev/' /usr/local/adtpro/disks/ADTPro.properties 2> /dev/null | cut -f 3 -d '/') + fi + else + echo -e "#ADTPro.properties\n#$(date)\nCommPortSpeed=115200\nCommPortBootstrapSpeed=2400\nCommPort=/dev/$serialPortName\nCommPortBootstrapPacing=250\nHardwareHandshaking=false\nSerialIPHost=localhost\nSerialIPPort=1977" > /usr/local/adtpro/disks/ADTPro.properties + chmod ugo+w /usr/local/adtpro/disks/ADTPro.properties + fi - ADTPRO_EXTRA_JAVA_PARMS="-Dgnu.io.rxtx.SerialPorts=/dev/$serialPortName" + ADTPRO_EXTRA_JAVA_PARMS="-Dgnu.io.rxtx.SerialPorts=/dev/$serialPortName" - if [ -f /usr/bin/raspi-config ]; then - export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/arm - elif [ "$OS_ARCH" = "i686" ]; then - export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/i686-pc-linux-gnu - else - if [ "$OS_ARCH" = "i386" ]; then - export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/i686-pc-linux-gnu - else - export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/x86_64-unknown-linux-gnu - fi - fi + if [ -f /usr/bin/raspi-config ]; then + export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/arm + elif [ "$OS_ARCH" = "i686" ]; then + export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/i686-pc-linux-gnu + else + if [ "$OS_ARCH" = "i386" ]; then + export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/i686-pc-linux-gnu + else + export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/x86_64-unknown-linux-gnu + fi + fi fi # For OSX, use this: if [ "$OS" = "Darwin" ]; then - if [ "$OS_ARCH" = "powerpc" ]; then - export RXTXLIB=lib/rxtx/rxtx-2.1-7-bins-r2/Mac_OS_X - else - export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/mac-10.5 - fi + if [ "$OS_ARCH" = "powerpc" ]; then + export RXTXLIB=lib/rxtx/rxtx-2.1-7-bins-r2/Mac_OS_X + else + export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/mac-10.5 + fi fi # For Solaris, use this: if [ "$OS" = "SunOS" ]; then - export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/sparc-sun-solaris2.10-32 + export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/sparc-sun-solaris2.10-32 fi # Set up the library location. @@ -116,29 +116,29 @@ export TWEAK1="-Djava.library.path=" export TWEAK=$TWEAK1$ADTPRO_HOME/$RXTXLIB if [[ $headless ]]; then - if [[ ! $1 || ! -f /usr/bin/xvfb-run ]]; then - if [[ ! -f /usr/bin/xvfb-run ]]; then - echo "Headless operation requires xvfb." - usageExit - else - echo "Headless operation requires a communication mode (e.g. serial)." - usageExit - fi - exit 1 - else - HEADLESS="xvfb-run --auto-servernum " - fi + if [[ ! $1 || ! -f /usr/bin/xvfb-run ]]; then + if [[ ! -f /usr/bin/xvfb-run ]]; then + echo "Headless operation requires xvfb." + usageExit + else + echo "Headless operation requires a communication mode (e.g. serial)." + usageExit + fi + exit 1 + else + HEADLESS="xvfb-run --auto-servernum " + fi fi if [[ $serialPortName && $(ps aux | grep "/sbin/getty.*$serialPortName") ]]; then - sudo pkill -f "/sbin/getty.*$serialPortName" + sudo pkill -f "/sbin/getty.*$serialPortName" fi sudo pkill -f [A]DTPro cd "$ADTPRO_HOME"/disks $HEADLESS"$MY_JAVA_HOME"java -Xms256m -Xmx512m "$TWEAK" $ADTPRO_EXTRA_JAVA_PARMS -cp ../lib/ADTPro.jar:../"$RXTXLIB"/../RXTXcomm.jar:../lib/AppleCommander/AppleCommander-ac.jar org.adtpro.ADTPro $* & if [[ $1 == "serial" ]]; then - echo "Starting up on interface $serialPortName. Please wait..." + echo "Starting up on interface $serialPortName. Please wait..." fi if [ -t 0 ]; then - sleep 30 + sleep 30 fi diff --git a/setup/baud.txt b/setup/baud.txt old mode 100644 new mode 100755 index 9e15f8e..2f46e9b --- a/setup/baud.txt +++ b/setup/baud.txt @@ -1,38 +1,38 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: isSystemd= isSysVInit= # If you really want something else, *you* maintain it! if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then - gettyFile="/etc/systemd/system/getty.target.wants/usbgetty@.service" + gettyFile="/etc/systemd/system/getty.target.wants/usbgetty@.service" elif [[ -f /etc/inittab ]]; then - gettyFile="/etc/inittab" + gettyFile="/etc/inittab" fi if [[ $1 == "-d" ]]; then - shift - setgetty=1 + shift + setgetty=1 else - setgetty= + setgetty= fi if [[ $1 -ne 300 && $1 -ne 1200 && $1 -ne 2400 && $1 -ne 4800 && $1 -ne 9600 && $1 -ne 19200 && $1 -ne 38400 && $1 -ne 57600 && $1 -ne 115200 ]]; then - echo 'Usage: baud [-d] 300|1200|2400|4800|9600|19200|38400|57600|115200'; - echo ' -d sets default speed for all serial port shells (takes effect on logout)' - echo ' omitting -d makes change temporary and immediate' + echo 'Usage: baud [-d] 300|1200|2400|4800|9600|19200|38400|57600|115200'; + echo ' -d sets default speed for all serial port shells (takes effect on logout)' + echo ' omitting -d makes change temporary and immediate' else - if [[ $setgetty ]]; then - sudo sed -i "s/ttyAMA0 .* /ttyAMA0 $1 /" $gettyFile; - sudo sed -i "s/ttyAMA0,[0-9]*/ttyAMA0,$1/g" /boot/cmdline.txt; - sudo sed -i "s/\(ttyUSB.*\) .* /\1 $1 /g" $gettyFile; - sudo init q; - sudo pkill -f "/sbin/getty" - else - if [[ $(tty | grep tty) ]]; then - stty -F $(tty) $1 - fi - fi + if [[ $setgetty ]]; then + sudo sed -i "s/ttyAMA0 .* /ttyAMA0 $1 /" $gettyFile; + sudo sed -i "s/ttyAMA0,[0-9]*/ttyAMA0,$1/g" /boot/cmdline.txt; + sudo sed -i "s/\(ttyUSB.*\) .* /\1 $1 /g" $gettyFile; + sudo init q; + sudo pkill -f "/sbin/getty" + else + if [[ $(tty | grep tty) ]]; then + stty -F $(tty) $1 + fi + fi fi echo -e "$(tput bold)$(tty) current $(stty -a -F $(tty) | grep -o 'speed .* baud')$(tput sgr0)" diff --git a/setup/cppo.txt b/setup/cppo.txt old mode 100644 new mode 100755 index 07e83fd..da1537e --- a/setup/cppo.txt +++ b/setup/cppo.txt @@ -1,5 +1,5 @@ #!/usr/bin/env python -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=python: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=python: """cppo: Copy/catalog files from a ProDOS/DOS 3.3/ShrinkIt image/archive. @@ -47,7 +47,7 @@ import tempfile b'ERROR: cppo requires Python 2.6 or later, including 3.x.' class Globals(object): - pass + pass g = Globals() @@ -87,36 +87,36 @@ g.D33 = 0 # (DOS 3.3 image source, selected automatically) # functions def pdosDateToUnixDate(arg1): - # input: ProDOS date/time bit sequence string in format: - # "yyyyyyymmmmddddd000hhhhh00mmmmmm" (ustr) - # output: seconds since Unix epoch (1-Jan-1970), - # or current date/time if no ProDOS date - year = (binToDec(slyce(arg1,0,7)) + 1900) - if (year < 1940): year += 100 - month = binToDec(slyce(arg1,7,4)) - day = binToDec(slyce(arg1,11,5)) - hour = binToDec(slyce(arg1,19,5)) - minute = binToDec(slyce(arg1,26,6)) - # print(year, month, day, hour, minute) - td = (datetime.datetime(year, month, day, hour, minute) - - datetime.datetime(1970,1,1)) - unixDate_naive = (td.days*24*60*60 + td.seconds) - td2 = (datetime.datetime.fromtimestamp(unixDate_naive) - - datetime.datetime.utcfromtimestamp(unixDate_naive)) - utcoffset = (td2.days*24*60*60 + td2.seconds) - # print(unixDate_naive - utcoffset) - return (unixDate_naive - utcoffset) # local time zone with DST + # input: ProDOS date/time bit sequence string in format: + # "yyyyyyymmmmddddd000hhhhh00mmmmmm" (ustr) + # output: seconds since Unix epoch (1-Jan-1970), + # or current date/time if no ProDOS date + year = (binToDec(slyce(arg1,0,7)) + 1900) + if (year < 1940): year += 100 + month = binToDec(slyce(arg1,7,4)) + day = binToDec(slyce(arg1,11,5)) + hour = binToDec(slyce(arg1,19,5)) + minute = binToDec(slyce(arg1,26,6)) + # print(year, month, day, hour, minute) + td = (datetime.datetime(year, month, day, hour, minute) - + datetime.datetime(1970,1,1)) + unixDate_naive = (td.days*24*60*60 + td.seconds) + td2 = (datetime.datetime.fromtimestamp(unixDate_naive) - + datetime.datetime.utcfromtimestamp(unixDate_naive)) + utcoffset = (td2.days*24*60*60 + td2.seconds) + # print(unixDate_naive - utcoffset) + return (unixDate_naive - utcoffset) # local time zone with DST def unixDateToADDate(arg1): - # input: seconds since Unix epoch (1-Jan-1970 00:00:00 GMT) - # output: seconds since Netatalk epoch (1-Jan-2000 00:00:00 GMT), - # in hex-ustr (big endian) - adDate = (arg1 - 946684800) - if (adDate < 0 ): - adDate += 4294967296 # to get negative hex number - adDateHex = to_hex(adDate).zfill(8).upper() - # print(arg1, adDate, adDateHex) - return adDateHex + # input: seconds since Unix epoch (1-Jan-1970 00:00:00 GMT) + # output: seconds since Netatalk epoch (1-Jan-2000 00:00:00 GMT), + # in hex-ustr (big endian) + adDate = (arg1 - 946684800) + if (adDate < 0 ): + adDate += 4294967296 # to get negative hex number + adDateHex = to_hex(adDate).zfill(8).upper() + # print(arg1, adDate, adDateHex) + return adDateHex # cppo support functions: # arg1: directory block or [T,S] containing file entry, or shk file dir path @@ -124,640 +124,640 @@ def unixDateToADDate(arg1): # returns byte position in disk image file def getStartPos(arg1, arg2): - if g.D33: - return (ts(arg1) + (35 * (arg2 % 7)) + 11) - else: # ProDOS - return ( (arg1 * 512) + - (39 * ((arg2 + (arg2 > 11)) % 13)) + - (4 if (arg2 > 11) else 43) ) + if g.D33: + return (ts(arg1) + (35 * (arg2 % 7)) + 11) + else: # ProDOS + return ( (arg1 * 512) + + (39 * ((arg2 + (arg2 > 11)) % 13)) + + (4 if (arg2 > 11) else 43) ) def getStorageType(arg1, arg2): - start = getStartPos(arg1, arg2) - firstByte = readcharDec(g.imageData, start) - return (int(firstByte != 255)*2 if g.D33 else (firstByte//16)) + start = getStartPos(arg1, arg2) + firstByte = readcharDec(g.imageData, start) + return (int(firstByte != 255)*2 if g.D33 else (firstByte//16)) def getFileName(arg1, arg2): - start = getStartPos(arg1, arg2) - if g.D33: - fileNameLo = bytearray() - fileNameHi = readchars(g.imageData, start+3, 30) - for b in fileNameHi: - fileNameLo += to_bytes(to_dec(b)-128) - fileName = bytes(fileNameLo).rstrip() - else: # ProDOS - firstByte = readcharDec(g.imageData, start) - entryType = (firstByte//16) - nameLength = (firstByte - entryType*16) - fileName = readchars(g.imageData, start+1, nameLength) - caseMask = getCaseMask(arg1, arg2) - if (not g.UC and caseMask != None): - for i in range(0, len(fileName)): - if (caseMask[i] == "1"): - fileName = (fileName[:i] + - fileName[i:i+1].lower() + - fileName[i+1:]) - return fileName + start = getStartPos(arg1, arg2) + if g.D33: + fileNameLo = bytearray() + fileNameHi = readchars(g.imageData, start+3, 30) + for b in fileNameHi: + fileNameLo += to_bytes(to_dec(b)-128) + fileName = bytes(fileNameLo).rstrip() + else: # ProDOS + firstByte = readcharDec(g.imageData, start) + entryType = (firstByte//16) + nameLength = (firstByte - entryType*16) + fileName = readchars(g.imageData, start+1, nameLength) + caseMask = getCaseMask(arg1, arg2) + if (not g.UC and caseMask != None): + for i in range(0, len(fileName)): + if (caseMask[i] == "1"): + fileName = (fileName[:i] + + fileName[i:i+1].lower() + + fileName[i+1:]) + return fileName def getCaseMask(arg1, arg2): - start = getStartPos(arg1, arg2) - caseMaskDec = (readcharDec(g.imageData, start+28) + - readcharDec(g.imageData, start+29)*256) - if (caseMaskDec < 32768): - return None - else: - return to_bin(caseMaskDec - 32768).zfill(15) + start = getStartPos(arg1, arg2) + caseMaskDec = (readcharDec(g.imageData, start+28) + + readcharDec(g.imageData, start+29)*256) + if (caseMaskDec < 32768): + return None + else: + return to_bin(caseMaskDec - 32768).zfill(15) def getFileType(arg1, arg2): - if g.SHK: - return arg2.split('#')[1][0:2] - start = getStartPos(arg1, arg2) - if g.D33: - d33fileType = readcharDec(g.imageData, start+2) - if ((d33fileType & 127) == 4): return '06' # BIN - elif ((d33fileType & 127) == 1): return 'FA' # INT - elif ((d33fileType & 127) == 2): return 'FC' # BAS - else: return '04' # TXT or other - else: # ProDOS - return readcharHex(g.imageData, start+16) + if g.SHK: + return arg2.split('#')[1][0:2] + start = getStartPos(arg1, arg2) + if g.D33: + d33fileType = readcharDec(g.imageData, start+2) + if ((d33fileType & 127) == 4): return '06' # BIN + elif ((d33fileType & 127) == 1): return 'FA' # INT + elif ((d33fileType & 127) == 2): return 'FC' # BAS + else: return '04' # TXT or other + else: # ProDOS + return readcharHex(g.imageData, start+16) def getAuxType(arg1, arg2): - if g.SHK: - return arg2.split('#')[1][2:6] - start = getStartPos(arg1, arg2) - if g.D33: - fileType = getFileType(arg1, arg2) - if (fileType == '06'): # BIN (B) - # file address is in first two bytes of file data - fileTSlist = [readcharDec(g.imageData, start+0), - readcharDec(g.imageData, start+1)] - fileStart = [readcharDec(g.imageData, ts(fileTSlist)+12), - readcharDec(g.imageData, ts(fileTSlist)+13)] - return (readcharHex(g.imageData, ts(fileStart)+1) + - readcharHex(g.imageData, ts(fileStart)+0)) - elif (fileType == 'FC'): # BAS (A) - return '0801' - elif (fileType == 'FA'): # INT (I) - return '9600' - else: # TXT (T) or other - return '0000' - else: # ProDOS - return (readcharHex(g.imageData, start+32) + - readcharHex(g.imageData, start+31)) + if g.SHK: + return arg2.split('#')[1][2:6] + start = getStartPos(arg1, arg2) + if g.D33: + fileType = getFileType(arg1, arg2) + if (fileType == '06'): # BIN (B) + # file address is in first two bytes of file data + fileTSlist = [readcharDec(g.imageData, start+0), + readcharDec(g.imageData, start+1)] + fileStart = [readcharDec(g.imageData, ts(fileTSlist)+12), + readcharDec(g.imageData, ts(fileTSlist)+13)] + return (readcharHex(g.imageData, ts(fileStart)+1) + + readcharHex(g.imageData, ts(fileStart)+0)) + elif (fileType == 'FC'): # BAS (A) + return '0801' + elif (fileType == 'FA'): # INT (I) + return '9600' + else: # TXT (T) or other + return '0000' + else: # ProDOS + return (readcharHex(g.imageData, start+32) + + readcharHex(g.imageData, start+31)) def getKeyPointer(arg1, arg2): - start = getStartPos(arg1, arg2) - if g.D33: - return [readcharDec(g.imageData, start+0), - readcharDec(g.imageData, start+1)] - else: # ProDOS - return (readcharDec(g.imageData, start+17) + - readcharDec(g.imageData, start+18)*256) + start = getStartPos(arg1, arg2) + if g.D33: + return [readcharDec(g.imageData, start+0), + readcharDec(g.imageData, start+1)] + else: # ProDOS + return (readcharDec(g.imageData, start+17) + + readcharDec(g.imageData, start+18)*256) def getFileLength(arg1, arg2): - start = getStartPos(arg1, arg2) - if g.D33: - fileType = getFileType(arg1, arg2) - fileTSlist = [readcharDec(g.imageData, start+0), - readcharDec(g.imageData, start+1)] - fileStart = [readcharDec(g.imageData, ts(fileTSlist)+12), - readcharDec(g.imageData, ts(fileTSlist)+13)] - if (fileType == '06'): # BIN (B) - # file length is in second two bytes of file data - return ((readcharDec(g.imageData, ts(fileStart)+2) + - readcharDec(g.imageData, ts(fileStart)+3)*256) + 4) - elif (fileType == 'FC' or fileType == 'FA'): # BAS (A) or INT (I) - # file length is in first two bytes of file data - return ((readcharDec(g.imageData, ts(fileStart)+0) + - readcharDec(g.imageData, ts(fileStart)+1)*256) + 2) - else: # TXT (T) or other - # sadly, we have to walk the whole file - # length is determined by sectors in TSlist, minus wherever - # anything after the first zero in the last sector - fileSize = 0 - lastTSpair = None - nextTSlistSector = fileTSlist - endFound = False - while not endFound: - pos = ts(nextTSlistSector) - for tsPos in range(12, 256, 2): - if ts(readcharDec(g.imageData, pos+tsPos+0), - readcharDec(g.imageData, pos+tsPos+1)) != 0: - fileSize += 256 - prevTSpair = [readcharDec(g.imageData, (pos+tsPos)+0), - readcharDec(g.imageData, (pos+tsPos)+1)] - else: - lastTSpair = prevTSpair - endFound = True - break - if not lastTSpair: - nextTSlistSector = [readcharDec(g.imageData, pos+1), - readcharDec(g.imageData, pos+2)] - if (nextTSlistSector[0]+nextTSlistSector[1] == 0): - lastTSpair = prevTSpair - endFound = True - break - fileSize -= 256 - pos = ts(prevTSpair) - # now find out where the file really ends by finding the last 00 - for offset in range(255, -1, -1): - #print("pos: " + to_hex(pos)) - if (readcharDec(g.imageData, pos+offset) != 0): - fileSize += (offset + 1) - break - return fileSize - else: # ProDOS - return (readcharDec(g.imageData, start+21) + - readcharDec(g.imageData, start+22)*256 + - readcharDec(g.imageData, start+23)*65536) + start = getStartPos(arg1, arg2) + if g.D33: + fileType = getFileType(arg1, arg2) + fileTSlist = [readcharDec(g.imageData, start+0), + readcharDec(g.imageData, start+1)] + fileStart = [readcharDec(g.imageData, ts(fileTSlist)+12), + readcharDec(g.imageData, ts(fileTSlist)+13)] + if (fileType == '06'): # BIN (B) + # file length is in second two bytes of file data + return ((readcharDec(g.imageData, ts(fileStart)+2) + + readcharDec(g.imageData, ts(fileStart)+3)*256) + 4) + elif (fileType == 'FC' or fileType == 'FA'): # BAS (A) or INT (I) + # file length is in first two bytes of file data + return ((readcharDec(g.imageData, ts(fileStart)+0) + + readcharDec(g.imageData, ts(fileStart)+1)*256) + 2) + else: # TXT (T) or other + # sadly, we have to walk the whole file + # length is determined by sectors in TSlist, minus wherever + # anything after the first zero in the last sector + fileSize = 0 + lastTSpair = None + nextTSlistSector = fileTSlist + endFound = False + while not endFound: + pos = ts(nextTSlistSector) + for tsPos in range(12, 256, 2): + if ts(readcharDec(g.imageData, pos+tsPos+0), + readcharDec(g.imageData, pos+tsPos+1)) != 0: + fileSize += 256 + prevTSpair = [readcharDec(g.imageData, (pos+tsPos)+0), + readcharDec(g.imageData, (pos+tsPos)+1)] + else: + lastTSpair = prevTSpair + endFound = True + break + if not lastTSpair: + nextTSlistSector = [readcharDec(g.imageData, pos+1), + readcharDec(g.imageData, pos+2)] + if (nextTSlistSector[0]+nextTSlistSector[1] == 0): + lastTSpair = prevTSpair + endFound = True + break + fileSize -= 256 + pos = ts(prevTSpair) + # now find out where the file really ends by finding the last 00 + for offset in range(255, -1, -1): + #print("pos: " + to_hex(pos)) + if (readcharDec(g.imageData, pos+offset) != 0): + fileSize += (offset + 1) + break + return fileSize + else: # ProDOS + return (readcharDec(g.imageData, start+21) + + readcharDec(g.imageData, start+22)*256 + + readcharDec(g.imageData, start+23)*65536) def getCreationDate(arg1, arg2): - #outputs prodos creation date/time as Unix time - # (seconds since Jan 1 1970 GMT) - #or None if there is none - if g.SHK: - return None - elif g.D33: - return None - else: # ProDOS - start = getStartPos(arg1, arg2) - pdosDate = (hexToBin(readcharHex(g.imageData, start+25)) + - hexToBin(readcharHex(g.imageData, start+24)) + - hexToBin(readcharHex(g.imageData, start+27)) + - hexToBin(readcharHex(g.imageData, start+26))) - try: - rVal = pdosDateToUnixDate(pdosDate) - except Exception: - rVal = None - return rVal + #outputs prodos creation date/time as Unix time + # (seconds since Jan 1 1970 GMT) + #or None if there is none + if g.SHK: + return None + elif g.D33: + return None + else: # ProDOS + start = getStartPos(arg1, arg2) + pdosDate = (hexToBin(readcharHex(g.imageData, start+25)) + + hexToBin(readcharHex(g.imageData, start+24)) + + hexToBin(readcharHex(g.imageData, start+27)) + + hexToBin(readcharHex(g.imageData, start+26))) + try: + rVal = pdosDateToUnixDate(pdosDate) + except Exception: + rVal = None + return rVal def getModifiedDate(arg1, arg2): - #outputs prodos modified date/time as Unix time - # (seconds since Jan 1 1970 GMT) - #or None if there is none + #outputs prodos modified date/time as Unix time + # (seconds since Jan 1 1970 GMT) + #or None if there is none - if g.SHK: - modifiedDate = int(time.mktime( - time.strptime( - time.ctime( - os.path.getmtime(os.path.join(arg1, arg2)))))) - rVal = modifiedDate - elif g.D33: - rVal = None - else: # ProDOS - start = getStartPos(arg1, arg2) - pdosDate = (hexToBin(readcharHex(g.imageData, start+34)) + - hexToBin(readcharHex(g.imageData, start+33)) + - hexToBin(readcharHex(g.imageData, start+36)) + - hexToBin(readcharHex(g.imageData, start+35))) - try: - rVal = pdosDateToUnixDate(pdosDate) - except Exception: - rVal = None - return rVal + if g.SHK: + modifiedDate = int(time.mktime( + time.strptime( + time.ctime( + os.path.getmtime(os.path.join(arg1, arg2)))))) + rVal = modifiedDate + elif g.D33: + rVal = None + else: # ProDOS + start = getStartPos(arg1, arg2) + pdosDate = (hexToBin(readcharHex(g.imageData, start+34)) + + hexToBin(readcharHex(g.imageData, start+33)) + + hexToBin(readcharHex(g.imageData, start+36)) + + hexToBin(readcharHex(g.imageData, start+35))) + try: + rVal = pdosDateToUnixDate(pdosDate) + except Exception: + rVal = None + return rVal def getVolumeName(): - return getWorkingDirName(2) + return getWorkingDirName(2) def getWorkingDirName(arg1, arg2=None): - # arg1:block, arg2:casemask (optional) - start = ( arg1 * 512 ) - firstByte = readcharDec(g.imageData, start+4) - entryType = (firstByte//16) - nameLength = (firstByte - entryType*16) - workingDirName = readchars(g.imageData, start+5, nameLength) - if (entryType == 15): # volume directory, get casemask from header - caseMaskDec = (readcharDec(g.imageData, start+26) + - readcharDec(g.imageData, start+27)*256) - if (caseMaskDec < 32768): - caseMask = None - else: - caseMask = to_bin(caseMaskDec - 32768).zfill(15) - else: # subdirectory, get casemask from arg2 (not available in header) - caseMask = arg2 - if (not g.UC and caseMask != None): - for i in range(0, len(workingDirName)): - if (caseMask[i] == "1"): - workingDirName = (workingDirName[:i] + - workingDirName[i:i+1].lower() + - workingDirName[i+1:]) - return workingDirName + # arg1:block, arg2:casemask (optional) + start = ( arg1 * 512 ) + firstByte = readcharDec(g.imageData, start+4) + entryType = (firstByte//16) + nameLength = (firstByte - entryType*16) + workingDirName = readchars(g.imageData, start+5, nameLength) + if (entryType == 15): # volume directory, get casemask from header + caseMaskDec = (readcharDec(g.imageData, start+26) + + readcharDec(g.imageData, start+27)*256) + if (caseMaskDec < 32768): + caseMask = None + else: + caseMask = to_bin(caseMaskDec - 32768).zfill(15) + else: # subdirectory, get casemask from arg2 (not available in header) + caseMask = arg2 + if (not g.UC and caseMask != None): + for i in range(0, len(workingDirName)): + if (caseMask[i] == "1"): + workingDirName = (workingDirName[:i] + + workingDirName[i:i+1].lower() + + workingDirName[i+1:]) + return workingDirName def getDirEntryCount(arg1): - if g.D33: - entryCount = 0 - #nextSector = [readcharDec(g.imageData, ts(arg1)+1), - # readcharDec(g.imageData, ts(arg1)+2)] - nextSector = arg1 - while True: - top = ts(nextSector) - pos = top+11 - for e in range(0, 7): - if (readcharDec(g.imageData, pos+0) == 0): - return entryCount # no more file entries - else: - if (readcharDec(g.imageData, pos+0) != 255): - entryCount += 1 # increment if not deleted file - pos += 35 - nextSector = [readcharDec(g.imageData, top+1), - readcharDec(g.imageData, top+2)] - if (nextSector[0]+nextSector[1] == 0): # no more catalog sectors - return entryCount - else: # ProDOS - start = ( arg1 * 512 ) - return (readcharDec(g.imageData, start+37) + - readcharDec(g.imageData, start+38)*256) + if g.D33: + entryCount = 0 + #nextSector = [readcharDec(g.imageData, ts(arg1)+1), + # readcharDec(g.imageData, ts(arg1)+2)] + nextSector = arg1 + while True: + top = ts(nextSector) + pos = top+11 + for e in range(0, 7): + if (readcharDec(g.imageData, pos+0) == 0): + return entryCount # no more file entries + else: + if (readcharDec(g.imageData, pos+0) != 255): + entryCount += 1 # increment if not deleted file + pos += 35 + nextSector = [readcharDec(g.imageData, top+1), + readcharDec(g.imageData, top+2)] + if (nextSector[0]+nextSector[1] == 0): # no more catalog sectors + return entryCount + else: # ProDOS + start = ( arg1 * 512 ) + return (readcharDec(g.imageData, start+37) + + readcharDec(g.imageData, start+38)*256) def getDirNextChunkPointer(arg1): - if g.D33: - start = ts(arg1) - return [readcharDec(g.imageData, start+1), - readcharDec(g.imageData, start+2)] - else: # ProDOS - start = ( arg1 * 512 ) - return (readcharDec(g.imageData, start+2) + - readcharDec(g.imageData, start+3)*256) + if g.D33: + start = ts(arg1) + return [readcharDec(g.imageData, start+1), + readcharDec(g.imageData, start+2)] + else: # ProDOS + start = ( arg1 * 512 ) + return (readcharDec(g.imageData, start+2) + + readcharDec(g.imageData, start+3)*256) def toProdosName(name): - i=0 - if (name[0:1] == '.'): # eliminate leading period - name = name[1:] - for c in name: - if (c != '.' and not c.isalnum()): - name = name[:i] + '.' + name[i+1:] - i+=1 - name = name[0:15] - return name + i=0 + if (name[0:1] == '.'): # eliminate leading period + name = name[1:] + for c in name: + if (c != '.' and not c.isalnum()): + name = name[:i] + '.' + name[i+1:] + i+=1 + name = name[0:15] + return name def ts(track, sector=None): - # returns offset; track and sector can be dec, or hex-ustr - # can also supply as [t,s] for convenience - if (sector == None): - sector = track[1] - track = track[0] - if isinstance(track, type("".encode("L1").decode("L1"))): # hex-ustr - track = int(track, 16) - if isinstance(sector, type("".encode("L1").decode("L1"))): # hex-ustr - sector = int(sector, 16) - return (track*16*256)+(sector*256) + # returns offset; track and sector can be dec, or hex-ustr + # can also supply as [t,s] for convenience + if (sector == None): + sector = track[1] + track = track[0] + if isinstance(track, type("".encode("L1").decode("L1"))): # hex-ustr + track = int(track, 16) + if isinstance(sector, type("".encode("L1").decode("L1"))): # hex-ustr + sector = int(sector, 16) + return (track*16*256)+(sector*256) # --- main logic functions def copyFile(arg1, arg2): - #arg1/arg2: - # ProDOS : directory block / file index in overall directory - # DOS 3.3 : [track, sector] / file index in overall VTOC - # ShrinkIt: directory path / file name - # copies file or dfork to g.outFileData, rfork if any to g.exFileData - g.activeFileBytesCopied = 0 + #arg1/arg2: + # ProDOS : directory block / file index in overall directory + # DOS 3.3 : [track, sector] / file index in overall VTOC + # ShrinkIt: directory path / file name + # copies file or dfork to g.outFileData, rfork if any to g.exFileData + g.activeFileBytesCopied = 0 - if g.SHK: - with open(os.path.join(arg1, arg2), 'rb') as infile: - g.outFileData += infile.read() - if g.shk_hasrf: - print(" [data fork]") - if (g.EX or g.AD): - print(" [resource fork]") - if (g.exFileData == None): - g.exFileData = bytearray(b'') - with open(os.path.join(arg1, (arg2 + "r")), 'rb') as infile: - g.exFileData += infile.read() - else: # ProDOS or DOS 3.3 - storageType = getStorageType(arg1, arg2) - keyPointer = getKeyPointer(arg1, arg2) - fileLen = getFileLength(arg1, arg2) - if (storageType == 1): #seedling - copyBlock(keyPointer, fileLen) - elif (storageType == 2): #sapling - processIndexBlock(keyPointer) - elif (storageType == 3): #tree - processMasterIndexBlock(keyPointer) - elif (storageType == 5): #extended (forked) - processForkedFile(keyPointer) - if g.PNAME: - # remove address/length data from DOS 3.3 file data if ProDOS target - if (getFileType(arg1, arg2) == '06'): - g.outFileData = g.outFileData[4:] - elif ((getFileType(arg1, arg2) == 'FA') or - getFileType(arg1, arg2) == 'FC'): - g.outFileData = g.outFileData[2:] + if g.SHK: + with open(os.path.join(arg1, arg2), 'rb') as infile: + g.outFileData += infile.read() + if g.shk_hasrf: + print(" [data fork]") + if (g.EX or g.AD): + print(" [resource fork]") + if (g.exFileData == None): + g.exFileData = bytearray(b'') + with open(os.path.join(arg1, (arg2 + "r")), 'rb') as infile: + g.exFileData += infile.read() + else: # ProDOS or DOS 3.3 + storageType = getStorageType(arg1, arg2) + keyPointer = getKeyPointer(arg1, arg2) + fileLen = getFileLength(arg1, arg2) + if (storageType == 1): #seedling + copyBlock(keyPointer, fileLen) + elif (storageType == 2): #sapling + processIndexBlock(keyPointer) + elif (storageType == 3): #tree + processMasterIndexBlock(keyPointer) + elif (storageType == 5): #extended (forked) + processForkedFile(keyPointer) + if g.PNAME: + # remove address/length data from DOS 3.3 file data if ProDOS target + if (getFileType(arg1, arg2) == '06'): + g.outFileData = g.outFileData[4:] + elif ((getFileType(arg1, arg2) == 'FA') or + getFileType(arg1, arg2) == 'FC'): + g.outFileData = g.outFileData[2:] def copyBlock(arg1, arg2): - #arg1: block number or [t,s] to copy - #arg2: bytes to write (should be 256 (DOS 3.3) or 512 (ProDOS), - # unless final block with less) - #print(arg1 + " " + arg2 + " " + g.activeFileBytesCopied) - if (arg1 == 0): - outBytes = (b'\x00' * arg2) - else: - outBytes = slyce(g.imageData, (ts(arg1) if g.D33 else arg1*512), arg2) - if (g.resourceFork > 0): - if g.AD or g.EX: - offset = (741 if g.AD else 0) - if (g.exFileData == None): - g.exFileData = bytearray(b'') - g.exFileData[(g.activeFileBytesCopied + offset): - (g.activeFileBytesCopied + offset + arg2)] = outBytes - else: - g.outFileData[g.activeFileBytesCopied: - (g.activeFileBytesCopied + arg2)] = outBytes - g.activeFileBytesCopied += arg2 + #arg1: block number or [t,s] to copy + #arg2: bytes to write (should be 256 (DOS 3.3) or 512 (ProDOS), + # unless final block with less) + #print(arg1 + " " + arg2 + " " + g.activeFileBytesCopied) + if (arg1 == 0): + outBytes = (b'\x00' * arg2) + else: + outBytes = slyce(g.imageData, (ts(arg1) if g.D33 else arg1*512), arg2) + if (g.resourceFork > 0): + if g.AD or g.EX: + offset = (741 if g.AD else 0) + if (g.exFileData == None): + g.exFileData = bytearray(b'') + g.exFileData[(g.activeFileBytesCopied + offset): + (g.activeFileBytesCopied + offset + arg2)] = outBytes + else: + g.outFileData[g.activeFileBytesCopied: + (g.activeFileBytesCopied + arg2)] = outBytes + g.activeFileBytesCopied += arg2 def processDir(arg1, arg2=None, arg3=None, arg4=None, arg5=None): - # arg1: ProDOS directory block, or DOS 3.3 [track,sector] - # for key block (with directory header): - # arg2: casemask (optional), arg3:None, arg4:None, arg5:None - # for secondary directory blocks (non-key block): - # arg2/3/4/5: for non-key chunks: entryCount, entry#, - # workingDirName, processedEntryCount + # arg1: ProDOS directory block, or DOS 3.3 [track,sector] + # for key block (with directory header): + # arg2: casemask (optional), arg3:None, arg4:None, arg5:None + # for secondary directory blocks (non-key block): + # arg2/3/4/5: for non-key chunks: entryCount, entry#, + # workingDirName, processedEntryCount - entryCount = None - e = None - pe = None - workingDirName = None + entryCount = None + e = None + pe = None + workingDirName = None - if arg3: - entryCount = arg2 - e = arg3 - workingDirName = arg4 - pe = arg5 - else: - e = 0 - pe = 0 - entryCount = getDirEntryCount(arg1) - if not g.D33: - workingDirName = getWorkingDirName(arg1, arg2).decode("L1") - g.DIRPATH = (g.DIRPATH + "/" + workingDirName) - if g.PDOSPATH_INDEX: - if (g.PDOSPATH_INDEX == 1): - if (("/" + g.PDOSPATH_SEGMENT.lower()) != - g.DIRPATH.lower()): - print("ProDOS volume name does not match disk image.") - quitNow(2) - else: - g.PDOSPATH_INDEX += 1 - g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX] - else: - pass - # print(g.DIRPATH) - while (pe < entryCount): - if (getStorageType(arg1, e) > 0): - #print(pe, e, entryCount) - processEntry(arg1, e) - pe += 1 - e += 1 - if not ((e + (0 if g.D33 else (e>11)) ) % (7 if g.D33 else 13)): - processDir(getDirNextChunkPointer(arg1), - entryCount, - e, - workingDirName, - pe) - break + if arg3: + entryCount = arg2 + e = arg3 + workingDirName = arg4 + pe = arg5 + else: + e = 0 + pe = 0 + entryCount = getDirEntryCount(arg1) + if not g.D33: + workingDirName = getWorkingDirName(arg1, arg2).decode("L1") + g.DIRPATH = (g.DIRPATH + "/" + workingDirName) + if g.PDOSPATH_INDEX: + if (g.PDOSPATH_INDEX == 1): + if (("/" + g.PDOSPATH_SEGMENT.lower()) != + g.DIRPATH.lower()): + print("ProDOS volume name does not match disk image.") + quitNow(2) + else: + g.PDOSPATH_INDEX += 1 + g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX] + else: + pass + # print(g.DIRPATH) + while (pe < entryCount): + if (getStorageType(arg1, e) > 0): + #print(pe, e, entryCount) + processEntry(arg1, e) + pe += 1 + e += 1 + if not ((e + (0 if g.D33 else (e>11)) ) % (7 if g.D33 else 13)): + processDir(getDirNextChunkPointer(arg1), + entryCount, + e, + workingDirName, + pe) + break def processEntry(arg1, arg2): - # arg1=block number, [t,s] if g.D33=1, or subdir name if g.SHK=1 - # arg2=index number of entry in directory, or file name if g.SHK=1 + # arg1=block number, [t,s] if g.D33=1, or subdir name if g.SHK=1 + # arg2=index number of entry in directory, or file name if g.SHK=1 - ''' - print(getFileName(arg1, arg2), getStorageType(arg1, arg2), - getFileType(arg1, arg2), getKeyPointer(arg1, arg2), - getFileLength(arg1, arg2), getAuxType(arg1, arg2), - getCreationDate(arg1, arg2), getModifiedDate(arg1, arg2)) - ''' + ''' + print(getFileName(arg1, arg2), getStorageType(arg1, arg2), + getFileType(arg1, arg2), getKeyPointer(arg1, arg2), + getFileLength(arg1, arg2), getAuxType(arg1, arg2), + getCreationDate(arg1, arg2), getModifiedDate(arg1, arg2)) + ''' - eTargetName = None - g.exFileData = None - g.outFileData = bytearray(b'') - if g.SHK: # ShrinkIt archive - g.activeFileName = (arg2 if g.EX else arg2.split('#')[0]) - if g.UC: - g.activeFileName = g.activeFileName.upper() - origFileName = g.activeFileName - else: # ProDOS or DOS 3.3 image - g.activeFileName = getFileName(arg1 ,arg2).decode("L1") - origFileName = g.activeFileName - if g.PNAME: - g.activeFileName = toProdosName(g.activeFileName) - g.activeFileSize = getFileLength(arg1, arg2) + eTargetName = None + g.exFileData = None + g.outFileData = bytearray(b'') + if g.SHK: # ShrinkIt archive + g.activeFileName = (arg2 if g.EX else arg2.split('#')[0]) + if g.UC: + g.activeFileName = g.activeFileName.upper() + origFileName = g.activeFileName + else: # ProDOS or DOS 3.3 image + g.activeFileName = getFileName(arg1 ,arg2).decode("L1") + origFileName = g.activeFileName + if g.PNAME: + g.activeFileName = toProdosName(g.activeFileName) + g.activeFileSize = getFileLength(arg1, arg2) - if (not g.PDOSPATH_INDEX or - g.activeFileName.upper() == g.PDOSPATH_SEGMENT.upper()): + if (not g.PDOSPATH_INDEX or + g.activeFileName.upper() == g.PDOSPATH_SEGMENT.upper()): - # if ProDOS directory, not file - if (not g.SHK and getStorageType(arg1, arg2) == 13): - if not g.PDOSPATH_INDEX: - g.targetDir = (g.targetDir + "/" + g.activeFileName) - g.ADdir = (g.targetDir + "/.AppleDouble") - if not (g.CAT or os.path.isdir(g.targetDir)): - makedirs(g.targetDir) - if not (g.CAT or (not g.AD) or os.path.isdir(g.ADdir)): - makedirs(g.ADdir) - if g.PDOSPATH_SEGMENT: - g.PDOSPATH_INDEX += 1 - g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX] - processDir(getKeyPointer(arg1, arg2), getCaseMask(arg1, arg2)) - g.DIRPATH = g.DIRPATH.rsplit("/", 1)[0] - if not g.PDOSPATH_INDEX: - g.targetDir = g.targetDir.rsplit("/", 1)[0] - g.ADdir = (g.targetDir + "/.AppleDouble") - else: # ProDOS or DOS 3.3 file either from image or ShrinkIt archive - dirPrint = "" - if g.DIRPATH: - dirPrint = g.DIRPATH + "/" - else: - if g.SHK: - if ("/".join(dirName.split('/')[3:])): - dirPrint = ("/".join(dirName.split('/')[3:]) + "/") - if (not g.extractFile or - (os.path.basename(g.extractFile.lower()) == - origFileName.split('#')[0].lower())): - filePrint = g.activeFileName.split("#")[0] - print(dirPrint + filePrint + - ("+" if (g.shk_hasrf or - (not g.SHK and getStorageType(arg1, arg2) == 5)) - else "") + - ((" [" + origFileName + "] ") - if (g.PNAME and (origFileName != g.activeFileName)) - else "")) - if g.CAT: - return - if not g.targetName: - g.targetName = g.activeFileName - if g.EX: - if g.SHK: - eTargetName = arg2 - else: # ProDOS image - eTargetName = (g.targetName + "#" + - getFileType(arg1, arg2).lower() + - getAuxType(arg1, arg2).lower()) - # touch(g.targetDir + "/" + g.targetName) - if g.AD: - makeADfile() - copyFile(arg1, arg2) - saveName = (g.targetDir + "/" + - (eTargetName if eTargetName else g.targetName)) - saveFile(saveName, g.outFileData) - creationDate = getCreationDate(arg1, arg2) - modifiedDate = getModifiedDate(arg1, arg2) - if (creationDate is None and modifiedDate is not None): - creationDate = modifiedDate - elif (creationDate is not None and modifiedDate is None): - modifiedDate = creationDate - elif (creationDate is None and modifiedDate is None): - creationDate = (datetime.datetime.today() - - datetime.datetime(1970,1,1)).days*24*60*60 - modifiedDate = creationDate - if g.AD: # AppleDouble - # set dates - ADfilePath = (g.ADdir + "/" + g.targetName) - writecharsHex(g.exFileData, - 637, - (unixDateToADDate(creationDate) + - unixDateToADDate(modifiedDate))) - writecharHex(g.exFileData, 645, "80") - writecharHex(g.exFileData, 649, "80") - #set type/creator - writechars(g.exFileData, 653, b'p') - writecharsHex(g.exFileData, - 654, - getFileType(arg1, arg2) + - getAuxType(arg1, arg2)) - writechars(g.exFileData, 657, b'pdos') - saveFile(ADfilePath, g.exFileData) - touch(saveName, modifiedDate) - if g.EX: # extended name from ProDOS image - if (g.exFileData != None): - saveFile((saveName + "r"), g.exFileData) - touch((saveName + "r"), modifiedDate) - if (g.PDOSPATH_SEGMENT or - (g.extractFile and - (g.extractFile.lower() == origFileName.lower()))): - quitNow(0) - g.targetName = None - #else: - #print(g.activeFileName + " doesn't match " + g.PDOSPATH_SEGMENT) + # if ProDOS directory, not file + if (not g.SHK and getStorageType(arg1, arg2) == 13): + if not g.PDOSPATH_INDEX: + g.targetDir = (g.targetDir + "/" + g.activeFileName) + g.ADdir = (g.targetDir + "/.AppleDouble") + if not (g.CAT or os.path.isdir(g.targetDir)): + makedirs(g.targetDir) + if not (g.CAT or (not g.AD) or os.path.isdir(g.ADdir)): + makedirs(g.ADdir) + if g.PDOSPATH_SEGMENT: + g.PDOSPATH_INDEX += 1 + g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX] + processDir(getKeyPointer(arg1, arg2), getCaseMask(arg1, arg2)) + g.DIRPATH = g.DIRPATH.rsplit("/", 1)[0] + if not g.PDOSPATH_INDEX: + g.targetDir = g.targetDir.rsplit("/", 1)[0] + g.ADdir = (g.targetDir + "/.AppleDouble") + else: # ProDOS or DOS 3.3 file either from image or ShrinkIt archive + dirPrint = "" + if g.DIRPATH: + dirPrint = g.DIRPATH + "/" + else: + if g.SHK: + if ("/".join(dirName.split('/')[3:])): + dirPrint = ("/".join(dirName.split('/')[3:]) + "/") + if (not g.extractFile or + (os.path.basename(g.extractFile.lower()) == + origFileName.split('#')[0].lower())): + filePrint = g.activeFileName.split("#")[0] + print(dirPrint + filePrint + + ("+" if (g.shk_hasrf or + (not g.SHK and getStorageType(arg1, arg2) == 5)) + else "") + + ((" [" + origFileName + "] ") + if (g.PNAME and (origFileName != g.activeFileName)) + else "")) + if g.CAT: + return + if not g.targetName: + g.targetName = g.activeFileName + if g.EX: + if g.SHK: + eTargetName = arg2 + else: # ProDOS image + eTargetName = (g.targetName + "#" + + getFileType(arg1, arg2).lower() + + getAuxType(arg1, arg2).lower()) + # touch(g.targetDir + "/" + g.targetName) + if g.AD: + makeADfile() + copyFile(arg1, arg2) + saveName = (g.targetDir + "/" + + (eTargetName if eTargetName else g.targetName)) + saveFile(saveName, g.outFileData) + creationDate = getCreationDate(arg1, arg2) + modifiedDate = getModifiedDate(arg1, arg2) + if (creationDate is None and modifiedDate is not None): + creationDate = modifiedDate + elif (creationDate is not None and modifiedDate is None): + modifiedDate = creationDate + elif (creationDate is None and modifiedDate is None): + creationDate = (datetime.datetime.today() - + datetime.datetime(1970,1,1)).days*24*60*60 + modifiedDate = creationDate + if g.AD: # AppleDouble + # set dates + ADfilePath = (g.ADdir + "/" + g.targetName) + writecharsHex(g.exFileData, + 637, + (unixDateToADDate(creationDate) + + unixDateToADDate(modifiedDate))) + writecharHex(g.exFileData, 645, "80") + writecharHex(g.exFileData, 649, "80") + #set type/creator + writechars(g.exFileData, 653, b'p') + writecharsHex(g.exFileData, + 654, + getFileType(arg1, arg2) + + getAuxType(arg1, arg2)) + writechars(g.exFileData, 657, b'pdos') + saveFile(ADfilePath, g.exFileData) + touch(saveName, modifiedDate) + if g.EX: # extended name from ProDOS image + if (g.exFileData != None): + saveFile((saveName + "r"), g.exFileData) + touch((saveName + "r"), modifiedDate) + if (g.PDOSPATH_SEGMENT or + (g.extractFile and + (g.extractFile.lower() == origFileName.lower()))): + quitNow(0) + g.targetName = None + #else: + #print(g.activeFileName + " doesn't match " + g.PDOSPATH_SEGMENT) def processForkedFile(arg1): - # finder info except type/creator - fInfoA_entryType = readcharDec(g.imageData, 9) - fInfoB_entryType = readcharDec(g.imageData, 27) - if (fInfoA_entryType == 1): - writechars(g.imageData, 661, readchars(g.imageData, 18, 8)) - elif (fInfoA_entryType == 2): - writechars(g.imageData, 669, readchars(g.imageData, 10, 16)) - if (fInfoB_entryType == 1): - writechars(g.imageData, 661, readchars(g.imageData, 36, 8)) - elif (fInfoB_entryType == 2): - writechars(g.imageData, 669, readchars(g.imageData, 28, 16)) + # finder info except type/creator + fInfoA_entryType = readcharDec(g.imageData, 9) + fInfoB_entryType = readcharDec(g.imageData, 27) + if (fInfoA_entryType == 1): + writechars(g.imageData, 661, readchars(g.imageData, 18, 8)) + elif (fInfoA_entryType == 2): + writechars(g.imageData, 669, readchars(g.imageData, 10, 16)) + if (fInfoB_entryType == 1): + writechars(g.imageData, 661, readchars(g.imageData, 36, 8)) + elif (fInfoB_entryType == 2): + writechars(g.imageData, 669, readchars(g.imageData, 28, 16)) - for f in [0, 256]: - g.resourceFork = f - g.activeFileBytesCopied = 0 - forkStart = (arg1 * 512) # start of Forked File key block - # print("--" + forkStart) - forkStorageType = readcharDec(g.imageData, forkStart+f+0) - forkKeyPointer = (readcharDec(g.imageData, forkStart+f+1) + - readcharDec(g.imageData, forkStart+f+2)*256) - forkFileLen = (readcharDec(g.imageData, forkStart+f+5) + - readcharDec(g.imageData, forkStart+f+6)*256 + - readcharDec(g.imageData, forkStart+f+7)*256*256) - g.activeFileSize = forkFileLen - if (g.resourceFork > 0): - rsrcForkLenHex = (readcharHex(g.imageData, forkStart+f+7) + - readcharHex(g.imageData, forkStart+f+6) + - readcharHex(g.imageData, forkStart+f+5)) - # print(">>>" + rsrcForkLenHex) - if (g.AD or g.EX): - print(" [resource fork]") - if g.AD: - writecharsHex(g.exFileData, 35, rsrcForkLenHex) - else: - print(" [data fork]") - if (forkStorageType == 1): #seedling - copyBlock(forkKeyPointer, forkFileLen) - elif (forkStorageType == 2): #sapling - processIndexBlock(forkKeyPointer) - elif (forkStorageType == 3): #tree - processMasterIndexBlock(forkKeyPointer) - # print() - g.resourceFork = 0 + for f in [0, 256]: + g.resourceFork = f + g.activeFileBytesCopied = 0 + forkStart = (arg1 * 512) # start of Forked File key block + # print("--" + forkStart) + forkStorageType = readcharDec(g.imageData, forkStart+f+0) + forkKeyPointer = (readcharDec(g.imageData, forkStart+f+1) + + readcharDec(g.imageData, forkStart+f+2)*256) + forkFileLen = (readcharDec(g.imageData, forkStart+f+5) + + readcharDec(g.imageData, forkStart+f+6)*256 + + readcharDec(g.imageData, forkStart+f+7)*256*256) + g.activeFileSize = forkFileLen + if (g.resourceFork > 0): + rsrcForkLenHex = (readcharHex(g.imageData, forkStart+f+7) + + readcharHex(g.imageData, forkStart+f+6) + + readcharHex(g.imageData, forkStart+f+5)) + # print(">>>" + rsrcForkLenHex) + if (g.AD or g.EX): + print(" [resource fork]") + if g.AD: + writecharsHex(g.exFileData, 35, rsrcForkLenHex) + else: + print(" [data fork]") + if (forkStorageType == 1): #seedling + copyBlock(forkKeyPointer, forkFileLen) + elif (forkStorageType == 2): #sapling + processIndexBlock(forkKeyPointer) + elif (forkStorageType == 3): #tree + processMasterIndexBlock(forkKeyPointer) + # print() + g.resourceFork = 0 def processMasterIndexBlock(arg1): - processIndexBlock(arg1, True) + processIndexBlock(arg1, True) def processIndexBlock(arg1, arg2=False): - #arg1: indexBlock, or [t,s] of track/sector list - #arg2: if True, it's a Master Index Block - pos = 12 if g.D33 else 0 - bytesRemaining = g.activeFileSize - while (g.activeFileBytesCopied < g.activeFileSize): - if g.D33: - targetTS = [readcharDec(g.imageData, ts(arg1)+pos+0), - readcharDec(g.imageData, ts(arg1)+pos+1)] - #print(to_hex(targetTS[0]),to_hex(targetTS[1])) - bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied) - bs = (bytesRemaining if (bytesRemaining < 256) else 256) - copyBlock(targetTS, bs) - pos += 2 - if (pos > 255): - # continue with next T/S list sector - processIndexBlock([readcharDec(g.imageData, ts(arg1)+1), - readcharDec(g.imageData, ts(arg1)+2)]) - else: # ProDOS - targetBlock = (readcharDec(g.imageData, arg1*512+pos) + - readcharDec(g.imageData, arg1*512+(pos+256))*256) - if arg2: - processIndexBlock(targetBlock) - else: - bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied) - bs = (bytesRemaining if (bytesRemaining < 512) else 512) - copyBlock(targetBlock, bs) - pos += 1 - if (pos > 255): - break # go to next entry in Master Index Block (tree) + #arg1: indexBlock, or [t,s] of track/sector list + #arg2: if True, it's a Master Index Block + pos = 12 if g.D33 else 0 + bytesRemaining = g.activeFileSize + while (g.activeFileBytesCopied < g.activeFileSize): + if g.D33: + targetTS = [readcharDec(g.imageData, ts(arg1)+pos+0), + readcharDec(g.imageData, ts(arg1)+pos+1)] + #print(to_hex(targetTS[0]),to_hex(targetTS[1])) + bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied) + bs = (bytesRemaining if (bytesRemaining < 256) else 256) + copyBlock(targetTS, bs) + pos += 2 + if (pos > 255): + # continue with next T/S list sector + processIndexBlock([readcharDec(g.imageData, ts(arg1)+1), + readcharDec(g.imageData, ts(arg1)+2)]) + else: # ProDOS + targetBlock = (readcharDec(g.imageData, arg1*512+pos) + + readcharDec(g.imageData, arg1*512+(pos+256))*256) + if arg2: + processIndexBlock(targetBlock) + else: + bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied) + bs = (bytesRemaining if (bytesRemaining < 512) else 512) + copyBlock(targetBlock, bs) + pos += 1 + if (pos > 255): + break # go to next entry in Master Index Block (tree) def makeADfile(): - if not g.AD: return - touch(g.ADdir + "/" + g.targetName) - g.exFileData = bytearray(b'\x00' * 741) - # ADv2 header - writecharsHex(g.exFileData, hexToDec("00"), "0005160700020000") - # number of entries - writecharsHex(g.exFileData, hexToDec("18"), "000D") - # Resource Fork - writecharsHex(g.exFileData, hexToDec("1A"), "00000002000002E500000000") - # Real Name - writecharsHex(g.exFileData, hexToDec("26"), "00000003000000B600000000") - # Comment - writecharsHex(g.exFileData, hexToDec("32"), "00000004000001B500000000") - # Dates Info - writecharsHex(g.exFileData, hexToDec("3E"), "000000080000027D00000010") - # Finder Info - writecharsHex(g.exFileData, hexToDec("4A"), "000000090000028D00000020") - # ProDOS file info - writecharsHex(g.exFileData, hexToDec("56"), "0000000B000002C100000008") - # AFP short name - writecharsHex(g.exFileData, hexToDec("62"), "0000000D000002B500000000") - # AFP File Info - writecharsHex(g.exFileData, hexToDec("6E"), "0000000E000002B100000004") - # AFP Directory ID - writecharsHex(g.exFileData, hexToDec("7A"), "0000000F000002AD00000004") - # dbd (second time) will create DEV, INO, SYN, SV~ + if not g.AD: return + touch(g.ADdir + "/" + g.targetName) + g.exFileData = bytearray(b'\x00' * 741) + # ADv2 header + writecharsHex(g.exFileData, hexToDec("00"), "0005160700020000") + # number of entries + writecharsHex(g.exFileData, hexToDec("18"), "000D") + # Resource Fork + writecharsHex(g.exFileData, hexToDec("1A"), "00000002000002E500000000") + # Real Name + writecharsHex(g.exFileData, hexToDec("26"), "00000003000000B600000000") + # Comment + writecharsHex(g.exFileData, hexToDec("32"), "00000004000001B500000000") + # Dates Info + writecharsHex(g.exFileData, hexToDec("3E"), "000000080000027D00000010") + # Finder Info + writecharsHex(g.exFileData, hexToDec("4A"), "000000090000028D00000020") + # ProDOS file info + writecharsHex(g.exFileData, hexToDec("56"), "0000000B000002C100000008") + # AFP short name + writecharsHex(g.exFileData, hexToDec("62"), "0000000D000002B500000000") + # AFP File Info + writecharsHex(g.exFileData, hexToDec("6E"), "0000000E000002B100000004") + # AFP Directory ID + writecharsHex(g.exFileData, hexToDec("7A"), "0000000F000002AD00000004") + # dbd (second time) will create DEV, INO, SYN, SV~ def quitNow(exitCode=0): - if (exitCode == 0 and not g.nomsg and - g.AD and os.path.isdir("/usr/local/etc/netatalk")): - print("File(s) have been copied to the target directory. " + - "If the directory") - print("is shared by Netatalk, please type 'afpsync' now.") - if g.SHK: # clean up - for file in os.listdir('/tmp'): - if file.startswith("cppo-"): - shutil.rmtree('/tmp' + "/" + file) - sys.exit(exitCode) + if (exitCode == 0 and not g.nomsg and + g.AD and os.path.isdir("/usr/local/etc/netatalk")): + print("File(s) have been copied to the target directory. " + + "If the directory") + print("is shared by Netatalk, please type 'afpsync' now.") + if g.SHK: # clean up + for file in os.listdir('/tmp'): + if file.startswith("cppo-"): + shutil.rmtree('/tmp' + "/" + file) + sys.exit(exitCode) def usage(exitcode=1): - print(sys.modules[__name__].__doc__) - quitNow(exitcode) + print(sys.modules[__name__].__doc__) + quitNow(exitcode) # --- ID bashbyter functions (adapted) @@ -766,70 +766,70 @@ def decToHex(arg1): # arg: decimal value from 0-255 # out: two-digit hex string from 00-FF #exit: 21=invalid arg - if (arg1<0 or arg1>255): sys.exit(21) - return to_hex(arg1).upper() + if (arg1<0 or arg1>255): sys.exit(21) + return to_hex(arg1).upper() def hexToDec(arg1): # converts single-byte hexadecimal value to decimal equivalent # arg: two-digit hex value from 00-FF # out: decimal value #exit: 21=invalid arg - if (len(arg1) != 2): return 21 - return to_dec(arg1) + if (len(arg1) != 2): return 21 + return to_dec(arg1) def hexToBin(arg1): # converts single-byte hexadecimal value to binary string # arg: two-digit hex value from 00-FF # out: binary string value #exit: 21=invalid arg - if (len(arg1) != 2): return 21 - return to_bin(arg1).zfill(8) + if (len(arg1) != 2): return 21 + return to_bin(arg1).zfill(8) def binToDec(arg1): # converts single-byte binary string (8 bits) value to decimal # warning: no error checking # arg: binary string up to 8 bits # out: decimal value - return to_dec([arg1]) + return to_dec([arg1]) def binToHex(arg1): # converts single-byte binary string (8 bits) value to hex # warning: no error checking # arg: binary string up to 8 bits # out: hex value - return to_hex(arg1).upper() + return to_hex(arg1).upper() def charToDec(arg1): # converts single char (of type bytes) to corresponding decimal value # arg: one char (of type bytes) # out: decimal value from 0-255 #exit: 21=invalid arg - if (len(arg1) != 1): return 21 - return to_dec(arg1) + if (len(arg1) != 1): return 21 + return to_dec(arg1) def charToHex(arg1): # converts single char (of type bytes) to corresponding hex value # arg: one char (of type bytes) # out: hexadecimal value from 00-FF #exit: 21=invalid arg - if (len(arg1) != 1): return 21 - return to_hex(arg1).upper() + if (len(arg1) != 1): return 21 + return to_hex(arg1).upper() def decToChar(arg1): # converts single-byte decimal value to equivalent char (of type bytes) # arg: decimal number from 0-255 # out: one character #exit: 21=invalid arg - if (arg1<0 or arg1>255): sys.exit(21) - return to_bytes(arg1) + if (arg1<0 or arg1>255): sys.exit(21) + return to_bytes(arg1) def hexToChar(arg1): # converts single-byte hex value to corresponding char (of type bytes) # arg: two-digit hexadecimal number from 00-FF # out: one character #exit: 21=invalid arg - if (len(arg1) != 2): return 21 - return to_bytes(arg1) + if (len(arg1) != 2): return 21 + return to_bytes(arg1) def readchars(arg1, arg2=0, arg3=0): # read one or more characters from a bytes variable @@ -838,13 +838,13 @@ def readchars(arg1, arg2=0, arg3=0): # arg3: (optional) # of chars to read (default is to end of bytes var) # out: sequence of characters (bytes or bytearray) # exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3 - if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)): - sys.exit(21) - if (arg2<0): sys.exit(22) - if (arg3<0): sys.exit(23) - if (arg3 == 0): - arg3 = len(arg1) - return slyce(arg1, arg2, arg3) + if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)): + sys.exit(21) + if (arg2<0): sys.exit(22) + if (arg3<0): sys.exit(23) + if (arg3 == 0): + arg3 = len(arg1) + return slyce(arg1, arg2, arg3) def readcharDec(arg1, arg2=0): # read one character from bytes var & convert to equivalent dec value @@ -852,10 +852,10 @@ def readcharDec(arg1, arg2=0): # arg2: (optional) offset (# of bytes to skip before reading) # out: decimal value from 0-255 # exit: 21=invalid arg1, 22=invalid arg2 - if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)): - sys.exit(21) - if (arg2<0): sys.exit(22) - return to_dec(slyce(arg1, arg2, 1)) + if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)): + sys.exit(21) + if (arg2<0): sys.exit(22) + return to_dec(slyce(arg1, arg2, 1)) def readcharHex(arg1, arg2=0): # read one character from bytes var & convert to corresponding hex value @@ -863,10 +863,10 @@ def readcharHex(arg1, arg2=0): # arg2: (optional) offset (# of bytes to skip before reading) # out: two-digit hex value from 00-FF # exit: 21=invalid arg1, 22=invalid arg2 - if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)): - sys.exit(21) - if (arg2<0): sys.exit(22) - return to_hex(slyce(arg1, arg2, 1)) + if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)): + sys.exit(21) + if (arg2<0): sys.exit(22) + return to_hex(slyce(arg1, arg2, 1)) def writechars(arg1, arg2, arg3): # write one or more characters (bytes) to bytearray @@ -875,11 +875,11 @@ def writechars(arg1, arg2, arg3): # arg3: sequence of bytes (or bytearray) # out: nothing # exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3 - if not isinstance(arg1, bytearray): sys.exit(21) - if (arg2<0): sys.exit(22) - if not (isinstance(arg3, bytes) or isinstance(arg3, bytearray)): - sys.exit(23) - arg1[arg2:arg2+len(arg3)] = arg3 + if not isinstance(arg1, bytearray): sys.exit(21) + if (arg2<0): sys.exit(22) + if not (isinstance(arg3, bytes) or isinstance(arg3, bytearray)): + sys.exit(23) + arg1[arg2:arg2+len(arg3)] = arg3 def writecharDec(arg1, arg2, arg3): # write corresponding char of single-byte decimal value into bytearray @@ -888,10 +888,10 @@ def writecharDec(arg1, arg2, arg3): # arg3: decimal number from 0-255 # exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3 # out: nothing - if not isinstance(arg1, bytearray): sys.exit(21) - if (arg2<0): sys.exit(22) - if not isnumber(arg3): sys.exit(23) - arg1[arg2:arg2+1] = to_bytes(arg3) + if not isinstance(arg1, bytearray): sys.exit(21) + if (arg2<0): sys.exit(22) + if not isnumber(arg3): sys.exit(23) + arg1[arg2:arg2+1] = to_bytes(arg3) def writecharHex(arg1, arg2, arg3): # write corresponding character of single-byte hex value into bytearray @@ -900,10 +900,10 @@ def writecharHex(arg1, arg2, arg3): # arg3: two-digit hexadecimal number from 00-FF # out: nothing # exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3 - if not isinstance(arg1, bytearray): sys.exit(21) - if (arg2<0): sys.exit(22) - if not isinstance(arg3, type("".encode("L1").decode("L1"))): sys.exit(23) - arg1[arg2:arg2+1] = to_bytes(arg3) + if not isinstance(arg1, bytearray): sys.exit(21) + if (arg2<0): sys.exit(22) + if not isinstance(arg3, type("".encode("L1").decode("L1"))): sys.exit(23) + arg1[arg2:arg2+1] = to_bytes(arg3) def writecharsHex(arg1, arg2, arg3): # write corresponding characters of hex values into bytearray @@ -912,183 +912,183 @@ def writecharsHex(arg1, arg2, arg3): # arg3: string of two-digit hexadecimal numbers from 00-FF # out: nothing # exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3 - if not isinstance(arg1, bytearray): sys.exit(21) - if (arg2<0): sys.exit(22) - if not isinstance(arg3, type("".encode("L1").decode("L1"))): sys.exit(23) - arg1[arg2:arg2+len(to_bytes(arg3))] = to_bytes(arg3) + if not isinstance(arg1, bytearray): sys.exit(21) + if (arg2<0): sys.exit(22) + if not isinstance(arg3, type("".encode("L1").decode("L1"))): sys.exit(23) + arg1[arg2:arg2+len(to_bytes(arg3))] = to_bytes(arg3) #---- IvanX general purpose functions ----# def slyce(val, start_pos=0, length=1, reverse=False): - """returns slice of object (but not a slice object) - allows specifying length, and 3.x "bytes" consistency""" - if (start_pos < 0): - the_slyce = val[start_pos:] - else: - the_slyce = val[start_pos:start_pos+length] - return (the_slyce[::-1] if reverse else the_slyce) + """returns slice of object (but not a slice object) + allows specifying length, and 3.x "bytes" consistency""" + if (start_pos < 0): + the_slyce = val[start_pos:] + else: + the_slyce = val[start_pos:start_pos+length] + return (the_slyce[::-1] if reverse else the_slyce) def to_hex(val): - """convert bytes, decimal number, or [bin-ustr] to two-digit hex values - unlike hex(), accepts bytes; has no leading 0x or trailing L""" - from binascii import b2a_hex - if isinstance(val, list): # [bin-ustr] - val = int(val[0], 2) - if isinstance(val, bytes): # bytes - return b2a_hex(val).decode("L1") - elif isnumber(val): - # hex returns str/bytes in P2, but str/unicode in P3, so - # .encode().decode() always returns unicode in either - if (val < 0): print ("val: " + str(val)) - return hex(val)[2:].encode("L1").decode("L1").split("L")[0] - else: - raise Exception("to_hex() requires bytes, int/long, or [bin-ustr]") + """convert bytes, decimal number, or [bin-ustr] to two-digit hex values + unlike hex(), accepts bytes; has no leading 0x or trailing L""" + from binascii import b2a_hex + if isinstance(val, list): # [bin-ustr] + val = int(val[0], 2) + if isinstance(val, bytes): # bytes + return b2a_hex(val).decode("L1") + elif isnumber(val): + # hex returns str/bytes in P2, but str/unicode in P3, so + # .encode().decode() always returns unicode in either + if (val < 0): print ("val: " + str(val)) + return hex(val)[2:].encode("L1").decode("L1").split("L")[0] + else: + raise Exception("to_hex() requires bytes, int/long, or [bin-ustr]") def hex_slyce(val, start_pos=0, length=1, little_endian=False): - """returns bytes slyce as hex-ustr""" - return to_hex(slyce(val, start_pos, length, little_endian)) + """returns bytes slyce as hex-ustr""" + return to_hex(slyce(val, start_pos, length, little_endian)) def dec_slyce(val, start_pos=0, length=1, little_endian=False): - """returns bytes slyce converted to decimal int/long""" - return to_dec(hex_slyce(val, start_pos, length, little_endian)) + """returns bytes slyce converted to decimal int/long""" + return to_dec(hex_slyce(val, start_pos, length, little_endian)) def bin_slyce(val, start_pos=0, length=1, little_endian=False): - """returns bytes slyce converted to bin-ustr""" - return to_bin(hex_slyce(val, start_pos, length, little_endian)) + """returns bytes slyce converted to bin-ustr""" + return to_bin(hex_slyce(val, start_pos, length, little_endian)) def to_dec(val): - """convert bytes, hex-ustr or [bin-ustr] to decimal int/long""" - if isinstance(val, list): # [bin-ustr] - return int(val[0], 2) - elif isinstance(val, bytes): # bytes - return int(to_hex(val), 16) - elif isinstance(val, type("".encode("L1").decode("L1"))): # hex-ustr - return int(val, 16) - elif isnumber(val): # int/long - return val # so we can use a bytes[x] in P2 or P3 - else: - raise Exception("to_dec() requires bytes, hex-ustr or [bin-ustr]") + """convert bytes, hex-ustr or [bin-ustr] to decimal int/long""" + if isinstance(val, list): # [bin-ustr] + return int(val[0], 2) + elif isinstance(val, bytes): # bytes + return int(to_hex(val), 16) + elif isinstance(val, type("".encode("L1").decode("L1"))): # hex-ustr + return int(val, 16) + elif isnumber(val): # int/long + return val # so we can use a bytes[x] in P2 or P3 + else: + raise Exception("to_dec() requires bytes, hex-ustr or [bin-ustr]") def to_bin(val): - """convert bytes, hex-ustr, or int/long to bin-ustr""" - if isinstance(val, bytes): # bytes - return (bin(to_dec(to_hex(val))))[2:].encode("L1").decode("L1") - elif isinstance(val, type("".encode("L1").decode("L1"))): # hex-ustr - return (bin(int(val, 16)))[2:].encode("L1").decode("L1") - elif isnumber(val): # int/long - return (bin(val))[2:].encode("L1").decode("L1") - else: - raise Exception("to_bin() requires bytes, hex-ustr, or int/long") + """convert bytes, hex-ustr, or int/long to bin-ustr""" + if isinstance(val, bytes): # bytes + return (bin(to_dec(to_hex(val))))[2:].encode("L1").decode("L1") + elif isinstance(val, type("".encode("L1").decode("L1"))): # hex-ustr + return (bin(int(val, 16)))[2:].encode("L1").decode("L1") + elif isnumber(val): # int/long + return (bin(val))[2:].encode("L1").decode("L1") + else: + raise Exception("to_bin() requires bytes, hex-ustr, or int/long") def to_bytes(val): - """converts hex-ustr, int/long, or [bin-ustr] to bytes""" - from binascii import a2b_hex - if isinstance(val, list): # [bin-ustr] - val = to_hex(val[0]) - if isnumber(val): # int/long - val = to_hex(val) - if isinstance(val, type("".encode("L1").decode("L1"))): # hex-ustr - return a2b_hex(bytes(val.encode("L1"))) # works on both P2 and P3 - elif isinstance(val, bytes): # so we can use a bytes[x] in P2 or P3 - return val - else: - raise Exception( - "to_bytes() requires hex-ustr, int/long, or [bin-ustr]") + """converts hex-ustr, int/long, or [bin-ustr] to bytes""" + from binascii import a2b_hex + if isinstance(val, list): # [bin-ustr] + val = to_hex(val[0]) + if isnumber(val): # int/long + val = to_hex(val) + if isinstance(val, type("".encode("L1").decode("L1"))): # hex-ustr + return a2b_hex(bytes(val.encode("L1"))) # works on both P2 and P3 + elif isinstance(val, bytes): # so we can use a bytes[x] in P2 or P3 + return val + else: + raise Exception( + "to_bytes() requires hex-ustr, int/long, or [bin-ustr]") def shift(items): - """Shift list items to left, losing the first item. + """Shift list items to left, losing the first item. - in : list - out: list - """ - for i in range(0, (len(items)-1)): - items[i] = items[i+1] - del items[-1] - return items + in : list + out: list + """ + for i in range(0, (len(items)-1)): + items[i] = items[i+1] + del items[-1] + return items def s(string): - """Perform local variable substution, e.g. 'total: {num} items'""" - # http://stackoverflow.com/questions/2960772/ - # putting-a-variable-inside-a-string-python - # http://stackoverflow.com/questions/6618795/ - # get-locals-from-calling-namespace-in-python - import inspect - frame = inspect.currentframe() - try: - rVal = string.format(**frame.f_back.f_locals) - finally: - del frame - return rVal + """Perform local variable substution, e.g. 'total: {num} items'""" + # http://stackoverflow.com/questions/2960772/ + # putting-a-variable-inside-a-string-python + # http://stackoverflow.com/questions/6618795/ + # get-locals-from-calling-namespace-in-python + import inspect + frame = inspect.currentframe() + try: + rVal = string.format(**frame.f_back.f_locals) + finally: + del frame + return rVal def get_object_names(cls, include_subclasses=True): - object_names = [] - for (this_object_name, this_object_id) in list(globals().items()): - if include_subclasses: - if isinstance(this_object_id, cls): - object_names.append(this_object_name) - else: - if type(this_object_id) is cls: - object_names.append(this_object_name) - return object_names + object_names = [] + for (this_object_name, this_object_id) in list(globals().items()): + if include_subclasses: + if isinstance(this_object_id, cls): + object_names.append(this_object_name) + else: + if type(this_object_id) is cls: + object_names.append(this_object_name) + return object_names def touch(filePath, modTime=None): - # http://stackoverflow.com/questions/1158076/implement-touch-using-python - # print(filePath) - import os - if (os.name == "nt"): - if filePath[-1] == ".": filePath += "-" - filePath = filePath.replace("./", ".-/") - with open(filePath, "ab"): - os.utime(filePath, (None if (modTime is None) else (modTime, modTime))) + # http://stackoverflow.com/questions/1158076/implement-touch-using-python + # print(filePath) + import os + if (os.name == "nt"): + if filePath[-1] == ".": filePath += "-" + filePath = filePath.replace("./", ".-/") + with open(filePath, "ab"): + os.utime(filePath, (None if (modTime is None) else (modTime, modTime))) def mkdir(dirPath): - import os - if (os.name == "nt"): - if dirPath[-1] == ".": dirPath += "-" - dirPath = dirPath.replace("./", ".-/") - try: - os.mkdir(dirPath) - except FileExistsError: - pass + import os + if (os.name == "nt"): + if dirPath[-1] == ".": dirPath += "-" + dirPath = dirPath.replace("./", ".-/") + try: + os.mkdir(dirPath) + except FileExistsError: + pass def makedirs(dirPath): - import os - if (os.name == "nt"): - if dirPath[-1] == ".": dirPath += "-" - dirPath = dirPath.replace("./", ".-/") - try: - os.makedirs(dirPath) - except OSError as e: - if (e.errno != errno.EEXIST): - raise + import os + if (os.name == "nt"): + if dirPath[-1] == ".": dirPath += "-" + dirPath = dirPath.replace("./", ".-/") + try: + os.makedirs(dirPath) + except OSError as e: + if (e.errno != errno.EEXIST): + raise def loadFile(filePath): - import os - if (os.name == "nt"): - if filePath[-1] == ".": filePath += "-" - filePath = filePath.replace("./", ".-/") - with open(filePath, "rb") as imageHandle: - return imageHandle.read() + import os + if (os.name == "nt"): + if filePath[-1] == ".": filePath += "-" + filePath = filePath.replace("./", ".-/") + with open(filePath, "rb") as imageHandle: + return imageHandle.read() def saveFile(filePath, fileData): - import os - if (os.name == "nt"): - if filePath[-1] == ".": filePath += "-" - filePath = filePath.replace("./", ".-/") - with open(filePath, "wb") as imageHandle: - imageHandle.write(fileData) + import os + if (os.name == "nt"): + if filePath[-1] == ".": filePath += "-" + filePath = filePath.replace("./", ".-/") + with open(filePath, "wb") as imageHandle: + imageHandle.write(fileData) def isnumber(number): - try: # make sure it's not a string - len(number) - return False - except TypeError: - pass - try: - int(number) - except ValueError: - return False - return True + try: # make sure it's not a string + len(number) + return False + except TypeError: + pass + try: + int(number) + except ValueError: + return False + return True #---- end IvanX general purpose functions ----# @@ -1099,189 +1099,189 @@ args = sys.argv while True: # breaks when there are no more arguments starting with dash - if (len(args) == 1): - usage() + if (len(args) == 1): + usage() - if (slyce(args[1],0,1) != "-"): - break + if (slyce(args[1],0,1) != "-"): + break - if (args[1] == "-s"): - g.nomsg = 1 - args = args[1:] #shift + if (args[1] == "-s"): + g.nomsg = 1 + args = args[1:] #shift - elif (args[1] == "-n"): - g.nodir = 1 - args = args[1:] #shift + elif (args[1] == "-n"): + g.nodir = 1 + args = args[1:] #shift - elif (args[1] == "-uc"): - g.UC = 1 - args = args[1:] #shift + elif (args[1] == "-uc"): + g.UC = 1 + args = args[1:] #shift - elif (args[1] == "-ad"): - g.AD = 1 - g.PNAME = 1 - args = args[1:] #shift + elif (args[1] == "-ad"): + g.AD = 1 + g.PNAME = 1 + args = args[1:] #shift - elif (args[1] == "-shk"): - g.SHK = 1 - args = args[1:] #shift + elif (args[1] == "-shk"): + g.SHK = 1 + args = args[1:] #shift - elif (args[1] == "-pro"): - g.PNAME = 1 - args = args[1:] #shift + elif (args[1] == "-pro"): + g.PNAME = 1 + args = args[1:] #shift - elif (args[1] == "-e"): - g.EX = 1 - g.PNAME = 1 - args = args[1:] #shift + elif (args[1] == "-e"): + g.EX = 1 + g.PNAME = 1 + args = args[1:] #shift - elif (args[1] == "-cat"): - g.CAT = 1 - args = args[1:] #shift + elif (args[1] == "-cat"): + g.CAT = 1 + args = args[1:] #shift - else: - usage() + else: + usage() if g.EX: - if g.AD: usage() + if g.AD: usage() if g.AD: - if g.EX: usage() + if g.EX: usage() if g.CAT: - if not (len(args) == 2): usage() + if not (len(args) == 2): usage() else: - if not ((len(args) == 3) or (len(args) == 4)): usage() + if not ((len(args) == 3) or (len(args) == 4)): usage() g.imageFile = args[1] if not os.path.isfile(g.imageFile): - print("Image/archive file \"" + g.imageFile + "\" was not found.") - quitNow(2) + print("Image/archive file \"" + g.imageFile + "\" was not found.") + quitNow(2) # automatically set ShrinkIt mode if extension suggests it if (g.SHK or - g.imageFile[-3:].lower() == "shk" or - g.imageFile[-3:].lower() == "sdk" or - g.imageFile[-3:].lower() == "bxy"): - if (os.name == "nt"): - print("ShrinkIt archives cannot be extracted on Windows.") - quitNow(2) - else: - try: - with open(os.devnull, "w") as fnull: - subprocess.call("nulib2", stdout = fnull, stderr = fnull) - g.SHK=1 - except Exception: - print("Nulib2 is not available; not expanding ShrinkIt archive.") - quitNow(2) + g.imageFile[-3:].lower() == "shk" or + g.imageFile[-3:].lower() == "sdk" or + g.imageFile[-3:].lower() == "bxy"): + if (os.name == "nt"): + print("ShrinkIt archives cannot be extracted on Windows.") + quitNow(2) + else: + try: + with open(os.devnull, "w") as fnull: + subprocess.call("nulib2", stdout = fnull, stderr = fnull) + g.SHK=1 + except Exception: + print("Nulib2 is not available; not expanding ShrinkIt archive.") + quitNow(2) if (len(args) == 4): - g.extractFile = args[2] + g.extractFile = args[2] if g.extractFile: - targetPath = args[3] - if os.path.isdir(targetPath): - g.targetDir = targetPath - elif (targetPath.rsplit("/", 1) > 1): - g.targetDir = targetPath.rsplit("/", 1)[0] - g.targetName = targetPath.rsplit("/", 1)[1] - if not os.path.isdir(g.targetDir): - print("Target directory not found.") - quitNow(2) + targetPath = args[3] + if os.path.isdir(targetPath): + g.targetDir = targetPath + elif (targetPath.rsplit("/", 1) > 1): + g.targetDir = targetPath.rsplit("/", 1)[0] + g.targetName = targetPath.rsplit("/", 1)[1] + if not os.path.isdir(g.targetDir): + print("Target directory not found.") + quitNow(2) else: - if not g.CAT: - if not os.path.isdir(args[2]): - print("Target directory not found.") - quitNow(2) + if not g.CAT: + if not os.path.isdir(args[2]): + print("Target directory not found.") + quitNow(2) if g.SHK: - g.PNAME = 0 - if not g.CAT: - targetDir = (args[3] if g.extractFile else args[2]) - unshkdir = ('/tmp' + "/cppo-" + str(uuid.uuid4())) - makedirs(unshkdir) - result = os.system("/bin/bash -c 'cd " + unshkdir + "; " + - "result=$(nulib2 -xse " + os.path.abspath(g.imageFile) + - ((" " + args[2].replace('/', ':')) - if g.extractFile else "") + " 2> /dev/null); " + - "if [[ $result == \"Failed.\" ]]; then exit 3; " + - "else if grep -q \"no records match\" <<< \"$result\"" + - " > /dev/null; then exit 2; else exit 0; fi; fi'") - if (result == 512): - print( - "File not found in ShrinkIt archive. Try cppo -cat to get the path,") - print(" and omit any leading slash or colon.") - quitNow(1) - elif (result != 0): - print("ShrinkIt archive is invalid, or some other problem happened.") - quitNow(1) - if g.extractFile: - g.extractFile = g.extractFile.replace(':', '/') - extractPath = (unshkdir + "/" + g.extractFile) - extractPathDir = os.path.dirname(extractPath) - # move the extracted file to the root - newunshkdir = ('/tmp' + "/cppo-" + str(uuid.uuid4())) - makedirs(newunshkdir) - for filename in os.listdir(extractPathDir): - shutil.move(extractPathDir + "/" + filename, newunshkdir) - shutil.rmtree(unshkdir) - unshkdir = newunshkdir + g.PNAME = 0 + if not g.CAT: + targetDir = (args[3] if g.extractFile else args[2]) + unshkdir = ('/tmp' + "/cppo-" + str(uuid.uuid4())) + makedirs(unshkdir) + result = os.system("/bin/bash -c 'cd " + unshkdir + "; " + + "result=$(nulib2 -xse " + os.path.abspath(g.imageFile) + + ((" " + args[2].replace('/', ':')) + if g.extractFile else "") + " 2> /dev/null); " + + "if [[ $result == \"Failed.\" ]]; then exit 3; " + + "else if grep -q \"no records match\" <<< \"$result\"" + + " > /dev/null; then exit 2; else exit 0; fi; fi'") + if (result == 512): + print( + "File not found in ShrinkIt archive. Try cppo -cat to get the path,") + print(" and omit any leading slash or colon.") + quitNow(1) + elif (result != 0): + print("ShrinkIt archive is invalid, or some other problem happened.") + quitNow(1) + if g.extractFile: + g.extractFile = g.extractFile.replace(':', '/') + extractPath = (unshkdir + "/" + g.extractFile) + extractPathDir = os.path.dirname(extractPath) + # move the extracted file to the root + newunshkdir = ('/tmp' + "/cppo-" + str(uuid.uuid4())) + makedirs(newunshkdir) + for filename in os.listdir(extractPathDir): + shutil.move(extractPathDir + "/" + filename, newunshkdir) + shutil.rmtree(unshkdir) + unshkdir = newunshkdir - fileNames = [name for name in sorted(os.listdir(unshkdir)) - if not name.startswith(".")] - if g.nodir: # extract in place from "-n" - curDir = True - elif (len(fileNames) == 1 and - os.path.isdir(unshkdir + "/" + fileNames[0])): - curDir = True # only one folder at top level, so extract in place - volumeName = toProdosName(fileNames[0]) - elif (len(fileNames) == 1 and # disk image, so extract in place - fileNames[0][-1:] == "i"): - curDir = True - volumeName = toProdosName(fileNames[0].split("#")[0]) - else: # extract in folder based on disk image name - curDir = False - volumeName = toProdosName(os.path.basename(g.imageFile)) - if (volumeName[-4:].lower() == ".shk" or - volumeName[-4:].lower() == ".sdk" or - volumeName[-4:].lower() == ".bxy"): - volumeName = volumeName[0:-4] - if not g.CAT and not curDir and not g.extractFile: - print("Extracting into " + volumeName) - # recursively process unshrunk archive hierarchy - for dirName, subdirList, fileList in os.walk(unshkdir): - subdirList.sort() - if not g.CAT: - g.targetDir = (targetDir + ("" if curDir else ("/" + volumeName)) + - ("/" if (dirName.count('/') > 2) else "") + - ("/".join(dirName.split('/')[3:]))) # chop tempdir - if g.extractFile: # solo item, so don't put it in the tree - g.targetDir = targetDir - if g.UC: - g.targetDir = g.targetDir.upper() - g.ADdir = (g.targetDir + "/.AppleDouble") - makedirs(g.targetDir) - if g.AD: - makedirs(g.ADdir) - for fname in sorted(fileList): - if (fname[-1:] == "i"): - # disk image; rename to include suffix and correct type/auxtype - imagePath = os.path.join(dirName, fname).split("#")[0] - new_name = (imagePath + - ("" if (imagePath.lower().endswith(".po") or - imagePath.lower().endswith(".hdv")) - else ".PO") + "#e00005") - os.rename(os.path.join(dirName, fname), new_name) - fname = os.path.basename(new_name) - g.shk_hasrf = False - rfork = False - if (fname[-1:] == "r" and - os.path.isfile(os.path.join(dirName, fname[:-1]))): - rfork = True - elif (os.path.isfile(os.path.join(dirName, (fname + "r")))): - g.shk_hasrf = True - if not rfork: - processEntry(dirName, fname) - shutil.rmtree(unshkdir, True) - quitNow(0) + fileNames = [name for name in sorted(os.listdir(unshkdir)) + if not name.startswith(".")] + if g.nodir: # extract in place from "-n" + curDir = True + elif (len(fileNames) == 1 and + os.path.isdir(unshkdir + "/" + fileNames[0])): + curDir = True # only one folder at top level, so extract in place + volumeName = toProdosName(fileNames[0]) + elif (len(fileNames) == 1 and # disk image, so extract in place + fileNames[0][-1:] == "i"): + curDir = True + volumeName = toProdosName(fileNames[0].split("#")[0]) + else: # extract in folder based on disk image name + curDir = False + volumeName = toProdosName(os.path.basename(g.imageFile)) + if (volumeName[-4:].lower() == ".shk" or + volumeName[-4:].lower() == ".sdk" or + volumeName[-4:].lower() == ".bxy"): + volumeName = volumeName[0:-4] + if not g.CAT and not curDir and not g.extractFile: + print("Extracting into " + volumeName) + # recursively process unshrunk archive hierarchy + for dirName, subdirList, fileList in os.walk(unshkdir): + subdirList.sort() + if not g.CAT: + g.targetDir = (targetDir + ("" if curDir else ("/" + volumeName)) + + ("/" if (dirName.count('/') > 2) else "") + + ("/".join(dirName.split('/')[3:]))) # chop tempdir + if g.extractFile: # solo item, so don't put it in the tree + g.targetDir = targetDir + if g.UC: + g.targetDir = g.targetDir.upper() + g.ADdir = (g.targetDir + "/.AppleDouble") + makedirs(g.targetDir) + if g.AD: + makedirs(g.ADdir) + for fname in sorted(fileList): + if (fname[-1:] == "i"): + # disk image; rename to include suffix and correct type/auxtype + imagePath = os.path.join(dirName, fname).split("#")[0] + new_name = (imagePath + + ("" if (imagePath.lower().endswith(".po") or + imagePath.lower().endswith(".hdv")) + else ".PO") + "#e00005") + os.rename(os.path.join(dirName, fname), new_name) + fname = os.path.basename(new_name) + g.shk_hasrf = False + rfork = False + if (fname[-1:] == "r" and + os.path.isfile(os.path.join(dirName, fname[:-1]))): + rfork = True + elif (os.path.isfile(os.path.join(dirName, (fname + "r")))): + g.shk_hasrf = True + if not rfork: + processEntry(dirName, fname) + shutil.rmtree(unshkdir, True) + quitNow(0) # end script if SHK @@ -1289,96 +1289,96 @@ g.imageData = loadFile(g.imageFile) # detect if image is 2mg and remove 64-byte header if so if (g.imageFile.lower().endswith(".2mg") or - g.imageFile.lower().endswith(".2img")): - g.imageData = g.imageData[64:] + g.imageFile.lower().endswith(".2img")): + g.imageData = g.imageData[64:] # handle 140K disk image if (len(g.imageData) == 143360): - #print("140K disk") - prodosDisk = 0 - fixOrder = 0 - # is it ProDOS? - if (to_hex(readchars(g.imageData, ts(0,0)+0, 4)) == '0138b003'): - #print("detected ProDOS by boot block") - if (readchars(g.imageData, ts(0,1)+3, 6) == b'PRODOS'): - prodosDisk = 1 - #print("order OK (PO)") - elif (readchars(g.imageData, ts(0,14)+3, 6) == b'PRODOS'): - #print("order needs fixing (DO)") - prodosDisk = 1 - fixOrder = 1 - # is it DOS 3.3? - else: - #print("it's not ProDOS") - if (readcharDec(g.imageData, ts(17,0)+3) == 3): - vtocT = readcharDec(g.imageData, ts(17,0)+1) - vtocS = readcharDec(g.imageData, ts(17,0)+2) - if (vtocT<35 and vtocS<16): - #print("it's DOS 3.3") - g.D33 = 1 - # it's DOS 3.3; check sector order next - if (readcharDec(g.imageData, ts(17,14)+2) != 13): - #print("order needs fixing (PO)") - fixOrder = 1 - #else: # remove this - # print("order OK (DO)") - # pass - # fall back on disk extension if weird boot block (e.g. AppleCommander) - if not prodosDisk and not g.D33: - #print("format and ordering unknown, checking extension") - if (g.imageFile.lower().endswith(".dsk") or - g.imageFile.lower().endswith(".do")): - fixOrder = 1 - # print("extension indicates DO, changing to PO") - if fixOrder: - #print("fixing order") - # for each track, - # read each sector in the right sequence to make - # valid ProDOS blocks (sector pairs) - imageDataFixed = bytearray(143360) - for t in range(0, 35): - for s in [0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15]: - writechars(imageDataFixed, - ts(t,((15-s) if (s%15) else s)), - readchars(g.imageData, ts(t,s), 256)) - g.imageData = bytes(imageDataFixed) - #print("saving fixed order file as outfile.dsk") - #saveFile("outfile.dsk", g.imageData) - #print("saved") + #print("140K disk") + prodosDisk = 0 + fixOrder = 0 + # is it ProDOS? + if (to_hex(readchars(g.imageData, ts(0,0)+0, 4)) == '0138b003'): + #print("detected ProDOS by boot block") + if (readchars(g.imageData, ts(0,1)+3, 6) == b'PRODOS'): + prodosDisk = 1 + #print("order OK (PO)") + elif (readchars(g.imageData, ts(0,14)+3, 6) == b'PRODOS'): + #print("order needs fixing (DO)") + prodosDisk = 1 + fixOrder = 1 + # is it DOS 3.3? + else: + #print("it's not ProDOS") + if (readcharDec(g.imageData, ts(17,0)+3) == 3): + vtocT = readcharDec(g.imageData, ts(17,0)+1) + vtocS = readcharDec(g.imageData, ts(17,0)+2) + if (vtocT<35 and vtocS<16): + #print("it's DOS 3.3") + g.D33 = 1 + # it's DOS 3.3; check sector order next + if (readcharDec(g.imageData, ts(17,14)+2) != 13): + #print("order needs fixing (PO)") + fixOrder = 1 + #else: # remove this + # print("order OK (DO)") + # pass + # fall back on disk extension if weird boot block (e.g. AppleCommander) + if not prodosDisk and not g.D33: + #print("format and ordering unknown, checking extension") + if (g.imageFile.lower().endswith(".dsk") or + g.imageFile.lower().endswith(".do")): + fixOrder = 1 + # print("extension indicates DO, changing to PO") + if fixOrder: + #print("fixing order") + # for each track, + # read each sector in the right sequence to make + # valid ProDOS blocks (sector pairs) + imageDataFixed = bytearray(143360) + for t in range(0, 35): + for s in [0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15]: + writechars(imageDataFixed, + ts(t,((15-s) if (s%15) else s)), + readchars(g.imageData, ts(t,s), 256)) + g.imageData = bytes(imageDataFixed) + #print("saving fixed order file as outfile.dsk") + #saveFile("outfile.dsk", g.imageData) + #print("saved") - if not prodosDisk and not g.D33: - print("Warning: Unable to determine disk format, assuming ProDOS.") + if not prodosDisk and not g.D33: + print("Warning: Unable to determine disk format, assuming ProDOS.") # enforce leading slash if ProDOS if (not g.SHK and - not g.D33 and - g.extractFile and - (slyce(args[2],0,1) != "/") and - (slyce(args[2],0,1) != ":")): - usage() + not g.D33 and + g.extractFile and + (slyce(args[2],0,1) != "/") and + (slyce(args[2],0,1) != ":")): + usage() if g.D33: - diskName = os.path.basename(g.imageFile) - if (diskName[-4:].lower() == ".dsk" or - diskName[-3:].lower() == ".do" or - diskName[-3:].lower() == ".po"): - diskName = os.path.splitext(diskName)[0] - if g.PNAME: - diskName = toProdosName(diskName) - if not g.CAT: - g.targetDir = (args[3] if g.extractFile - else (args[2] + "/" + diskName)) - g.ADdir = (g.targetDir + "/.AppleDouble") - makedirs(g.targetDir) - if g.AD: - makedirs(g.ADdir) - if not g.extractFile: - print("Extracting into " + diskName) - processDir([readcharDec(g.imageData, ts(17,0)+1), - readcharDec(g.imageData, ts(17,0)+2)]) - if g.extractFile: - print("ProDOS file not found within image file.") - quitNow(0) + diskName = os.path.basename(g.imageFile) + if (diskName[-4:].lower() == ".dsk" or + diskName[-3:].lower() == ".do" or + diskName[-3:].lower() == ".po"): + diskName = os.path.splitext(diskName)[0] + if g.PNAME: + diskName = toProdosName(diskName) + if not g.CAT: + g.targetDir = (args[3] if g.extractFile + else (args[2] + "/" + diskName)) + g.ADdir = (g.targetDir + "/.AppleDouble") + makedirs(g.targetDir) + if g.AD: + makedirs(g.ADdir) + if not g.extractFile: + print("Extracting into " + diskName) + processDir([readcharDec(g.imageData, ts(17,0)+1), + readcharDec(g.imageData, ts(17,0)+2)]) + if g.extractFile: + print("ProDOS file not found within image file.") + quitNow(0) # below: ProDOS @@ -1391,27 +1391,27 @@ g.PDOSPATH_INDEX = 0 g.PNAME = 0 if g.extractFile: - g.PDOSPATH = g.extractFile.replace(':', '/').split('/') - g.extractFile = None - if not g.PDOSPATH[0]: - g.PDOSPATH_INDEX += 1 - g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX] - g.ADdir = (g.targetDir + "/.AppleDouble") - if not ((not g.AD) or os.path.isdir(g.ADdir)): - mkdir(g.ADdir) - processDir(2) - print("ProDOS file not found within image file.") - quitNow(2) + g.PDOSPATH = g.extractFile.replace(':', '/').split('/') + g.extractFile = None + if not g.PDOSPATH[0]: + g.PDOSPATH_INDEX += 1 + g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX] + g.ADdir = (g.targetDir + "/.AppleDouble") + if not ((not g.AD) or os.path.isdir(g.ADdir)): + mkdir(g.ADdir) + processDir(2) + print("ProDOS file not found within image file.") + quitNow(2) else: - if not g.CAT: - # print(args[0], args[1], args[2]) - g.targetDir = (args[2] + "/" + getVolumeName().decode("L1")) - g.ADdir = (g.targetDir + "/.AppleDouble") - if not os.path.isdir(g.targetDir): - makedirs(g.targetDir) - if not ((not g.AD) or os.path.isdir(g.ADdir)): - makedirs(g.ADdir) - processDir(2) - if not g.CAT: - quitNow(0) + if not g.CAT: + # print(args[0], args[1], args[2]) + g.targetDir = (args[2] + "/" + getVolumeName().decode("L1")) + g.ADdir = (g.targetDir + "/.AppleDouble") + if not os.path.isdir(g.targetDir): + makedirs(g.targetDir) + if not ((not g.AD) or os.path.isdir(g.ADdir)): + makedirs(g.ADdir) + processDir(2) + if not g.CAT: + quitNow(0) diff --git a/setup/dopo.txt b/setup/dopo.txt old mode 100644 new mode 100755 index 17b2c87..c080ead --- a/setup/dopo.txt +++ b/setup/dopo.txt @@ -1,76 +1,76 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # follows gzip syntax -- acts in place if filename provided, outputs to # stdout with -c, accepts stdin and outputs to stdout if filename is - or absent # output to stdout? if [[ "$1" == "-c" ]]; then - shift; - stdout=1; + shift; + stdout=1; else - stdout= + stdout= fi # use stdin? if [[ ! $1 || "$1" == "-" ]]; then - stdin=1 - stdout=1 + stdin=1 + stdout=1 elif [[ $1 && ! -f "$1" ]]; then - echo "usage: dopo [-c] [-|140KdiskImageFilename] 1>&2"; - exit 1; + echo "usage: dopo [-c] [-|140KdiskImageFilename] 1>&2"; + exit 1; else - stdin= + stdin= fi if [[ ! $stdout ]]; then - #get filename extension, in lowercase - f="$(tr [:upper:] [:lower:] <<< ${1##*.})"; + #get filename extension, in lowercase + f="$(tr [:upper:] [:lower:] <<< ${1##*.})"; - #if it's dsk/do/po, get name without extension - [[ "$f" == "dsk" || "$f" == "do" || "$f" == "po" ]] && of="${1%.*}" || of="$1"; + #if it's dsk/do/po, get name without extension + [[ "$f" == "dsk" || "$f" == "do" || "$f" == "po" ]] && of="${1%.*}" || of="$1"; - #if name had .po extension, append .dsk to outfile name, otherwise append .po - [[ "$f" == "po" ]] && of="$of.dsk" || of="$of.po" + #if name had .po extension, append .dsk to outfile name, otherwise append .po + [[ "$f" == "po" ]] && of="$of.dsk" || of="$of.po" - # set outfile param for dd - ofile="$of" + # set outfile param for dd + ofile="$of" else - ofile="/tmp/$$.dopo_out" + ofile="/tmp/$$.dopo_out" fi if [[ ! $stdin ]]; then - # set infile param for dd - ifile="$1" + # set infile param for dd + ifile="$1" elif [[ -t 0 ]]; then - echo "usage: dopo [-c] [-|140KdiskImageFilename]" 1>&2; exit 1; + echo "usage: dopo [-c] [-|140KdiskImageFilename]" 1>&2; exit 1; else - ifile="/tmp/$$.dopo_in" - cat > "$ifile" + ifile="/tmp/$$.dopo_in" + cat > "$ifile" fi # verify file is 140K by successfully reading 140K'th byte, and failing to read the one past [[ $(dd if="$ifile" of=/dev/null bs=1 skip=143359 2>&1 | tail -1 | cut -d ' ' -f 1) -ne 1 || $(dd if="$ifile" of=/dev/null bs=1 skip=143360 2>&1 | tail -1 | cut -d ' ' -f 1) -ne 0 ]] && badInput=1 || badInput= if [[ $badInput ]]; then - if [[ ! $stdin ]]; then - echo -n "$1 doesn't appear to be a 140K image. Continue? " 1>&2; - read - [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]] || exit 1; - else - echo "warning: Input file doesn't appear to be a 140K image." 1>&2 - echo " Output file is likely to be useless." 1>&2 - fi + if [[ ! $stdin ]]; then + echo -n "$1 doesn't appear to be a 140K image. Continue? " 1>&2; + read + [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]] || exit 1; + else + echo "warning: Input file doesn't appear to be a 140K image." 1>&2 + echo " Output file is likely to be useless." 1>&2 + fi fi # for each track for t in {0..34}; do - # read each sector in the right sequence to make (or unmake) - # valid ProDOS blocks (sector pairs) - for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do - # copy the sector from the old file to the new one - dd if="$ifile" of="$ofile" bs=256 count=1 skip=$(( t*16 + s )) seek=$(( t*16 + (s==0 || s==15 ? s : 15-s) )) 2> /dev/null - done + # read each sector in the right sequence to make (or unmake) + # valid ProDOS blocks (sector pairs) + for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do + # copy the sector from the old file to the new one + dd if="$ifile" of="$ofile" bs=256 count=1 skip=$(( t*16 + s )) seek=$(( t*16 + (s==0 || s==15 ? s : 15-s) )) 2> /dev/null + done done # remove the old one diff --git a/setup/dos2pro.txt b/setup/dos2pro.txt old mode 100644 new mode 100755 index 6a781ba..ee3a3cd --- a/setup/dos2pro.txt +++ b/setup/dos2pro.txt @@ -1,5 +1,5 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: readcharDec () { # read one character from file & convert to equivalent decimal value @@ -8,17 +8,17 @@ readcharDec () { # out: decimal value from 0-255 # exit: 8=extraneous arg, 11=missing arg1, # 21=invalid arg1, 22=invalid arg2 - [[ $1 ]] || return 11 - [[ $3 ]] && return 8 - [[ -f $1 ]] || return 21 - [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ - && ( $2 -ge 0 ) ]] || return 22; } - # args are valid - charX="$(dd if="$1" bs=1 skip=$(($2)) \ - count=1 2> /dev/null; echo -n X)" - [[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; } - echo -n "${charX:0:1}" | od -t u1 | \ - head -1 | sed 's/[0\ ]*//' | tr -d ' \n' + [[ $1 ]] || return 11 + [[ $3 ]] && return 8 + [[ -f $1 ]] || return 21 + [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ + && ( $2 -ge 0 ) ]] || return 22; } + # args are valid + charX="$(dd if="$1" bs=1 skip=$(($2)) \ + count=1 2> /dev/null; echo -n X)" + [[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; } + echo -n "${charX:0:1}" | od -t u1 | \ + head -1 | sed 's/[0\ ]*//' | tr -d ' \n' } readcharHex () { @@ -28,31 +28,31 @@ readcharHex () { # out: two-digit hex value from 00-FF # exit: 8=extraneous arg, 11=missing arg1, # 21=invalid arg1, 22=invalid arg2 - [[ $1 ]] || return 11 - [[ $3 ]] && return 8 - [[ -f $1 ]] || return 21 - [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ - && ( $2 -ge 0 ) ]] || return 22; } - # args are valid - charX="$(dd if="$1" bs=1 skip=$(($2)) \ - count=1 2> /dev/null; echo -n X)" - [[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } - printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ - head -1 | sed 's/[0\ ]*//' | tr -d ' \n') + [[ $1 ]] || return 11 + [[ $3 ]] && return 8 + [[ -f $1 ]] || return 21 + [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ + && ( $2 -ge 0 ) ]] || return 22; } + # args are valid + charX="$(dd if="$1" bs=1 skip=$(($2)) \ + count=1 2> /dev/null; echo -n X)" + [[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } + printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ + head -1 | sed 's/[0\ ]*//' | tr -d ' \n') } ### start usage () { - echo "Usage:" - echo "all files: dos2pro dosImageName" - echo "one file : dos2pro dosImageName DOSFILE" - echo "notes:" - echo " Wildcard matching (*) is not supported." - echo " Illegal prodos characters will be made into periods, and names" - echo " will be truncated at 15 characters and possibly overwrite" - echo " other files if they match a previous name conversion." - exit 1 + echo "Usage:" + echo "all files: dos2pro dosImageName" + echo "one file : dos2pro dosImageName DOSFILE" + echo "notes:" + echo " Wildcard matching (*) is not supported." + echo " Illegal prodos characters will be made into periods, and names" + echo " will be truncated at 15 characters and possibly overwrite" + echo " other files if they match a previous name conversion." + exit 1 } [[ $1 == "-h" || $1 == "--help" || ! $1 || ! -f "$1" ]] && usage @@ -64,62 +64,62 @@ dosImageBasename=$(basename "$dosImage") proImage="${dosImageBasename%.*}_prodos.po" if [[ ! -f "$proImage" ]]; then - echo "Creating $proImage..." - mkpo -b 280 "$proImage" + echo "Creating $proImage..." + mkpo -b 280 "$proImage" else - echo "Found $proImage..." + echo "Found $proImage..." fi if [[ ! $(acmd -i "$dosImage" 2> /dev/null | grep "Disk Format: DOS 3.3") ]]; then - echo "The file '$dosImage' doesn't appear to be a DOS 3.3 disk image." - exit 2 + echo "The file '$dosImage' doesn't appear to be a DOS 3.3 disk image." + exit 2 fi dosLines=$(acmd -ll "$dosImage") IFS='' while read thisLine; do - if [[ ${thisLine:0:2} == "* " || ${thisLine:0:2} == " " ]]; then - dosName=$(cut -c 5- <<< $thisLine | rev | sed 's/^[^ ]* [^ ]* [^ ]* [^ ]* [^ ]* \(.*$\)/\1/' | rev) - if [[ ! $fileName || "$fileName" == "$dosName" ]]; then + if [[ ${thisLine:0:2} == "* " || ${thisLine:0:2} == " " ]]; then + dosName=$(cut -c 5- <<< $thisLine | rev | sed 's/^[^ ]* [^ ]* [^ ]* [^ ]* [^ ]* \(.*$\)/\1/' | rev) + if [[ ! $fileName || "$fileName" == "$dosName" ]]; then - dosType=$(cut -c 3 <<< $thisLine) - if [[ $dosType == "A" ]]; then - proType="BAS" - binAddr="0801" - elif [[ $dosType == "I" ]]; then - proType="INT" - elif [[ $dosType == "T" ]]; then - proType="TXT" - elif [[ $dosType == "B" ]]; then - proType="BIN" - sector=$(rev <<< $thisLine | cut -f2 -d ' ' | rev | cut -c 2-) - track=$(rev <<< $thisLine | cut -f3 -d ' ' | rev | cut -c 2-) - offset=$(( (track * 16 + sector) * 256 + 12 )) - track=$(readcharDec "$dosImage" $offset) - sector=$(readcharDec "$dosImage" $((offset+1))) - offset=$(( (track * 16 + sector) * 256 )) - binAddr=$(readcharHex "$dosImage" $((offset+1)))$(readcharHex "$dosImage" $offset) - else - echo "Error: Unknown DOS 3.3 file type." - exit 2 - fi + dosType=$(cut -c 3 <<< $thisLine) + if [[ $dosType == "A" ]]; then + proType="BAS" + binAddr="0801" + elif [[ $dosType == "I" ]]; then + proType="INT" + elif [[ $dosType == "T" ]]; then + proType="TXT" + elif [[ $dosType == "B" ]]; then + proType="BIN" + sector=$(rev <<< $thisLine | cut -f2 -d ' ' | rev | cut -c 2-) + track=$(rev <<< $thisLine | cut -f3 -d ' ' | rev | cut -c 2-) + offset=$(( (track * 16 + sector) * 256 + 12 )) + track=$(readcharDec "$dosImage" $offset) + sector=$(readcharDec "$dosImage" $((offset+1))) + offset=$(( (track * 16 + sector) * 256 )) + binAddr=$(readcharHex "$dosImage" $((offset+1)))$(readcharHex "$dosImage" $offset) + else + echo "Error: Unknown DOS 3.3 file type." + exit 2 + fi - proName=$(sed 's/^[^A-Za-z]/A/' <<< $dosName | sed 's/[^A-Za-z0-9\.]/./g') + proName=$(sed 's/^[^A-Za-z]/A/' <<< $dosName | sed 's/[^A-Za-z0-9\.]/./g') - auxType= - [[ $binAddr ]] && auxType="\$$binAddr" - echo "Copying '$dosName' to '$proName'" - acmd -g "$dosImage" "$dosName" - | acmd -p "$proImage" "$proName" "$proType" "$auxType" - filesCopied=1 - fi - fi + auxType= + [[ $binAddr ]] && auxType="\$$binAddr" + echo "Copying '$dosName' to '$proName'" + acmd -g "$dosImage" "$dosName" - | acmd -p "$proImage" "$proName" "$proType" "$auxType" + filesCopied=1 + fi + fi done <<< $dosLines if [[ ! $filesCopied ]]; then - if [[ $fileName ]]; then - echo "File '$fileName' not found on DOS 3.3 disk image." - else - echo "No files copied." - fi + if [[ $fileName ]]; then + echo "File '$fileName' not found on DOS 3.3 disk image." + else + echo "No files copied." + fi fi diff --git a/setup/gsport-setup-shell.txt b/setup/gsport-setup-shell.txt old mode 100644 new mode 100755 index 4947fe5..75fb199 --- a/setup/gsport-setup-shell.txt +++ b/setup/gsport-setup-shell.txt @@ -1,9 +1,9 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: wget -qO /tmp/gsport-setup https://raw.githubusercontent.com/RasppleII/a2cloud/master/setup/gsport-setup.txt if [[ $(wc -c /tmp/gsport-setup | grep '^0 ') ]]; then - echo "Please connect to the internet to set up GSport." + echo "Please connect to the internet to set up GSport." else - source /tmp/gsport-setup "$@" + source /tmp/gsport-setup "$@" fi diff --git a/setup/gsport-setup.txt b/setup/gsport-setup.txt index adeeb21..61afe95 100755 --- a/setup/gsport-setup.txt +++ b/setup/gsport-setup.txt @@ -1,5 +1,5 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # to do: replace Spectrum Deluxe (2.5.3) with Spectrum Gold (2.5.4) @@ -10,17 +10,17 @@ readcharHex () { # out: two-digit hex value from 00-FF # exit: 8=extraneous arg, 11=missing arg1, # 21=invalid arg1, 22=invalid arg2 - [[ $1 ]] || return 11 - [[ $3 ]] && return 8 - [[ -f $1 ]] || return 21 - [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ - && ( $2 -ge 0 ) ]] || return 22; } - # args are valid - charX="$(dd if="$1" bs=1 skip=$(($2)) \ - count=1 2> /dev/null; echo -n X)" - [[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } - printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ - head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | tr [A-Z] [a-z] + [[ $1 ]] || return 11 + [[ $3 ]] && return 8 + [[ -f $1 ]] || return 21 + [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ + && ( $2 -ge 0 ) ]] || return 22; } + # args are valid + charX="$(dd if="$1" bs=1 skip=$(($2)) \ + count=1 2> /dev/null; echo -n X)" + [[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } + printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ + head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | tr [A-Z] [a-z] } readchars () { @@ -31,16 +31,16 @@ readchars () { # out: sequence of characters # exit: 8=extraneous arg, 11=missing arg1, # 21=invalid arg1, 22=invalid arg2, 23=invalid arg3 - [[ $1 ]] || return 11 - [[ $4 ]] && return 8 - [[ -f $1 ]] || return 21 - [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ - && ( $2 -ge 0 ) ]] || return 22; } - [[ $3 ]] && { [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ - && ( $3 -ge 0 ) ]] || return 23; } - # args are valid - dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \ - 2> /dev/null + [[ $1 ]] || return 11 + [[ $4 ]] && return 8 + [[ -f $1 ]] || return 21 + [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ + && ( $2 -ge 0 ) ]] || return 22; } + [[ $3 ]] && { [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ + && ( $3 -ge 0 ) ]] || return 23; } + # args are valid + dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \ + 2> /dev/null } writecharsHex () { @@ -51,23 +51,23 @@ writecharsHex () { # out: nothing # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, # 13=missing arg3, 22=invalid arg2, 23=invalid arg3 - [[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 - [[ $4 ]] && return 8 - [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ - && ( $2 -ge 0 ) ]] || return 22 - p=0 - offset=$2 - len=${#3} - while (( p < len )); do - outByte=${3:$p:2} - [[ $(printf %02X "0x$outByte" 2> /dev/null) == \ - $(echo -n "$outByte" | tr [a-z] [A-Z]) ]] || return 23 - # args are valid - echo -n -e "\x$outByte" | \ - dd of="$1" bs=1 seek=$offset conv=notrunc 2> /dev/null - (( p += 3 )) - (( offset++ )) - done + [[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 + [[ $4 ]] && return 8 + [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ + && ( $2 -ge 0 ) ]] || return 22 + p=0 + offset=$2 + len=${#3} + while (( p < len )); do + outByte=${3:$p:2} + [[ $(printf %02X "0x$outByte" 2> /dev/null) == \ + $(echo -n "$outByte" | tr [a-z] [A-Z]) ]] || return 23 + # args are valid + echo -n -e "\x$outByte" | \ + dd of="$1" bs=1 seek=$offset conv=notrunc 2> /dev/null + (( p += 3 )) + (( offset++ )) + done } @@ -75,12 +75,12 @@ writecharsHex () { # Ensure URL we'll use ends in a / case "$A2CLOUD_SCRIPT_URL" in - */) scriptURL="$A2CLOUD_SCRIPT_URL" ;; - *) scriptURL="${A2CLOUD_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2cloud/master}/" ;; + */) scriptURL="$A2CLOUD_SCRIPT_URL" ;; + *) scriptURL="${A2CLOUD_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2cloud/master}/" ;; esac case "$A2CLOUD_BINARY_URL" in - */) binaryURL="$A2CLOUD_BINARY_URL" ;; - *) binaryURL="${A2CLOUD_BINARY_URL:-http://ivanx.com/a2cloud/files}/" ;; + */) binaryURL="$A2CLOUD_BINARY_URL" ;; + *) binaryURL="${A2CLOUD_BINARY_URL:-http://ivanx.com/a2cloud/files}/" ;; esac useExternalURL=1 [[ $A2CLOUD_NO_EXTERNAL ]] && useExternalURL= @@ -90,41 +90,41 @@ 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" + 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 + debianMajor=$(cut -d . -f 1 <<< $debianVersion) + if [[ $debianMajor == "8" ]]; then + debianName="jessie" + elif [[ $debianMajor == "7" ]]; then + debianName="wheezy" + else + debianName="unknown" + fi fi isSystemd= isSysVInit= # If you really want something else, *you* maintain it! if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then - isSystemd=1 + isSystemd=1 elif [[ -f /etc/inittab ]]; then - isSysVInit=1 + isSysVInit=1 fi emulatorName="GSport" @@ -148,93 +148,93 @@ kegs= acmdOK= if hash acmd 2> /dev/null; then - acmdOK=1 + acmdOK=1 fi while { [[ $1 ]] || (( (0 + $gisk + $noDisks + $installDisks + 0) > 1 )); }; do - arg=$(tr -d '-' <<< ${1,,}) - if [[ $arg == "6" ]]; then - slot6=1 - shift - elif [[ $arg == "rom1" ]]; then - rom=ROM1 - shift - elif [[ $arg == "rom3" ]]; then - rom=ROM3 - shift - elif [[ $arg == "n" ]]; then - noDisks=1 - shift - elif [[ $arg == "g" ]]; then - gisk=1 - shift - elif [[ $arg == "i" ]]; then - installDisks=1 - shift - elif [[ $arg == "y" ]]; then - autoAnswerYes=1 - shift - else - echo "Usage: $emulatorSetup [rom1|rom3] [-6] [-y [-g|-i|-n]]" - echo "rom1: use GS ROM 01" - echo "rom3: use GS ROM 3" - echo "-6: put blank disks in slot 6" - echo "-y: auto-answer yes (no prompting)" - echo "-i: use GS/OS and Spectrum installer disk images (use with -y)" - echo "-g: use GSport Internet Starter Kit disk image (use with -y)" - echo "-n: don't provide any disk images (use with -y)" - exit 1 - fi + arg=$(tr -d '-' <<< ${1,,}) + if [[ $arg == "6" ]]; then + slot6=1 + shift + elif [[ $arg == "rom1" ]]; then + rom=ROM1 + shift + elif [[ $arg == "rom3" ]]; then + rom=ROM3 + shift + elif [[ $arg == "n" ]]; then + noDisks=1 + shift + elif [[ $arg == "g" ]]; then + gisk=1 + shift + elif [[ $arg == "i" ]]; then + installDisks=1 + shift + elif [[ $arg == "y" ]]; then + autoAnswerYes=1 + shift + else + echo "Usage: $emulatorSetup [rom1|rom3] [-6] [-y [-g|-i|-n]]" + echo "rom1: use GS ROM 01" + echo "rom3: use GS ROM 3" + echo "-6: put blank disks in slot 6" + echo "-y: auto-answer yes (no prompting)" + echo "-i: use GS/OS and Spectrum installer disk images (use with -y)" + echo "-g: use GSport Internet Starter Kit disk image (use with -y)" + echo "-n: don't provide any disk images (use with -y)" + exit 1 + fi done echo if [[ ! -f /usr/local/lib/$romFileName ]]; then - echo "$emulatorName needs to be set up. This may take several minutes." - if [[ ! $autoAnswerYes ]]; then - echo -n "Do you want to set up $emulatorName now? "; - read - if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then - exit 1 - fi - fi - echo "Ok, let's go!" - echo + echo "$emulatorName needs to be set up. This may take several minutes." + if [[ ! $autoAnswerYes ]]; then + echo -n "Do you want to set up $emulatorName now? "; + read + if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then + exit 1 + fi + fi + echo "Ok, let's go!" + echo fi if [[ ! $autoAnswerYes ]]; then - noDisks= - gisk= - while true; do - option1=0 - option2=0 - echo - echo "Do you want to:" - echo - if [[ $acmdOK ]]; then - [[ $kegs ]] && andSpectrum= || andSpectrum="and Spectrum " - echo "1) install GS/OS ${andSpectrum}from the installer disk images" - option1=1 - fi - if [[ ! $kegs ]]; then - echo "2) use the premade GSport Internet Starter Kit hard drive image" - option2=2 - fi - echo "3) prepare $emulatorName for use but don't provide any disk images" - echo "4) do nothing and quit" - echo - echo -n "Your choice: " - read - noDisks= - if [[ ${REPLY} == "4" ]]; then - [[ $0 == "-bash" ]] && return 1 || exit 1 - elif [[ ${REPLY} == "3" ]]; then - noDisks=1; break - elif [[ ${REPLY} == $option2 ]]; then - gisk=1; break - elif [[ ${REPLY} == $option1 ]]; then - gisk=; break - fi - done + noDisks= + gisk= + while true; do + option1=0 + option2=0 + echo + echo "Do you want to:" + echo + if [[ $acmdOK ]]; then + [[ $kegs ]] && andSpectrum= || andSpectrum="and Spectrum " + echo "1) install GS/OS ${andSpectrum}from the installer disk images" + option1=1 + fi + if [[ ! $kegs ]]; then + echo "2) use the premade GSport Internet Starter Kit hard drive image" + option2=2 + fi + echo "3) prepare $emulatorName for use but don't provide any disk images" + echo "4) do nothing and quit" + echo + echo -n "Your choice: " + read + noDisks= + if [[ ${REPLY} == "4" ]]; then + [[ $0 == "-bash" ]] && return 1 || exit 1 + elif [[ ${REPLY} == "3" ]]; then + noDisks=1; break + elif [[ ${REPLY} == $option2 ]]; then + gisk=1; break + elif [[ ${REPLY} == $option1 ]]; then + gisk=; break + fi + done fi sudo mkdir -p "$imagesDir" @@ -248,54 +248,54 @@ sudo apt-get -y update > /dev/null # http://wakaba.c3.cx/s/apps/unarchiver.html if ! hash unar 2> /dev/null; then - ### ArchiveTools: Install unar package - echo "A2CLOUD: Installing The Unarchiver..." + ### ArchiveTools: Install unar package + 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 + # 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 ! 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 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 + 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 $tempDir/unar &> /dev/null - mkdir $tempDir/unar - cd $tempDir/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 $tempDir/unar - fi - sudo mandb &> /dev/null - fi + rm -rf $tempDir/unar &> /dev/null + mkdir $tempDir/unar + cd $tempDir/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 $tempDir/unar + fi + sudo mandb &> /dev/null + fi else - echo "A2CLOUD: The Unarchiver has already been installed." + echo "A2CLOUD: The Unarchiver has already been installed." fi cd $tempDir @@ -305,141 +305,141 @@ sudo chmod ugo+x /usr/local/bin/mkpo if ! hash nulib2 2> /dev/null; then - echo "A2CLOUD: Installing nulib2..." + echo "A2CLOUD: Installing nulib2..." - cd $tempDir - if [[ $downloadBinaries ]]; then - ### ArchiveTools: Install nulib2 binaries - wget -qO- "${binaryURL}precompiled/nulib2-${arch}_${debianName}.tgz" | sudo tar Pzx - fi + cd $tempDir + if [[ $downloadBinaries ]]; then + ### ArchiveTools: Install nulib2 binaries + wget -qO- "${binaryURL}precompiled/nulib2-${arch}_${debianName}.tgz" | sudo tar Pzx + fi - if ! hash nulib2 2> /dev/null; then - ### ArchiveTools: Install nulib2 from source - sudo apt-get -y install build-essential - sudo apt-get -y install zlib1g-dev - sudo apt-get -y clean + if ! hash nulib2 2> /dev/null; then + ### ArchiveTools: Install nulib2 from source + 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 $tempDir - rm -rf nulib - fi + # 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 $tempDir + rm -rf nulib + fi else - echo "A2CLOUD: nulib2 is already installed." + echo "A2CLOUD: nulib2 is already installed." fi cd $tempDir if ! hash sciibin 2> /dev/null; then - ### ArchiveTools: Install undoit (sciibin, etc.) - echo "A2CLOUD: Installing sciibin, unblu, unbit, unexec, usq..." + ### ArchiveTools: Install undoit (sciibin, etc.) + 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 $tempDir - rm -rf undoit + 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 $tempDir + rm -rf undoit else - echo "A2CLOUD: sciibin, unblu, unbit, unexec, usq are already installed." + echo "A2CLOUD: sciibin, unblu, unbit, unexec, usq are already installed." fi cd $tempDir if [[ ! -f $imagesDir/ROM1 ]]; then - echo "Getting GS ROM 01..." - wget -qO ROM1.zip http://web.archive.org/web/20130216031247/http://www.whatisthe2gs.apple2.org.za/files/rom1.zip - unzip ROM1.zip &> /dev/null - mv APPLE2GS.ROM $imagesDir/ROM1 - chmod ugo-w $imagesDir/ROM1 + echo "Getting GS ROM 01..." + wget -qO ROM1.zip http://web.archive.org/web/20130216031247/http://www.whatisthe2gs.apple2.org.za/files/rom1.zip + unzip ROM1.zip &> /dev/null + mv APPLE2GS.ROM $imagesDir/ROM1 + chmod ugo-w $imagesDir/ROM1 fi if [[ ! -f $imagesDir/ROM3 ]]; then - echo "Getting GS ROM 3..." - wget -qO ROM3.zip http://web.archive.org/web/20130216031247/http://www.whatisthe2gs.apple2.org.za/files/rom3.zip - unzip ROM3.zip &> /dev/null - mv APPLE2GS.ROM2 $imagesDir/ROM3 - chmod ugo-w $imagesDir/ROM3 + echo "Getting GS ROM 3..." + wget -qO ROM3.zip http://web.archive.org/web/20130216031247/http://www.whatisthe2gs.apple2.org.za/files/rom3.zip + unzip ROM3.zip &> /dev/null + mv APPLE2GS.ROM2 $imagesDir/ROM3 + chmod ugo-w $imagesDir/ROM3 fi if [[ ! -f /usr/local/lib/$romFileName || $arg ]]; then - echo "Setting $emulatorName to use $rom..." - echo " (to change, use '$emulatorSetup rom1' or '$emulatorSetup rom3')" - sudo rm /usr/local/lib/$romFileName &> /dev/null - sudo ln -s $imagesDir/$rom /usr/local/lib/$romFileName &> /dev/null - sudo ln -s $romFileName /usr/local/lib/ROM &> /dev/null + echo "Setting $emulatorName to use $rom..." + echo " (to change, use '$emulatorSetup rom1' or '$emulatorSetup rom3')" + sudo rm /usr/local/lib/$romFileName &> /dev/null + sudo ln -s $imagesDir/$rom /usr/local/lib/$romFileName &> /dev/null + sudo ln -s $romFileName /usr/local/lib/ROM &> /dev/null fi if [[ $slot6 ]]; then - echo "Putting blank disks in slot 6..." - sudo sed -i 's@^s6d1.*$@s6d1 = $imagesDir/slot6drive1.po@' /usr/local/lib/$configFileName - sudo sed -i 's@^s6d2.*$@s6d2 = $imagesDir/slot6drive2.po@' /usr/local/lib/$configFileName - if [[ ! -f $imagesDir/slot6drive1.po || ! -f $imagesDir/slot6drive2.po ]]; then - wget -qO- ${binaryURL}slot6.tgz | sudo tar Pzx 2> /dev/null - fi + echo "Putting blank disks in slot 6..." + sudo sed -i 's@^s6d1.*$@s6d1 = $imagesDir/slot6drive1.po@' /usr/local/lib/$configFileName + sudo sed -i 's@^s6d2.*$@s6d2 = $imagesDir/slot6drive2.po@' /usr/local/lib/$configFileName + if [[ ! -f $imagesDir/slot6drive1.po || ! -f $imagesDir/slot6drive2.po ]]; then + wget -qO- ${binaryURL}slot6.tgz | sudo tar Pzx 2> /dev/null + fi fi # set AppleTalk to turbo (works more reliably than Normal) echo "Setting AppleTalk to turbo..." if ! grep -q 'g_appletalk_turbo' /usr/local/lib/$configFileName; then - if grep -q 'bram1\[00\]' /usr/local/lib/$configFileName; then - sudo sed -i 's/^\(bram1\[00\]\)/g_appletalk_turbo = 1\n\n\1/' /usr/local/lib/$configFileName - else - echo -e '\ng_appletalk_turbo = 1' | sudo tee -a /usr/local/lib/$configFileName > /dev/null - fi + if grep -q 'bram1\[00\]' /usr/local/lib/$configFileName; then + sudo sed -i 's/^\(bram1\[00\]\)/g_appletalk_turbo = 1\n\n\1/' /usr/local/lib/$configFileName + else + echo -e '\ng_appletalk_turbo = 1' | sudo tee -a /usr/local/lib/$configFileName > /dev/null + fi fi sudo sed -i 's/g_appletalk_turbo = 0/g_appletalk_turbo = 1/' /usr/local/lib/$configFileName # enable Uthernet echo "Enabling Uthernet card emulation..." if ! grep -q 'g_ethernet[^_]' /usr/local/lib/$configFileName; then - if grep -q 'bram1\[00\]' /usr/local/lib/$configFileName; then - sudo sed -i 's/^\(bram1\[00\]\)/g_ethernet = 1\n\n\1/' /usr/local/lib/$configFileName - else - echo -e '\ng_ethernet = 1' | sudo tee -a /usr/local/lib/$configFileName > /dev/null - fi + if grep -q 'bram1\[00\]' /usr/local/lib/$configFileName; then + sudo sed -i 's/^\(bram1\[00\]\)/g_ethernet = 1\n\n\1/' /usr/local/lib/$configFileName + else + echo -e '\ng_ethernet = 1' | sudo tee -a /usr/local/lib/$configFileName > /dev/null + fi fi sudo sed -i 's/g_ethernet = 0/g_ethernet = 1/' /usr/local/lib/$configFileName # GISK if [[ $gisk ]]; then - echo "Getting GSport Internet Starter Kit..." - wget -O $tempDir/GSport_Internet_Starter_Kit.zip http://sourceforge.net/projects/gsport/files/Emulator%20Software%20Images/GSport_Internet_Starter_Kit.zip - unzip -d $tempDir $tempDir/GSport_Internet_Starter_Kit.zip "GSport Internet Starter Kit/GSport Internet Starter Kit.2mg" - sudo mv "$tempDir/GSport Internet Starter Kit/GSport Internet Starter Kit.2mg" $imagesDir - rm -r $tempDir/GSport* - if [[ $(grep ^s7d1 /usr/local/lib/$configFileName) ]]; then - sudo sed -i "s:^s7d1.*$:s7d1 = $imagesDir/GSport Internet Starter Kit.2mg:" /usr/local/lib/$configFileName - else - echo "s7d1 = $imagesDir/GSport Internet Starter Kit.2mg" | tee -a /usr/local/lib/$configFileName > /dev/null - fi - noDisks=1 + echo "Getting GSport Internet Starter Kit..." + wget -O $tempDir/GSport_Internet_Starter_Kit.zip http://sourceforge.net/projects/gsport/files/Emulator%20Software%20Images/GSport_Internet_Starter_Kit.zip + unzip -d $tempDir $tempDir/GSport_Internet_Starter_Kit.zip "GSport Internet Starter Kit/GSport Internet Starter Kit.2mg" + sudo mv "$tempDir/GSport Internet Starter Kit/GSport Internet Starter Kit.2mg" $imagesDir + rm -r $tempDir/GSport* + if [[ $(grep ^s7d1 /usr/local/lib/$configFileName) ]]; then + sudo sed -i "s:^s7d1.*$:s7d1 = $imagesDir/GSport Internet Starter Kit.2mg:" /usr/local/lib/$configFileName + else + echo "s7d1 = $imagesDir/GSport Internet Starter Kit.2mg" | tee -a /usr/local/lib/$configFileName > /dev/null + fi + noDisks=1 fi if [[ $noDisks ]]; then - echo - echo - echo "Setup complete. You can now start $emulatorName." - echo - if [[ ! $autoAnswerYes ]]; then - echo -n "Press return to continue..." - read - fi - exit 0 + echo + echo + echo "Setup complete. You can now start $emulatorName." + echo + if [[ ! $autoAnswerYes ]]; then + echo -n "Press return to continue..." + read + fi + exit 0 fi # non-GISK; get installer disks @@ -452,221 +452,221 @@ if [[ ! -f $imagesDir/INSTALL.HDV ]] \ || [[ ! -f $imagesDir/"$gsosHD" ]] \ || [[ ! $kegs && ! -f $imagesDir/spectrum.hdv ]]; then -# if [[ ! $autoAnswerYes ]]; then -# echo -# echo -n "Do you want to download the GS/OS installer disks" -# if [[ ! -f $imagesDir/"$gsosHD" ]]; then -# echo -n -e "\nand create a hard disk image file" -# fi -# if [[ ! $kegs && -f /usr/local/bin/acmd && ! -f $imagesDir/spectrum.hdv ]]; then -# echo -n -e "\nand download Spectrum communications software" -# fi -# echo -n "? " -# read -# fi - REPLY="y" - if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then +# if [[ ! $autoAnswerYes ]]; then +# echo +# echo -n "Do you want to download the GS/OS installer disks" +# if [[ ! -f $imagesDir/"$gsosHD" ]]; then +# echo -n -e "\nand create a hard disk image file" +# fi +# if [[ ! $kegs && -f /usr/local/bin/acmd && ! -f $imagesDir/spectrum.hdv ]]; then +# echo -n -e "\nand download Spectrum communications software" +# fi +# echo -n "? " +# read +# fi + REPLY="y" + if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then - echo - activeDisk=0 - for diskname in Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB; do - (( activeDisk++ )) - outfile="$imagesDir/$(tr [:lower:] [:upper:] <<< $diskname).HDV" - if [[ ! -f "$outfile" ]]; then - echo "Getting GS/OS disk ${activeDisk} of 6: $diskname" - wget -qO "Disk_${activeDisk}_of_7-$diskname.sea.bin" "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%2FDisk_${activeDisk}_of_7-$diskname.sea.bin" - unar -k skip "Disk_${activeDisk}_of_7-$diskname.sea.bin" &> /dev/null - truncate -s 819284 "Disk ${activeDisk} of 7-${diskname}.sea" - dd if="Disk ${activeDisk} of 7-${diskname}.sea" of=${outfile} bs=84 skip=1 &> /dev/null - chmod ugo-w "$outfile" - if [[ $activeDisk -eq 1 ]]; then - if [[ $(grep ^s5d1 /usr/local/lib/$configFileName) ]]; then - sudo sed -i "s:^s5d1.*$:s5d1 = $imagesDir/INSTALL.HDV:" /usr/local/lib/$configFileName - else - echo "s5d1 = $imagesDir/INSTALL.HDV" | tee -a /usr/local/lib/$configFileName > /dev/null - fi - else - if [[ $(grep ^s7d$activeDisk /usr/local/lib/$configFileName) ]]; then - sudo sed -i "s:^s7d$activeDisk.*$:s7d$activeDisk = $outfile:" /usr/local/lib/$configFileName - else - echo "s7d$activeDisk = $outfile" | tee -a /usr/local/lib/$configFileName > /dev/null - fi - fi - else - echo "GS/OS disk ${activeDisk} of 6: $diskname has already been downloaded." - fi - done - rm *.sea* &> /dev/null + echo + activeDisk=0 + for diskname in Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB; do + (( activeDisk++ )) + outfile="$imagesDir/$(tr [:lower:] [:upper:] <<< $diskname).HDV" + if [[ ! -f "$outfile" ]]; then + echo "Getting GS/OS disk ${activeDisk} of 6: $diskname" + wget -qO "Disk_${activeDisk}_of_7-$diskname.sea.bin" "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%2FDisk_${activeDisk}_of_7-$diskname.sea.bin" + unar -k skip "Disk_${activeDisk}_of_7-$diskname.sea.bin" &> /dev/null + truncate -s 819284 "Disk ${activeDisk} of 7-${diskname}.sea" + dd if="Disk ${activeDisk} of 7-${diskname}.sea" of=${outfile} bs=84 skip=1 &> /dev/null + chmod ugo-w "$outfile" + if [[ $activeDisk -eq 1 ]]; then + if [[ $(grep ^s5d1 /usr/local/lib/$configFileName) ]]; then + sudo sed -i "s:^s5d1.*$:s5d1 = $imagesDir/INSTALL.HDV:" /usr/local/lib/$configFileName + else + echo "s5d1 = $imagesDir/INSTALL.HDV" | tee -a /usr/local/lib/$configFileName > /dev/null + fi + else + if [[ $(grep ^s7d$activeDisk /usr/local/lib/$configFileName) ]]; then + sudo sed -i "s:^s7d$activeDisk.*$:s7d$activeDisk = $outfile:" /usr/local/lib/$configFileName + else + echo "s7d$activeDisk = $outfile" | tee -a /usr/local/lib/$configFileName > /dev/null + fi + fi + else + echo "GS/OS disk ${activeDisk} of 6: $diskname has already been downloaded." + fi + done + rm *.sea* &> /dev/null - if [[ ! -f $imagesDir/"$gsosHD" ]]; then - echo "Creating 32 MB blank image at $imagesDir/$gsosHD..." - if [[ -f /usr/local/bin/acmd ]]; then - # if acmd exists, make a ProDOS disk with GS-ShrinkIt and Teach + if [[ ! -f $imagesDir/"$gsosHD" ]]; then + echo "Creating 32 MB blank image at $imagesDir/$gsosHD..." + if [[ -f /usr/local/bin/acmd ]]; then + # if acmd exists, make a ProDOS disk with GS-ShrinkIt and Teach - if [[ ! -f /usr/local/adtpro/lib/AppleCommander/AppleCommander-1.3.5.13id-ac.jar ]]; then - echo "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 - fi + if [[ ! -f /usr/local/adtpro/lib/AppleCommander/AppleCommander-1.3.5.13id-ac.jar ]]; then + echo "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 + fi - echo "Copying ProDOS..." - acmd -g "$imagesDir/INSTALL.HDV" PRODOS "PRODOS#ff0000" - #writecharsHex "PRODOS#ff0000" 0 "4C.00.C5.00" - wget -qO- ${binaryURL}${emulatorName}SPLASH.SYS | dd of="PRODOS#ff0000" conv=notrunc &> /dev/null - echo "Copying Teach..." - cppo -uc -e $imagesDir/SYSTEMTOOLS2.HDV /SYSTEMTOOLS2/TEACH . &> /dev/null - echo "Downloading GS-ShrinkIt..." - wget -qO- http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea | nulib2 -x -e - GSHK &> /dev/null - echo 1 - nulib2 -a -e $gsosHD.shk "PRODOS#"* "GSHK#"* "TEACH#"* &> /dev/null - echo 2 - acmd -convert $gsosHD.shk $imagesDir/"$gsosHD" 65535 - echo 3 - rm "PRODOS#"* "GSHK#"* "TEACH#"* $gsosHD.shk &> /dev/null + echo "Copying ProDOS..." + acmd -g "$imagesDir/INSTALL.HDV" PRODOS "PRODOS#ff0000" + #writecharsHex "PRODOS#ff0000" 0 "4C.00.C5.00" + wget -qO- ${binaryURL}${emulatorName}SPLASH.SYS | dd of="PRODOS#ff0000" conv=notrunc &> /dev/null + echo "Copying Teach..." + cppo -uc -e $imagesDir/SYSTEMTOOLS2.HDV /SYSTEMTOOLS2/TEACH . &> /dev/null + echo "Downloading GS-ShrinkIt..." + wget -qO- http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea | nulib2 -x -e - GSHK &> /dev/null + echo 1 + nulib2 -a -e $gsosHD.shk "PRODOS#"* "GSHK#"* "TEACH#"* &> /dev/null + echo 2 + acmd -convert $gsosHD.shk $imagesDir/"$gsosHD" 65535 + echo 3 + rm "PRODOS#"* "GSHK#"* "TEACH#"* $gsosHD.shk &> /dev/null - acmd -n $imagesDir/"$gsosHD" $gsosHDvolName - dd bs=512 count=1 conv=notrunc if="$imagesDir/INSTALL.HDV" of="$imagesDir/$gsosHD" 2> /dev/null - sudo chmod ugo+rw $imagesDir/"$gsosHD" - #acmd -p "$imagesDir/$gsosHD" PRODOS SYS < $tempDir/PRODOS - #rm $tempDir/PRODOS - fi - echo 4 - if [[ $(grep ^s7d1 /usr/local/lib/$configFileName) ]]; then - sudo sed -i "s:^s7d1.*$:s7d1 = $imagesDir/$gsosHD:" /usr/local/lib/$configFileName - else - echo "s7d1 = $imagesDir/$gsosHD" | tee -a /usr/local/lib/$configFileName > /dev/null - fi - fi + acmd -n $imagesDir/"$gsosHD" $gsosHDvolName + dd bs=512 count=1 conv=notrunc if="$imagesDir/INSTALL.HDV" of="$imagesDir/$gsosHD" 2> /dev/null + sudo chmod ugo+rw $imagesDir/"$gsosHD" + #acmd -p "$imagesDir/$gsosHD" PRODOS SYS < $tempDir/PRODOS + #rm $tempDir/PRODOS + fi + echo 4 + if [[ $(grep ^s7d1 /usr/local/lib/$configFileName) ]]; then + sudo sed -i "s:^s7d1.*$:s7d1 = $imagesDir/$gsosHD:" /usr/local/lib/$configFileName + else + echo "s7d1 = $imagesDir/$gsosHD" | tee -a /usr/local/lib/$configFileName > /dev/null + fi + fi - if [[ $(grep ^g_limit_speed /usr/local/lib/$configFileName) ]]; then - sudo sed -i "s:^g_limit_speed.*$:g_limit_speed = 0:" /usr/local/lib/$configFileName - else - echo "g_limit_speed = 0" | tee -a /usr/local/lib/$configFileName > /dev/null - fi + if [[ $(grep ^g_limit_speed /usr/local/lib/$configFileName) ]]; then + sudo sed -i "s:^g_limit_speed.*$:g_limit_speed = 0:" /usr/local/lib/$configFileName + else + echo "g_limit_speed = 0" | tee -a /usr/local/lib/$configFileName > /dev/null + fi - if [[ -f /usr/local/bin/acmd && ! $(acmd -ls $imagesDir/$gsosHD | grep 'GSHK') ]]; then - echo - echo "Downloading GS-ShrinkIt..." - wget -qO- http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea | acmd -p $imagesDir/$gsosHD GS.SHRINKIT.SEA S16 - fi + if [[ -f /usr/local/bin/acmd && ! $(acmd -ls $imagesDir/$gsosHD | grep 'GSHK') ]]; then + echo + echo "Downloading GS-ShrinkIt..." + wget -qO- http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea | acmd -p $imagesDir/$gsosHD GS.SHRINKIT.SEA S16 + fi - # Spectrum starts here + # Spectrum starts here - if [[ ! $kegs ]]; then + if [[ ! $kegs ]]; then - mkdir -p $tempDir/spectrum - cd $tempDir/spectrum + mkdir -p $tempDir/spectrum + cd $tempDir/spectrum - imageName="$tempDir/spectrum/spectrum.dmg" - hfsName="$tempDir/spectrum/spectrumH.dmg" - ullName="$tempDir/spectrum/uthernet.bxy" + imageName="$tempDir/spectrum/spectrum.dmg" + hfsName="$tempDir/spectrum/spectrumH.dmg" + ullName="$tempDir/spectrum/uthernet.bxy" - if [[ ! -f /usr/bin/hcopy || ! -f /usr/bin/macsave ]]; then - echo "Installing HFS utilities..." - sudo apt-get -y install hfsutils macutils &> /dev/null - else - echo "HFS utilities are already installed." - fi + if [[ ! -f /usr/bin/hcopy || ! -f /usr/bin/macsave ]]; then + echo "Installing HFS utilities..." + sudo apt-get -y install hfsutils macutils &> /dev/null + else + echo "HFS utilities are already installed." + fi - if [[ ! -f /usr/local/adtpro/lib/AppleCommander/AppleCommander-1.3.5.13id-ac.jar ]]; then - echo "Installing AppleCommander..." - 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 - fi + if [[ ! -f /usr/local/adtpro/lib/AppleCommander/AppleCommander-1.3.5.13id-ac.jar ]]; then + echo "Installing AppleCommander..." + 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 + fi - if [[ ! -f "$imageName" ]]; then - echo "Downloading Spectrum Deluxe..." - wget -qO spectrum.dmg http://www.wannop.info/speccie/software/spectrum_2.5.3_deluxe.dmg - else - echo "Spectrum Deluxe has already been downloaded." - fi + if [[ ! -f "$imageName" ]]; then + echo "Downloading Spectrum Deluxe..." + wget -qO spectrum.dmg http://www.wannop.info/speccie/software/spectrum_2.5.3_deluxe.dmg + else + echo "Spectrum Deluxe has already been downloaded." + fi - mkdir -p mnt - mkdir -p extract - mkdir -p shkstage - cp "$imageName" "$hfsName" - sudo mount -r -t hfs "$imageName" mnt - hmount "$hfsName" + mkdir -p mnt + mkdir -p extract + mkdir -p shkstage + cp "$imageName" "$hfsName" + sudo mount -r -t hfs "$imageName" mnt + hmount "$hfsName" - IFS='' - cd $tempDir/spectrum/mnt - find Spectrum.2.5.3 -type d | while read thisDirPath; do - mkdir -p $tempDir/spectrum/shkstage/"$thisDirPath" - hcd - IFS='/' - for thisDir in $thisDirPath; do - hcd $thisDir - done - echo " Copying: $(hpwd)" - IFS='' - cd $tempDir/spectrum/extract - hls -1 | while read thisFile; do - hcopy -m "$thisFile" - 2> /dev/null | macsave -f 2> /dev/null - if [[ -f "$thisFile".info ]]; then - if [[ $(readcharHex "$thisFile".info 65) == "70" ]]; then - fileType=$(readcharHex "$thisFile".info 66) - auxType=$(readcharHex "$thisFile".info 67)$(readcharHex "$thisFile".info 68) - else - auxType="0000" - fMac=$(readchars "$thisFile".info 65 4) - if [[ "$fMac" == "PS16" ]]; then - fileType="b3"; - elif [[ "$fMac" == "PSYS" ]]; then - fileType="ff"; - elif [[ "$fMac" == "BINA" ]]; then - fileType="00"; - elif [[ "$fMac" == "TEXT" ]]; then - fileType="04"; - elif [[ "$fMac" == "MIDI" ]]; then - fileType="D7"; - elif [[ "$fMac" == "AIFF" || "$fMac" == "AIFC" ]]; then - fileType="D8"; - elif [[ "$fMac" == "dImg" ]]; then - fileType="E0"; - else - echo "WARNING: unknown file type '$fMac' found for file $thisFile" - fi - fi - [[ -f "$thisFile".rsrc ]] && mv "$thisFile".rsrc $tempDir/spectrum/shkstage/"$thisDirPath"/"${thisFile}#${fileType}${auxType}r" - [[ -f "$thisFile".data ]] && mv "$thisFile".data $tempDir/spectrum/shkstage/"$thisDirPath"/"${thisFile}#${fileType}${auxType}" - rm "$thisFile".info 2> /dev/null - fi - done - cd $tempDir/spectrum/mnt - done + IFS='' + cd $tempDir/spectrum/mnt + find Spectrum.2.5.3 -type d | while read thisDirPath; do + mkdir -p $tempDir/spectrum/shkstage/"$thisDirPath" + hcd + IFS='/' + for thisDir in $thisDirPath; do + hcd $thisDir + done + echo " Copying: $(hpwd)" + IFS='' + cd $tempDir/spectrum/extract + hls -1 | while read thisFile; do + hcopy -m "$thisFile" - 2> /dev/null | macsave -f 2> /dev/null + if [[ -f "$thisFile".info ]]; then + if [[ $(readcharHex "$thisFile".info 65) == "70" ]]; then + fileType=$(readcharHex "$thisFile".info 66) + auxType=$(readcharHex "$thisFile".info 67)$(readcharHex "$thisFile".info 68) + else + auxType="0000" + fMac=$(readchars "$thisFile".info 65 4) + if [[ "$fMac" == "PS16" ]]; then + fileType="b3"; + elif [[ "$fMac" == "PSYS" ]]; then + fileType="ff"; + elif [[ "$fMac" == "BINA" ]]; then + fileType="00"; + elif [[ "$fMac" == "TEXT" ]]; then + fileType="04"; + elif [[ "$fMac" == "MIDI" ]]; then + fileType="D7"; + elif [[ "$fMac" == "AIFF" || "$fMac" == "AIFC" ]]; then + fileType="D8"; + elif [[ "$fMac" == "dImg" ]]; then + fileType="E0"; + else + echo "WARNING: unknown file type '$fMac' found for file $thisFile" + fi + fi + [[ -f "$thisFile".rsrc ]] && mv "$thisFile".rsrc $tempDir/spectrum/shkstage/"$thisDirPath"/"${thisFile}#${fileType}${auxType}r" + [[ -f "$thisFile".data ]] && mv "$thisFile".data $tempDir/spectrum/shkstage/"$thisDirPath"/"${thisFile}#${fileType}${auxType}" + rm "$thisFile".info 2> /dev/null + fi + done + cd $tempDir/spectrum/mnt + done - cd $tempDir/spectrum/shkstage/Spectrum* - humount - sudo umount $tempDir/spectrum/mnt + cd $tempDir/spectrum/shkstage/Spectrum* + humount + sudo umount $tempDir/spectrum/mnt - mkdir -p Marinetti/Uthernet - cp SAFE2.Archive/Link.Layers/"Uthernet#bc4083" Marinetti/Uthernet - echo -n "After installing Marinetti, put Uthernet in the TCPIP folder of your System folder, and restart GS/OS. Then open Control Panels, choose TCP/IP, and choose Setup Connection. Choose Uthernet for the link layer. Under Primary Domain Name Server, enter 8.8.8.8, then click Configure and select Slot 3 and DHCP. Then click Save." > Marinetti/Uthernet/"Uthernet.README#040000" + mkdir -p Marinetti/Uthernet + cp SAFE2.Archive/Link.Layers/"Uthernet#bc4083" Marinetti/Uthernet + echo -n "After installing Marinetti, put Uthernet in the TCPIP folder of your System folder, and restart GS/OS. Then open Control Panels, choose TCP/IP, and choose Setup Connection. Choose Uthernet for the link layer. Under Primary Domain Name Server, enter 8.8.8.8, then click Configure and select Slot 3 and DHCP. Then click Save." > Marinetti/Uthernet/"Uthernet.README#040000" - echo "Making archive for conversion to disk image..." - rm $tempDir/spectrum/spectrum.shk 2> /dev/null - nulib2 -a -r -0 -e $tempDir/spectrum/spectrum.shk * &> /dev/null - echo "Converting archive to disk image..." - acmd -convert $tempDir/spectrum/spectrum.shk $imagesDir/spectrum.hdv 20480 - acmd -n $imagesDir/spectrum.hdv SPECTRUM.DELUXE + echo "Making archive for conversion to disk image..." + rm $tempDir/spectrum/spectrum.shk 2> /dev/null + nulib2 -a -r -0 -e $tempDir/spectrum/spectrum.shk * &> /dev/null + echo "Converting archive to disk image..." + acmd -convert $tempDir/spectrum/spectrum.shk $imagesDir/spectrum.hdv 20480 + acmd -n $imagesDir/spectrum.hdv SPECTRUM.DELUXE - if [[ $(grep ^s7d7 /usr/local/lib/$configFileName) ]]; then - sudo sed -i "s:^s7d7.*$:s7d7 = $imagesDir/spectrum.hdv:" /usr/local/lib/$configFileName - else - echo "s7d7 = $imagesDir/spectrum.hdv" | tee -a /usr/local/lib/$configFileName > /dev/null - fi + if [[ $(grep ^s7d7 /usr/local/lib/$configFileName) ]]; then + sudo sed -i "s:^s7d7.*$:s7d7 = $imagesDir/spectrum.hdv:" /usr/local/lib/$configFileName + else + echo "s7d7 = $imagesDir/spectrum.hdv" | tee -a /usr/local/lib/$configFileName > /dev/null + fi - cd $tempDir + cd $tempDir - rm -rf $tempDir/spectrum/extract $tempDir/spectrum/shkstage $tempDir/spectrum/spectrum.shk $tempDir/spectrum/mnt &> /dev/null - fi - # Spectrum ends here - fi + rm -rf $tempDir/spectrum/extract $tempDir/spectrum/shkstage $tempDir/spectrum/spectrum.shk $tempDir/spectrum/mnt &> /dev/null + fi + # Spectrum ends here + fi fi cd @@ -675,43 +675,43 @@ rm -r "$tempDir" echo echo if [[ -f "$imagesDir/$gsosHD" ]]; then - echo - echo "You can now start $emulatorName." - echo "When the installer boots, you can click Easy Update or Customize" - echo "to install GS/OS, if you downloaded the installer disks aobve." + echo + echo "You can now start $emulatorName." + echo "When the installer boots, you can click Easy Update or Customize" + echo "to install GS/OS, if you downloaded the installer disks aobve." else - # if no acmd, create unformatted disk - # requires that the disk first be formatted with Advanced Disk Utility - dd bs=512 count=65535 if=/dev/zero of=$imagesDir/"$gsosHD" 2> /dev/null - writecharsHex $imagesDir/"$gsosHD" 0 "00.4C.00.C5.00" - echo - echo "You can now start $emulatorName." - echo - echo "If you downloaded the installer disks above:" - echo "When the installer boots, quit it, change to the SystemTools1 disk," - echo "run Advanced Disk Utility, click Disk until a hard drive icon appears" - echo "that says Uninitialized, and initialize it. Then quit Advanced Disk" - echo "Utility, change to the Install Disk, and run Installer. When it loads," - echo "click Easy Update or Customize to install GS/OS." - echo + # if no acmd, create unformatted disk + # requires that the disk first be formatted with Advanced Disk Utility + dd bs=512 count=65535 if=/dev/zero of=$imagesDir/"$gsosHD" 2> /dev/null + writecharsHex $imagesDir/"$gsosHD" 0 "00.4C.00.C5.00" + echo + echo "You can now start $emulatorName." + echo + echo "If you downloaded the installer disks above:" + echo "When the installer boots, quit it, change to the SystemTools1 disk," + echo "run Advanced Disk Utility, click Disk until a hard drive icon appears" + echo "that says Uninitialized, and initialize it. Then quit Advanced Disk" + echo "Utility, change to the Install Disk, and run Installer. When it loads," + echo "click Easy Update or Customize to install GS/OS." + echo fi echo "When it's done, reboot." echo "(Use Shut Down, ctrl-F12, or ctrl-solidapple-equals.)" if [[ -f "$imagesDir/spectrum.hdv" ]]; then - echo - echo "Then on the Spectrum disk, optionally install:" - echo "Marinetti (plus update): TCP/IP driver for GS/OS" - echo "Uthernet: Ethernet driver for Marinetti" - echo "Spectrum: serial and telnet communications" - echo "SAFE: FTP client" - echo "SNAP: Usenet newsgroups (NNTP) client" - echo "SAM2: Email (POP) client" + echo + echo "Then on the Spectrum disk, optionally install:" + echo "Marinetti (plus update): TCP/IP driver for GS/OS" + echo "Uthernet: Ethernet driver for Marinetti" + echo "Spectrum: serial and telnet communications" + echo "SAFE: FTP client" + echo "SNAP: Usenet newsgroups (NNTP) client" + echo "SAM2: Email (POP) client" fi echo echo "After installing, press F4 and choose 'Disk Configuration' to" echo "eject all disks other than slot 7 drive 1." echo if [[ ! $autoAnswerYes ]]; then - echo -n "Press return to continue..." - read + echo -n "Press return to continue..." + read fi diff --git a/setup/gsport.txt b/setup/gsport.txt old mode 100644 new mode 100755 index c1bf24f..c0bdab3 --- a/setup/gsport.txt +++ b/setup/gsport.txt @@ -1,105 +1,105 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: if [[ -f /tmp/no-gsport ]]; then - echo - echo "Your system needs to be rebooted before you can use GSport." - echo -n "Do you want to reboot now? " - read - if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then - sudo shutdown -r now - fi - exit 0 + echo + echo "Your system needs to be rebooted before you can use GSport." + echo -n "Do you want to reboot now? " + read + if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then + sudo shutdown -r now + fi + exit 0 fi if [[ ( $(grep USB <<< $myTTY) || $(grep AMA <<< $myTTY) || $SSH_CLIENT || $REMOTEHOST ) && ! $DISPLAY ]]; then - echo "Please run GSport on the console, or in an X Window." + echo "Please run GSport on the console, or in an X Window." else - if [[ -f /usr/local/lib/ROM ]]; then - if [[ ! $(grep snd-pcm-oss /etc/modules) ]]; then - echo "Configuring GSport sound..." - echo "snd-pcm-oss" | sudo tee -a /etc/modules > /dev/null - [[ ! $(lsmod | grep snd_pcm_oss) ]] && sudo modprobe snd-pcm-oss - fi + if [[ -f /usr/local/lib/ROM ]]; then + if [[ ! $(grep snd-pcm-oss /etc/modules) ]]; then + echo "Configuring GSport sound..." + echo "snd-pcm-oss" | sudo tee -a /etc/modules > /dev/null + [[ ! $(lsmod | grep snd_pcm_oss) ]] && sudo modprobe snd-pcm-oss + fi - if [[ ! $(dpkg -l xfonts-base 2> /dev/null | grep '^ii') ]]; then - echo "Configuring GSport fonts..." - sudo apt-get -y update - touch /tmp/updated - sudo apt-get -y install xfonts-base &> /dev/null - sudo apt-get -y clean - fi + if [[ ! $(dpkg -l xfonts-base 2> /dev/null | grep '^ii') ]]; then + echo "Configuring GSport fonts..." + sudo apt-get -y update + touch /tmp/updated + sudo apt-get -y install xfonts-base &> /dev/null + sudo apt-get -y clean + fi - if [[ ! $(dpkg -l libpcap0.8-dev 2> /dev/null | grep '^ii') ]]; then - echo "Configuring GSport networking..." - [[ ! -f /tmp/updated ]] && sudo apt-get -y update - sudo apt-get -y install libpcap0.8-dev &> /dev/null - sudo apt-get -y clean - fi + if [[ ! $(dpkg -l libpcap0.8-dev 2> /dev/null | grep '^ii') ]]; then + echo "Configuring GSport networking..." + [[ ! -f /tmp/updated ]] && sudo apt-get -y update + sudo apt-get -y install libpcap0.8-dev &> /dev/null + sudo apt-get -y clean + fi - rm /tmp/updated &> /dev/null - else - gsport-setup - [[ $? -ne 0 ]] && exit 1 - fi + rm /tmp/updated &> /dev/null + else + gsport-setup + [[ $? -ne 0 ]] && exit 1 + fi - displayOK= - if [[ $DISPLAY ]]; then # X Window - displayOK=1 - else # console/framebuffer - if [[ ! -f /usr/local/etc/gsportconsolewarningoff ]] && { dpkg -l | grep -q -i virtualbox; }; then - echo - echo "If you have difficulties moving the mouse in GS/OS, choose" - echo "'Disable Mouse Integration' from the Machine menu. To free the mouse" - echo "from the virtual machine, press the Host key (shown in the lower right" - echo "corner of the virtual machine window)." - echo - echo "Press alt-F4 to exit GSport." - echo - echo "Press return to continue," - echo -n " or type 'OK' if you want to stop seeing this message: " - read - if [[ $REPLY == "ok" || $REPLY == "ok" || $REPLY == "Ok" ]]; then - sudo touch /usr/local/etc/gsportconsolewarningoff - fi - fi + displayOK= + if [[ $DISPLAY ]]; then # X Window + displayOK=1 + else # console/framebuffer + if [[ ! -f /usr/local/etc/gsportconsolewarningoff ]] && { dpkg -l | grep -q -i virtualbox; }; then + echo + echo "If you have difficulties moving the mouse in GS/OS, choose" + echo "'Disable Mouse Integration' from the Machine menu. To free the mouse" + echo "from the virtual machine, press the Host key (shown in the lower right" + echo "corner of the virtual machine window)." + echo + echo "Press alt-F4 to exit GSport." + echo + echo "Press return to continue," + echo -n " or type 'OK' if you want to stop seeing this message: " + read + if [[ $REPLY == "ok" || $REPLY == "ok" || $REPLY == "Ok" ]]; then + sudo touch /usr/local/etc/gsportconsolewarningoff + fi + fi - if [[ ! $(grep 'input' <<< $(groups) ) ]]; then - sudo groupadd input &> /dev/null - sudo usermod -a -G input $USER - echo 'SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee /etc/udev/rules.d/99-input.rules > /dev/null - touch /tmp/gsport-consolesetup - fi + if [[ ! $(grep 'input' <<< $(groups) ) ]]; then + sudo groupadd input &> /dev/null + sudo usermod -a -G input $USER + echo 'SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee /etc/udev/rules.d/99-input.rules > /dev/null + touch /tmp/gsport-consolesetup + fi - if [[ -c /dev/fb0 ]]; then - [[ ! -f /tmp/gsport-consolesetup ]] && displayOK=1 - else - if [[ -f /etc/default/grub ]]; then - if [[ ! $(grep 'GRUB_GFXPAYLOAD_LINUX' /etc/default/grub) ]]; then - echo "Preparing GSport for console use..." - sudo sed -i 's/^\(GRUB_CMDLINE_LINUX=.*\)$/\1\nGRUB_GFXPAYLOAD_LINUX=640x480/' /etc/default/grub - sudo update-grub &> /dev/null - touch /tmp/gsport-consolesetup - fi - else - echo "No framebuffer available. Please run GSport in an X window." - fi - fi - fi + if [[ -c /dev/fb0 ]]; then + [[ ! -f /tmp/gsport-consolesetup ]] && displayOK=1 + else + if [[ -f /etc/default/grub ]]; then + if [[ ! $(grep 'GRUB_GFXPAYLOAD_LINUX' /etc/default/grub) ]]; then + echo "Preparing GSport for console use..." + sudo sed -i 's/^\(GRUB_CMDLINE_LINUX=.*\)$/\1\nGRUB_GFXPAYLOAD_LINUX=640x480/' /etc/default/grub + sudo update-grub &> /dev/null + touch /tmp/gsport-consolesetup + fi + else + echo "No framebuffer available. Please run GSport in an X window." + fi + fi + fi - if [[ ! $DISPLAY && -f /tmp/gsport-consolesetup ]]; then - echo "GSport will be ready for console use after you restart your system." - echo "You can restart now by typing 'system-restart'." - elif [[ $displayOK ]]; then - if [[ $(xdpyinfo 2> /dev/null) ]]; then - exec /usr/local/bin/gsportx - else - exec /usr/local/bin/gsportfb - fi - else - echo "GSport has a problem. Please try updating A2CLOUD by" - echo "typing 'a2cloud-setup'." - fi + if [[ ! $DISPLAY && -f /tmp/gsport-consolesetup ]]; then + echo "GSport will be ready for console use after you restart your system." + echo "You can restart now by typing 'system-restart'." + elif [[ $displayOK ]]; then + if [[ $(xdpyinfo 2> /dev/null) ]]; then + exec /usr/local/bin/gsportx + else + exec /usr/local/bin/gsportfb + fi + else + echo "GSport has a problem. Please try updating A2CLOUD by" + echo "typing 'a2cloud-setup'." + fi fi diff --git a/setup/linapple.txt b/setup/linapple.txt old mode 100644 new mode 100755 index 8e7cd28..23c60ef --- a/setup/linapple.txt +++ b/setup/linapple.txt @@ -1,53 +1,53 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: if [[ ( $(grep USB <<< $myTTY) || $(grep AMA <<< $myTTY) || $SSH_CLIENT || $REMOTEHOST ) && ! $DISPLAY ]]; then - echo "Please run LinApple on the console, or in an X Window." + echo "Please run LinApple on the console, or in an X Window." else - if [[ $(dpkg -l libsdl1.2debian libcurl3 zlib1g libzip2 2> /dev/null | grep ^ii | wc -l) -ne 4 ]]; then - echo "Configuring LinApple libraries (this may take a moment)..." - sudo apt-get -y update &> /dev/null - sudo apt-get -y install libsdl1.2debian libcurl3 zlib1g libzip2 &> /dev/null - sudo apt-get -y clean - fi + if [[ $(dpkg -l libsdl1.2debian libcurl3 zlib1g libzip2 2> /dev/null | grep ^ii | wc -l) -ne 4 ]]; then + echo "Configuring LinApple libraries (this may take a moment)..." + sudo apt-get -y update &> /dev/null + sudo apt-get -y install libsdl1.2debian libcurl3 zlib1g libzip2 &> /dev/null + sudo apt-get -y clean + fi - linappleOk= + linappleOk= - if [[ $DISPLAY ]]; then # X Window - linappleOk=1 - else # console/framebuffer - if [[ ! -f /tmp/linapple-consolesetup && ! $(grep 'input' <<< $(groups) ) ]]; then - sudo groupadd input &> /dev/null - sudo usermod -a -G input $USER - echo 'SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee /etc/udev/rules.d/99-input.rules > /dev/null - touch /tmp/linapple-consolesetup - fi + if [[ $DISPLAY ]]; then # X Window + linappleOk=1 + else # console/framebuffer + if [[ ! -f /tmp/linapple-consolesetup && ! $(grep 'input' <<< $(groups) ) ]]; then + sudo groupadd input &> /dev/null + sudo usermod -a -G input $USER + echo 'SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee /etc/udev/rules.d/99-input.rules > /dev/null + touch /tmp/linapple-consolesetup + fi - if [[ -c /dev/fb0 ]]; then - [[ ! -f /tmp/linapple-consolesetup ]] && linappleOk=1 - else - if [[ -f /etc/default/grub ]]; then - if [[ ! $(grep 'GRUB_GFXPAYLOAD_LINUX' /etc/default/grub) ]]; then - echo "Preparing LinApple for console use..." - sudo sed -i 's/^\(GRUB_CMDLINE_LINUX=.*\)$/\1\nGRUB_GFXPAYLOAD_LINUX=640x480/' /etc/default/grub - sudo update-grub &> /dev/null - touch /tmp/linapple-consolesetup - fi - else - echo "No framebuffer available. Please run LinApple in an X window." - fi - fi - fi + if [[ -c /dev/fb0 ]]; then + [[ ! -f /tmp/linapple-consolesetup ]] && linappleOk=1 + else + if [[ -f /etc/default/grub ]]; then + if [[ ! $(grep 'GRUB_GFXPAYLOAD_LINUX' /etc/default/grub) ]]; then + echo "Preparing LinApple for console use..." + sudo sed -i 's/^\(GRUB_CMDLINE_LINUX=.*\)$/\1\nGRUB_GFXPAYLOAD_LINUX=640x480/' /etc/default/grub + sudo update-grub &> /dev/null + touch /tmp/linapple-consolesetup + fi + else + echo "No framebuffer available. Please run LinApple in an X window." + fi + fi + fi - if [[ ! $DISPLAY && -f /tmp/linapple-consolesetup ]]; then - echo "LinApple will be ready for console use after you restart your system." - echo "You can restart now by typing 'system-restart'." - elif [[ $linappleOk ]]; then - cd /usr/local/linapple - ./linapple - else - echo "LinApple has a problem. Please try updating A2CLOUD by" - echo "typing 'a2cloud-setup'." - fi + if [[ ! $DISPLAY && -f /tmp/linapple-consolesetup ]]; then + echo "LinApple will be ready for console use after you restart your system." + echo "You can restart now by typing 'system-restart'." + elif [[ $linappleOk ]]; then + cd /usr/local/linapple + ./linapple + else + echo "LinApple has a problem. Please try updating A2CLOUD by" + echo "typing 'a2cloud-setup'." + fi fi diff --git a/setup/mkpo.txt b/setup/mkpo.txt old mode 100644 new mode 100755 index d25971b..6d54930 --- a/setup/mkpo.txt +++ b/setup/mkpo.txt @@ -1,50 +1,50 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # ID-bashByter routines function binToDec () { - dec=0; - bits=$1; - while (( ${#bits} < 8 )); do - bits="0$bits"; - done; - for n in {0..7}; - do - (( dec+=( ${bits:$n:1} * ( 2**(7-$n) ) ) )); - done; - echo -n $dec + dec=0; + bits=$1; + while (( ${#bits} < 8 )); do + bits="0$bits"; + done; + for n in {0..7}; + do + (( dec+=( ${bits:$n:1} * ( 2**(7-$n) ) ) )); + done; + echo -n $dec }; function writecharDec () { - [[ -n $1 ]] || return 11; - [[ -n $2 ]] || return 12; - [[ -n $3 ]] || return 13; - [[ -n $4 ]] && return 8; - [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && ( $2 -ge 0 ) ]] || return 22; - [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) && ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23; - echo -n -e "\x$(printf %02X "$3")" | dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null + [[ -n $1 ]] || return 11; + [[ -n $2 ]] || return 12; + [[ -n $3 ]] || return 13; + [[ -n $4 ]] && return 8; + [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && ( $2 -ge 0 ) ]] || return 22; + [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) && ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23; + echo -n -e "\x$(printf %02X "$3")" | dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null }; function writecharsHex () { - [[ -n $1 ]] || return 11; - [[ -n $2 ]] || return 12; - [[ -n $3 ]] || return 13; - [[ -n $4 ]] && return 8; - [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && ( $2 -ge 0 ) ]] || return 22; - p=0; - offset=$2; - len=${#3}; - while (( p < len )); do - outByte=${3:$p:2}; - [[ $(printf %02X "0x$outByte" 2> /dev/null) == $(echo -n "$outByte" | tr [a-z] [A-Z]) ]] || return 23; - echo -n -e "\x$outByte" | dd of="$1" bs=1 seek=$offset conv=notrunc 2> /dev/null; - (( p += 3 )); - (( offset++ )); - done + [[ -n $1 ]] || return 11; + [[ -n $2 ]] || return 12; + [[ -n $3 ]] || return 13; + [[ -n $4 ]] && return 8; + [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && ( $2 -ge 0 ) ]] || return 22; + p=0; + offset=$2; + len=${#3}; + while (( p < len )); do + outByte=${3:$p:2}; + [[ $(printf %02X "0x$outByte" 2> /dev/null) == $(echo -n "$outByte" | tr [a-z] [A-Z]) ]] || return 23; + echo -n -e "\x$outByte" | dd of="$1" bs=1 seek=$offset conv=notrunc 2> /dev/null; + (( p += 3 )); + (( offset++ )); + done }; # mkpo @@ -55,9 +55,9 @@ function writecharsHex () [[ ! -d "$adtPath" ]] && { echo "AppleCommander not found."; exit 1; } if [[ $1 == "-b" ]]; then - totalBlocks="$2" - shift - shift + totalBlocks="$2" + shift + shift fi [[ -f $1 ]] && { echo "Image '$1' already exists."; exit 1; } @@ -66,7 +66,7 @@ fi # test ProDOS name legitimacy prodosVolName=$(tr [:lower:] [:upper:] <<< $prodosVolName ) if [[ ${#prodosVolName} -gt 15 || ! $(grep ^[A-Z][0-9A-Z\.]*$ <<< $prodosVolName) ]]; then - echo "Invalid ProDOS name: $prodosVolName"; exit 1; + echo "Invalid ProDOS name: $prodosVolName"; exit 1; fi # see if nulib2 is available; if so, acmd -convert will create image @@ -74,88 +74,88 @@ fi nulib2 &> /dev/null [[ $? == 2 ]] && nulib2=1 || nulib2= if [[ $nulib2 ]]; then - if [[ $totalBlocks ]]; then - imageBlocks="$totalBlocks" - else - if [[ $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then - imageBlocks=280 - else - imageBlocks=1600 - fi - fi - rm /tmp/blank.shk &> /dev/null - orig_dir="$PWD" - cd /tmp - rm blank.shk EMPTY &> /dev/null - touch EMPTY - nulib2 -a blank.shk EMPTY &> /dev/null - cd "$orig_dir" - acmd -convert /tmp/blank.shk "$1" $imageBlocks - acmd -d "$1" EMPTY - rm /tmp/blank.shk /tmp/EMPTY - acmd -n "$1" "$prodosVolName" + if [[ $totalBlocks ]]; then + imageBlocks="$totalBlocks" + else + if [[ $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then + imageBlocks=280 + else + imageBlocks=1600 + fi + fi + rm /tmp/blank.shk &> /dev/null + orig_dir="$PWD" + cd /tmp + rm blank.shk EMPTY &> /dev/null + touch EMPTY + nulib2 -a blank.shk EMPTY &> /dev/null + cd "$orig_dir" + acmd -convert /tmp/blank.shk "$1" $imageBlocks + acmd -d "$1" EMPTY + rm /tmp/blank.shk /tmp/EMPTY + acmd -n "$1" "$prodosVolName" else - # make the disk image without converting archive - if [[ $totalBlocks || $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then - acmd -pro140 "$1" $prodosVolName; - else - acmd -pro800 "$1" $prodosVolName; - fi + # make the disk image without converting archive + if [[ $totalBlocks || $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then + acmd -pro140 "$1" $prodosVolName; + else + acmd -pro800 "$1" $prodosVolName; + fi fi # make the disk bootable if [ -f "$adtPath"/disks/ADTPRO*PO ]; then - dd bs=512 count=1 of="$1" conv=notrunc < "$adtPath"/disks/ADTPRO*PO 2> /dev/null + dd bs=512 count=1 of="$1" conv=notrunc < "$adtPath"/disks/ADTPRO*PO 2> /dev/null fi # change .DSK to DOS-ordered if [[ ! $totalBlocks && $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then - mv "$1" "$1".tmp - for t in {0..34}; do - for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do - dd bs=256 count=1 if="$1".tmp of="$1" skip=$(( $t*16 + $s )) seek=$(( $t*16 + ( $s==0||$s==15 ? $s : 15-$s ) )) 2> /dev/null; - done; - done - rm "$1".tmp + mv "$1" "$1".tmp + for t in {0..34}; do + for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do + dd bs=256 count=1 if="$1".tmp of="$1" skip=$(( $t*16 + $s )) seek=$(( $t*16 + ( $s==0||$s==15 ? $s : 15-$s ) )) 2> /dev/null; + done; + done + rm "$1".tmp fi # if nulib2 isn't available, patch the disk image to use specified block size if [[ ! $nulib2 && $totalBlocks ]]; then - # change total block count - bcHex=$(printf "%04X" $totalBlocks); - writecharsHex "$1" 1065 "${bcHex:2:2}.${bcHex:0:2}"; + # change total block count + bcHex=$(printf "%04X" $totalBlocks); + writecharsHex "$1" 1065 "${bcHex:2:2}.${bcHex:0:2}"; - # fix FSB - dd if=/dev/zero of="$1" bs=512 seek=280 count=$(( $totalBlocks - 280 )) 2> /dev/null; - dd if="$1" of="$1" bs=1 skip=3073 seek=3107 count=$(( ($totalBlocks / 8) - 35 )) conv=notrunc 2> /dev/null; - bits=$(( $totalBlocks % 8 )); - if (( bits > 0 )); then - usedString="00000000"; - freeString=; - for ((b=0; b<$bits; b++)) - do - freeString=$freeString"1"; - done; - binString=$freeString${usedString:$bits}; - writecharDec "$1" $(( ( ($totalBlocks / 8) - 35) + 3107 )) $(binToDec $binString); - fi; + # fix FSB + dd if=/dev/zero of="$1" bs=512 seek=280 count=$(( $totalBlocks - 280 )) 2> /dev/null; + dd if="$1" of="$1" bs=1 skip=3073 seek=3107 count=$(( ($totalBlocks / 8) - 35 )) conv=notrunc 2> /dev/null; + bits=$(( $totalBlocks % 8 )); + if (( bits > 0 )); then + usedString="00000000"; + freeString=; + for ((b=0; b<$bits; b++)) + do + freeString=$freeString"1"; + done; + binString=$freeString${usedString:$bits}; + writecharDec "$1" $(( ( ($totalBlocks / 8) - 35) + 3107 )) $(binToDec $binString); + fi; - # assign extra blocks to FSB if needed - fsbExtraBlocks=$(( ($totalBlocks-1)/4096 )); - if (( fsbExtraBlocks > 0 )); then - dd if=/dev/zero of="$1" bs=1 seek=3072 count=$(( (fsbExtraBlocks > 8) + 1 )) conv=notrunc 2> /dev/null; - (( fsbExtraBlocks-- )); - fi; + # assign extra blocks to FSB if needed + fsbExtraBlocks=$(( ($totalBlocks-1)/4096 )); + if (( fsbExtraBlocks > 0 )); then + dd if=/dev/zero of="$1" bs=1 seek=3072 count=$(( (fsbExtraBlocks > 8) + 1 )) conv=notrunc 2> /dev/null; + (( fsbExtraBlocks-- )); + fi; - bits=$(( fsbExtraBlocks % 8 )); - if (( bits > 0 )); then - freeString="11111111"; - usedString=; - for ((b=0; b<$bits; b++)) - do - usedString=$usedString"0"; - done; - binString=$usedString${freeString:$bits}; - writecharDec "$1" $(( (fsbExtraBlocks>7)+3073 )) $(binToDec $binString); - fi; + bits=$(( fsbExtraBlocks % 8 )); + if (( bits > 0 )); then + freeString="11111111"; + usedString=; + for ((b=0; b<$bits; b++)) + do + usedString=$usedString"0"; + done; + binString=$usedString${freeString:$bits}; + writecharDec "$1" $(( (fsbExtraBlocks>7)+3073 )) $(binToDec $binString); + fi; fi diff --git a/setup/raspbian-update.txt b/setup/raspbian-update.txt old mode 100644 new mode 100755 index c1552ba..4839b02 --- a/setup/raspbian-update.txt +++ b/setup/raspbian-update.txt @@ -1,5 +1,5 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # raspbian-update # updates Raspbian to latest version, including NOOBS if installed @@ -7,8 +7,8 @@ [[ -f /usr/bin/raspi-config ]] && isRpi=1 || isRpi= if [[ ! $isRpi ]]; then - echo "This ain't a Raspberry Pi." - [[ $0 == "-bash" ]] && return 1 || exit 1 + echo "This ain't a Raspberry Pi." + [[ $0 == "-bash" ]] && return 1 || exit 1 fi skipRepoUpdate= @@ -16,172 +16,172 @@ autoYes= updateA2Cloud= updateA2Server= while [[ $1 ]]; do - if [[ $1 == "-r" ]]; then - shift - skipRepoUpdate="-r" - elif [[ $1 == "-y" ]]; then - shift - autoYes="-y" - elif [[ $1 == "-n" ]]; then - shift - noobsOnly="-n" - elif [[ $1 == "a2cloud" ]]; then - shift - updateA2Cloud=1 - elif [[ $1 == "a2server" ]]; then - shift - updateA2Server=1 - elif [[ $1 ]]; then - echo "options:" - echo "-y: auto-answer yes to all prompts and don't prompt for restart" - echo "-r: don't update package repositories" - echo "-n: update NOOBS only; don't update Raspbian" - echo "a2cloud : update A2CLOUD when complete" - echo "a2server: update A2SERVER when complete" - [[ $0 == "-bash" ]] && return 1 || exit 1 - fi + if [[ $1 == "-r" ]]; then + shift + skipRepoUpdate="-r" + elif [[ $1 == "-y" ]]; then + shift + autoYes="-y" + elif [[ $1 == "-n" ]]; then + shift + noobsOnly="-n" + elif [[ $1 == "a2cloud" ]]; then + shift + updateA2Cloud=1 + elif [[ $1 == "a2server" ]]; then + shift + updateA2Server=1 + elif [[ $1 ]]; then + echo "options:" + echo "-y: auto-answer yes to all prompts and don't prompt for restart" + echo "-r: don't update package repositories" + echo "-n: update NOOBS only; don't update Raspbian" + echo "a2cloud : update A2CLOUD when complete" + echo "a2server: update A2SERVER when complete" + [[ $0 == "-bash" ]] && return 1 || exit 1 + fi done noobs= readarray -t partitions < <(sudo fdisk -l | grep '^/dev') if [[ \ - ${partitions[0]:0:14} == "/dev/mmcblk0p1" && ${partitions[0]:57:2} == " e" && - ${partitions[1]:0:14} == "/dev/mmcblk0p2" && ${partitions[1]:57:2} == "85" && - ${partitions[2]:0:14} == "/dev/mmcblk0p3" && ${partitions[2]:57:2} == "83" && - ${partitions[3]:0:14} == "/dev/mmcblk0p5" && ${partitions[3]:57:2} == " c" && - ${partitions[4]:0:14} == "/dev/mmcblk0p6" && ${partitions[4]:57:2} == "83" ]]; then - noobs=" and the NOOBS install manager" + ${partitions[0]:0:14} == "/dev/mmcblk0p1" && ${partitions[0]:57:2} == " e" && + ${partitions[1]:0:14} == "/dev/mmcblk0p2" && ${partitions[1]:57:2} == "85" && + ${partitions[2]:0:14} == "/dev/mmcblk0p3" && ${partitions[2]:57:2} == "83" && + ${partitions[3]:0:14} == "/dev/mmcblk0p5" && ${partitions[3]:57:2} == " c" && + ${partitions[4]:0:14} == "/dev/mmcblk0p6" && ${partitions[4]:57:2} == "83" ]]; then + noobs=" and the NOOBS install manager" fi if [[ ! $autoYes ]]; then - echo - echo "You are about to update your SD card to the latest version of the" - echo "Raspbian operating system${noobs}." - echo - echo "This may take an hour or more, and will require restarting when complete." - echo "You might want a backup before continuing in case it doesn't go as planned." - echo - echo -n "Update Raspbian? " - read - if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then - [[ $0 == "-bash" ]] && return 2 || exit 2 - fi + echo + echo "You are about to update your SD card to the latest version of the" + echo "Raspbian operating system${noobs}." + echo + echo "This may take an hour or more, and will require restarting when complete." + echo "You might want a backup before continuing in case it doesn't go as planned." + echo + echo -n "Update Raspbian? " + read + if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then + [[ $0 == "-bash" ]] && return 2 || exit 2 + fi fi origDir="$PWD" cd /tmp if [[ ! $skipRepoUpdate ]]; then - echo "Updating package repositories..." - sudo apt-get -y update > /dev/null + echo "Updating package repositories..." + sudo apt-get -y update > /dev/null else - echo "Not updating package repositories..." - echo + echo "Not updating package repositories..." + echo fi if [[ ! $noobsOnly ]]; then - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null - freeSpace=$(df / | tail -1 | awk '{ print $4 }') - if (( $freeSpace < 400000 )); then - if dpkg -l | grep -q wolfram-engine; then - if [[ ! $autoYes ]]; then - echo "In order to create enough space on your SD card to upgrade," - echo "the Wolfram Language and Mathematica software packages must be removed." - echo "If you don't know what these are, this won't affect you at all." - echo - echo -n "Remove Wolfram software? " - read - if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then - [[ $0 == "-bash" ]] && return 2 || exit 2 - fi - sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null - sudo apt-get -y purge wolfram-engine - else - echo "Removing Wolfram software due to space constraints..." - sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null - sudo apt-get -y purge wolfram-engine - fi - else - echo "You don't have enough free space on your SD card to upgrade." - echo "Sorry, man. Delete some stuff or get a bigger card." - [[ $0 == "-bash" ]] && return 1 || exit 1 - fi - fi + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + freeSpace=$(df / | tail -1 | awk '{ print $4 }') + if (( $freeSpace < 400000 )); then + if dpkg -l | grep -q wolfram-engine; then + if [[ ! $autoYes ]]; then + echo "In order to create enough space on your SD card to upgrade," + echo "the Wolfram Language and Mathematica software packages must be removed." + echo "If you don't know what these are, this won't affect you at all." + echo + echo -n "Remove Wolfram software? " + read + if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then + [[ $0 == "-bash" ]] && return 2 || exit 2 + fi + sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null + sudo apt-get -y purge wolfram-engine + else + echo "Removing Wolfram software due to space constraints..." + sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null + sudo apt-get -y purge wolfram-engine + fi + else + echo "You don't have enough free space on your SD card to upgrade." + echo "Sorry, man. Delete some stuff or get a bigger card." + [[ $0 == "-bash" ]] && return 1 || exit 1 + fi + fi - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null - dpkg -l | grep -q a2pi && sudo apt-get -y --force-yes install a2pi - dpkg -l | grep -q apple2user && sudo apt-get -y --force-yes install apple2user gsport - if dpkg -l | grep -q wolfram-engine; then - sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null - if [[ $freeSpace -lt 750000 && $(apt-get -s install wolfram-engine | grep upgraded) ]]; then - sudo apt-get -y purge wolfram-engine - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null - fi - sudo apt-get -y install wolfram-engine - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null - fi - sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null - sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null - sudo apt-get -y install raspberrypi-ui-mods - { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + dpkg -l | grep -q a2pi && sudo apt-get -y --force-yes install a2pi + dpkg -l | grep -q apple2user && sudo apt-get -y --force-yes install apple2user gsport + if dpkg -l | grep -q wolfram-engine; then + sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null + if [[ $freeSpace -lt 750000 && $(apt-get -s install wolfram-engine | grep upgraded) ]]; then + sudo apt-get -y purge wolfram-engine + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + fi + sudo apt-get -y install wolfram-engine + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + fi + sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null + sudo apt-get -y install raspberrypi-ui-mods + { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null fi if [[ $noobs ]]; then - echo "Updating NOOBS..." + echo "Updating NOOBS..." - # update Partition 3 - mkdir -p /tmp/p3 - sudo mount /dev/mmcblk0p3 /tmp/p3 - sudo rm -rf /tmp/p3/os/* 2> /dev/null - if grep -q 'Raspple II' /tmp/p3/installed_os.json; then - echo "Downloading Raspple II lite..." - noobsUrl="ivanx.com/rasppleii/files/RasppleII_lite.zip" - noobsOSurl="ivanx.com/rasppleii/noobs-os" - distDir="Raspple_II" - sudo mkdir -p /tmp/p3/os/$distDir - sudo sed -i 's:/Raspbian:/Raspple_II:' /tmp/p3/installed_os.json - sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspple_II.png - wget -qO- $noobsOSurl/slidesAB.tar | sudo tar -C /tmp/p3/os/$distDir -x - else - echo "Downloading NOOBS lite..." - noobsRoot="downloads.raspberrypi.org/NOOBS_lite/images/" - noobsDir=$(wget -qO- $noobsRoot | grep '^ /dev/null - releaseDate=$(wget -qO- $noobsOSurl/os.json | grep 'release_date' | cut -f 4 -d '"') - sudo sed -i 's/"release_date".*$/"release_date" : "'$releaseDate'"/' /tmp/p3/installed_os.json - sudo sed -i 's/keyboard_layout=gb/keyboard_layout=us/' /tmp/p3/noobs.conf - sudo sed -i 's:/mnt/:/settings/:' /tmp/p3/installed_os.json - sudo sed -i 's@"icon".*,@"icon" : "/settings/os/'$distDir'/icon.png",@' /tmp/p3/installed_os.json - sudo cp /tmp/p3/icon.png /tmp/p3/os/$distDir - sudo wget -qO /tmp/p3/os/$distDir/os.json $noobsOSurl/os.json - sudo wget -qO /tmp/p3/os/$distDir/partition_setup.sh $noobsOSurl/partition_setup.sh - sudo wget -qO /tmp/p3/os/$distDir/partitions.json $noobsOSurl/partitions.json - sudo umount /tmp/p3 - rmdir /tmp/p3 + # update Partition 3 + mkdir -p /tmp/p3 + sudo mount /dev/mmcblk0p3 /tmp/p3 + sudo rm -rf /tmp/p3/os/* 2> /dev/null + if grep -q 'Raspple II' /tmp/p3/installed_os.json; then + echo "Downloading Raspple II lite..." + noobsUrl="ivanx.com/rasppleii/files/RasppleII_lite.zip" + noobsOSurl="ivanx.com/rasppleii/noobs-os" + distDir="Raspple_II" + sudo mkdir -p /tmp/p3/os/$distDir + sudo sed -i 's:/Raspbian:/Raspple_II:' /tmp/p3/installed_os.json + sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspple_II.png + wget -qO- $noobsOSurl/slidesAB.tar | sudo tar -C /tmp/p3/os/$distDir -x + else + echo "Downloading NOOBS lite..." + noobsRoot="downloads.raspberrypi.org/NOOBS_lite/images/" + noobsDir=$(wget -qO- $noobsRoot | grep '^ /dev/null + releaseDate=$(wget -qO- $noobsOSurl/os.json | grep 'release_date' | cut -f 4 -d '"') + sudo sed -i 's/"release_date".*$/"release_date" : "'$releaseDate'"/' /tmp/p3/installed_os.json + sudo sed -i 's/keyboard_layout=gb/keyboard_layout=us/' /tmp/p3/noobs.conf + sudo sed -i 's:/mnt/:/settings/:' /tmp/p3/installed_os.json + sudo sed -i 's@"icon".*,@"icon" : "/settings/os/'$distDir'/icon.png",@' /tmp/p3/installed_os.json + sudo cp /tmp/p3/icon.png /tmp/p3/os/$distDir + sudo wget -qO /tmp/p3/os/$distDir/os.json $noobsOSurl/os.json + sudo wget -qO /tmp/p3/os/$distDir/partition_setup.sh $noobsOSurl/partition_setup.sh + sudo wget -qO /tmp/p3/os/$distDir/partitions.json $noobsOSurl/partitions.json + sudo umount /tmp/p3 + rmdir /tmp/p3 - # update Partition 1 - mkdir -p /tmp/p1 - sudo mount /dev/mmcblk0p1 /tmp/p1 - wget -qO /tmp/noobs_lite.zip $noobsUrl - sudo rm -rf /tmp/p1/* - sudo unzip -d /tmp/p1 /tmp/noobs_lite.zip - sudo sed -i 's/^runinstaller //' /tmp/p1/recovery.cmdline - sudo sed -i 's/silentinstall//' /tmp/p1/recovery.cmdline - grep -q 'keyboard=us' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 keyboard=us/' /tmp/p1/recovery.cmdline - grep -q 'disablesafemode' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 disablesafemode/' /tmp/p1/recovery.cmdline - sudo umount /tmp/p1 - rmdir /tmp/p1 + # update Partition 1 + mkdir -p /tmp/p1 + sudo mount /dev/mmcblk0p1 /tmp/p1 + wget -qO /tmp/noobs_lite.zip $noobsUrl + sudo rm -rf /tmp/p1/* + sudo unzip -d /tmp/p1 /tmp/noobs_lite.zip + sudo sed -i 's/^runinstaller //' /tmp/p1/recovery.cmdline + sudo sed -i 's/silentinstall//' /tmp/p1/recovery.cmdline + grep -q 'keyboard=us' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 keyboard=us/' /tmp/p1/recovery.cmdline + grep -q 'disablesafemode' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 disablesafemode/' /tmp/p1/recovery.cmdline + sudo umount /tmp/p1 + rmdir /tmp/p1 - sudo sed -i 's/\(Raspple II release.*[^u]$\)/\1u/' /etc/issue + sudo sed -i 's/\(Raspple II release.*[^u]$\)/\1u/' /etc/issue fi echo @@ -191,44 +191,44 @@ echo cd /tmp if [[ $updateA2Cloud ]]; then - wget -qO /tmp/a2cloud-setup ivanx.com/a2cloud/setup/ - source /tmp/a2cloud-setup -y -r noSetGroups - if acmd -g /usr/share/gsport/disks/GSport\ Internet\ Starter\ Kit.2mg SYSTEM/FONTS/SIS.4.10 &> /dev/null; then - wget -qO /tmp/ua2.txt ivanx.com/rasppleii/files/a/ua2.txt - source /tmp/ua2.txt - fi - echo - echo "*** A2CLOUD update completed. ***" - echo + wget -qO /tmp/a2cloud-setup ivanx.com/a2cloud/setup/ + source /tmp/a2cloud-setup -y -r noSetGroups + if acmd -g /usr/share/gsport/disks/GSport\ Internet\ Starter\ Kit.2mg SYSTEM/FONTS/SIS.4.10 &> /dev/null; then + wget -qO /tmp/ua2.txt ivanx.com/rasppleii/files/a/ua2.txt + source /tmp/ua2.txt + fi + echo + echo "*** A2CLOUD update completed. ***" + echo fi cd /tmp if [[ $updateA2Server ]]; then - wget -q -O /tmp/a2server-setup ivanx.com/a2server/setup/ - if ps aux | grep -q [s]mbd; then - source /tmp/a2server-setup -y -r -w - else - source /tmp/a2server-setup -y -r - fi - echo - echo "*** A2SERVER update completed. ***" - echo + wget -q -O /tmp/a2server-setup ivanx.com/a2server/setup/ + if ps aux | grep -q [s]mbd; then + source /tmp/a2server-setup -y -r -w + else + source /tmp/a2server-setup -y -r + fi + echo + echo "*** A2SERVER update completed. ***" + echo fi cd "$origDir" if [[ ! $autoYes ]]; then - echo - echo - echo "Your system has been updated and needs to reboot to use its new software." - echo - echo -n "Reboot now (recommended)? " - read - if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then - sudo shutdown -r now - fi + echo + echo + echo "Your system has been updated and needs to reboot to use its new software." + echo + echo -n "Reboot now (recommended)? " + read + if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then + sudo shutdown -r now + fi else - echo "*** raspbian-update completed. ***" - sudo shutdown -r now + echo "*** raspbian-update completed. ***" + sudo shutdown -r now fi diff --git a/setup/setup.txt b/setup/setup.txt index 8e96893..4cc0f91 100755 --- a/setup/setup.txt +++ b/setup/setup.txt @@ -1,17 +1,17 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab 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://raw.githubusercontent.com/RasppleII/a2cloud/current}/" ;; + */) scriptURL="$A2CLOUD_SCRIPT_URL" ;; + *) scriptURL="${A2CLOUD_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2cloud/current}/" ;; esac case "$A2CLOUD_BINARY_URL" in - */) binaryURL="$A2CLOUD_BINARY_URL" ;; - *) binaryURL="${A2CLOUD_BINARY_URL:-http://ivanx.com/a2cloud/files}/" ;; + */) binaryURL="$A2CLOUD_BINARY_URL" ;; + *) binaryURL="${A2CLOUD_BINARY_URL:-http://ivanx.com/a2cloud/files}/" ;; esac useExternalURL=1 [[ $A2CLOUD_NO_EXTERNAL ]] && useExternalURL= @@ -21,48 +21,48 @@ isRpi= isDebian= arch= if [[ -f /usr/bin/raspi-config ]]; then - isRpi=1 - arch='rpi' - me="Pi" - fullme="Raspberry Pi" + 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" + 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 + debianMajor=$(cut -d . -f 1 <<< $debianVersion) + if [[ $debianMajor == "8" ]]; then + debianName="jessie" + elif [[ $debianMajor == "7" ]]; then + debianName="wheezy" + else + debianName="unknown" + fi fi isSystemd= isSysVInit= # If you really want something else, *you* maintain it! if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then - isSystemd=1 + isSystemd=1 elif [[ -f /etc/inittab ]]; then - isSysVInit=1 + isSysVInit=1 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 + 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}" @@ -77,56 +77,56 @@ 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 + 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 ### RaspbianUpdate #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 +# 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 @@ -141,123 +141,123 @@ 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 + 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 -# ### Q: Install all features? -# echo -# echo -n "Do you want to install all A2CLOUD features? " -# read +# ### Q: Install all features? +# echo +# echo -n "Do you want to install all A2CLOUD features? " +# read #fi #[[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installAllFeatures=1 installAllFeatures=1 # as of 1.9.0 if [[ $installAllFeatures ]]; then - installADTPro=1 - createBootDisk=1 - setupSerialPortLogin=1 - installCommTools=1 - installArchiveTools=1 - installEmulators=1 + installADTPro=1 + createBootDisk=1 + setupSerialPortLogin=1 + installCommTools=1 + installArchiveTools=1 + installEmulators=1 else - ### Q: Install ADTPro? - 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 + ### Q: Install ADTPro? + 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 - ### Q: Create disk images? - createBootDisk= - installArchiveTools= - newImageName= - imageSize= - if [[ $installADTPro ]]; then + ### Q: Create disk images? + 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 + 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 + 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 - ### Q: Install serial port login? - 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 + ### Q: Install serial port login? + 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 - ### Q: Install Comm Tools? - 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 + ### Q: Install Comm Tools? + 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 - ### Q: Install archive tools? - 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 + ### Q: Install archive tools? + 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 - ### Q: Install emulators? - installEmulators= - echo - echo -n "Install Apple IIgs and IIe emulators? " - read - [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installEmulators=1 + ### Q: Install emulators? + installEmulators= + echo + echo -n "Install Apple IIgs and IIe emulators? " + read + [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]] && installEmulators=1 fi @@ -267,18 +267,18 @@ userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') [[ $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 + 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'" @@ -290,8 +290,8 @@ echo "During this installation, enter ${thePassword}" echo "if prompted for passwords." echo if [[ ! $autoAnswerYes ]]; then - echo -n "Press return to continue..." - read + echo -n "Press return to continue..." + read fi @@ -303,10 +303,10 @@ cd /tmp/a2cloud-install ### A2CLOUD: Update apt package lists echo if [[ ! $skipRepoUpdate ]]; then - echo "A2CLOUD: Updating package lists..." - sudo apt-get -y update > /dev/null + echo "A2CLOUD: Updating package lists..." + sudo apt-get -y update > /dev/null else - echo "A2CLOUD: Not updating package lists..." + echo "A2CLOUD: Not updating package lists..." fi @@ -330,7 +330,7 @@ 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 + sudo sed -i 's/^gsport.*$/gsport : GSport Apple IIgs emulator (or log in with user "apple2user")/' /usr/local/etc/a2cloud-help.txt fi ### A2CLOUD: Install MOTD @@ -340,20 +340,20 @@ fi # 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 + 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 + 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 + wget -qO- "${scriptURL}setup/motd.txt" | sudo tee /etc/motd > /dev/null fi if lspci 2> /dev/null | grep -q VirtualBox; then - ### A2CLOUD: Disable screen blanking on vbox - 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 + ### A2CLOUD: Disable screen blanking on vbox + 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 ### A2CLOUD: Install aliases and make bash use them by default @@ -372,305 +372,305 @@ echo "$version" | sudo tee /usr/local/etc/A2CLOUD-version &> /dev/null ### A2CLOUD: Install avahi (Bonjour) 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 + 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." + echo "A2CLOUD: avahi-daemon (mDNS) is already installed." fi ### A2CLOUD: Install "at" if ! hash at 2> /dev/null; then - echo 'A2CLOUD: Installing "at"...' - sudo apt-get -y install at - sudo apt-get clean + echo 'A2CLOUD: Installing "at"...' + sudo apt-get -y install at + sudo apt-get clean else - echo 'A2CLOUD: "at" is already installed.' + echo 'A2CLOUD: "at" is already installed.' fi ### A2CLOUD: Install xdg-utils (FreeDesktop menus/icon tools) if ! hash xdg-desktop-menu 2> /dev/null; then - echo "A2CLOUD: Installing xdg-utils..." - sudo apt-get -y install xdg-utils - sudo apt-get clean + echo "A2CLOUD: Installing xdg-utils..." + sudo apt-get -y install xdg-utils + sudo apt-get clean else - echo "A2CLOUD: xdg-utils are already installed." + echo "A2CLOUD: xdg-utils are already installed." fi if [[ $installADTPro ]]; then - ### ADTPro: Make sure we have enough free space - 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 + ### ADTPro: Make sure we have enough free space + 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 - ### ADTPro: Install X and LXDE - ### Well, you need _something_ for ADTPro, and LXDE is the default on Raspbian - 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 - else - echo "A2CLOUD: X Window System and LXDE are already installed." - fi + ### ADTPro: Install X and LXDE + ### Well, you need _something_ for ADTPro, and LXDE is the default on Raspbian + 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 + else + echo "A2CLOUD: X Window System and LXDE are already installed." + fi - ### A2CLOUD: prevent automatically running LXDE at startup - if [[ -n "$isSystemd" ]]; then - sudo systemctl set-default multi-user.target &> /dev/null - elif [[ -n "$isSysVInit" ]]; then - sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT="text"/' /etc/default/grub - sudo update-grub - else - echo "A2CLOUD: can't disable GUI at startup: unrecognized init system." - fi + ### A2CLOUD: prevent automatically running LXDE at startup + if [[ -n "$isSystemd" ]]; then + sudo systemctl set-default multi-user.target &> /dev/null + elif [[ -n "$isSysVInit" ]]; then + sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT="text"/' /etc/default/grub + sudo update-grub + else + echo "A2CLOUD: can't disable GUI at startup: unrecognized init system." + fi -# ### A2CLOUD: Setup VirtualBox resolution -# ### FIXME: This doesn't appear to work in Jessie -# 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 -# ### A2CLOUD: Clean up after old version on RPi -# 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 +# ### A2CLOUD: Setup VirtualBox resolution +# ### FIXME: This doesn't appear to work in Jessie +# 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 +# ### A2CLOUD: Clean up after old version on RPi +# 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 + # 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 ADTPro - 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 + 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 ADTPro + 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 - ### ADTPro: Install ADTPro - if [[ ! -f /usr/local/adtpro/adtpro.sh || ! -f /usr/local/adtpro/ADTPro.html ]]; then - echo "A2CLOUD: installing ADTPro server..." - sudo pkill -f ADTPro - 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 + ### ADTPro: Install ADTPro + if [[ ! -f /usr/local/adtpro/adtpro.sh || ! -f /usr/local/adtpro/ADTPro.html ]]; then + echo "A2CLOUD: installing ADTPro server..." + sudo pkill -f ADTPro + 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 - ### ADTPro: Install AppleCommander - 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 - sudo 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 + ### ADTPro: Install AppleCommander + 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 + sudo 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 - ### ADTPro: Install our modified adtpro.sh - 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 + ### ADTPro: Install our modified adtpro.sh + 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 - ### ADTPro: Replace A2CLOUD's disks with the ones ... - ### FIXME: where are these created/downloaded to move? - 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 + ### ADTPro: Replace A2CLOUD's disks with the ones ... + ### FIXME: where are these created/downloaded to move? + 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 - ### ADTPro: Install rxtx - 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 + ### ADTPro: Install rxtx + 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 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 - ### A2CLOUD: Enable netatalk sharing for A2CLOUD if it's installed - if hash afpd 2> /dev/null; then # A2SERVER/netatalk installed - if [[ -d /srv/A2SERVER ]]; then - sharePath=/srv/A2SERVER - else - sharePath=/media/A2SHARED - fi + ### A2CLOUD: Enable netatalk sharing for A2CLOUD if it's installed + if hash afpd 2> /dev/null; then # A2SERVER/netatalk installed + if [[ -d /srv/A2SERVER ]]; then + sharePath=/srv/A2SERVER + else + sharePath=/media/A2SHARED + fi - if [[ ! -d ${sharePath}/ADTDISKS || ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then - echo "A2CLOUD: Setting up /usr/local/adtpro/disks for Apple file sharing..." - if [[ ! -d ${sharePath}/ADTDISKS ]]; then - ln -s /usr/local/adtpro/disks ${sharePath}/ADTDISKS 2> /dev/null - fi - if [[ $sharePath == "/srv/A2SERVER" ]] && grep '/media/A2SHARED/ADTDISKS' /usr/local/etc/netatalk/AppleVolumes.default; then - sudo sed -i 's@/media/A2SHARED/ADTDISKS@/srv/A2SERVER/ADTDISKS@' /usr/local/etc/netatalk/AppleVolumes.default - fi - if [[ ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then - sudo sed -i 's@^# End of File@${sharePath}/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 [[ ! -d ${sharePath}/ADTDISKS || ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then + echo "A2CLOUD: Setting up /usr/local/adtpro/disks for Apple file sharing..." + if [[ ! -d ${sharePath}/ADTDISKS ]]; then + ln -s /usr/local/adtpro/disks ${sharePath}/ADTDISKS 2> /dev/null + fi + if [[ $sharePath == "/srv/A2SERVER" ]] && grep '/media/A2SHARED/ADTDISKS' /usr/local/etc/netatalk/AppleVolumes.default; then + sudo sed -i 's@/media/A2SHARED/ADTDISKS@/srv/A2SERVER/ADTDISKS@' /usr/local/etc/netatalk/AppleVolumes.default + fi + if [[ ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then + sudo sed -i 's@^# End of File@${sharePath}/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 - ### A2CLOUD: Enable samba sharing for A2CLOUD, if A2SERVER installed it - if [[ $sharePath == "/srv/A2SERVER" ]] && grep '/media/A2SHARED/ADTDISKS' /etc/samba/smb.conf; then - sudo sed -i 's@/media/A2SHARED/ADTDISKS@/srv/A2SERVER/ADTDISKS@' /etc/samba/smb.conf - fi - if grep -q "$sharePath" /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 = ${sharePath}/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 + ### A2CLOUD: Enable samba sharing for A2CLOUD, if A2SERVER installed it + if [[ $sharePath == "/srv/A2SERVER" ]] && grep '/media/A2SHARED/ADTDISKS' /etc/samba/smb.conf; then + sudo sed -i 's@/media/A2SHARED/ADTDISKS@/srv/A2SERVER/ADTDISKS@' /etc/samba/smb.conf + fi + if grep -q "$sharePath" /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 = ${sharePath}/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 - ### A2CLOUD: Install various shell scripts - 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 + ### A2CLOUD: Install various shell scripts + 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 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 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 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 + 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 ### ADTPro: Install xrdp if hash X 2> /dev/null; then - if ! dpkg-query -l xrdp &> /dev/null; 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 + if ! dpkg-query -l xrdp &> /dev/null; 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." + echo "A2CLOUD: X11 not found; not installing xrdp/tightvncserver." fi ### A2CLOUD: Install serial port rules/scripts @@ -679,628 +679,628 @@ 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 - sudo udevadm control --reload-rules + 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 + sudo udevadm control --reload-rules else - echo "A2CLOUD: Device rules for USB ports already exist." + echo "A2CLOUD: Device rules for USB ports already exist." fi if [[ $setupSerialPortLogin ]]; then - ### SerialCon: Begin setting up serial console - 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 - if [[ -n "$isSystemd" ]]; then - sudo sed -i 's/ttyAMA0,[0-9]*/ttyAMA0,4800/g' /boot/cmdline.txt 2> /dev/null - elif [[ -n "$isSysVInit" ]]; then - 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 - else - echo "A2CLOUD: Cannot set console baud rate: Unrecognized init system" - fi + ### SerialCon: Begin setting up serial console + 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 + if [[ -n "$isSystemd" ]]; then + sudo sed -i 's/ttyAMA0,[0-9]*/ttyAMA0,4800/g' /boot/cmdline.txt 2> /dev/null + elif [[ -n "$isSysVInit" ]]; then + 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 + else + echo "A2CLOUD: Cannot set console baud rate: Unrecognized init system" + fi - 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 + 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 - ### SerialCon: Set up a single byte character set locale - ### TODO: Figure out how to make this ASCII or CP437. - # 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..." - locISO=$(grep "$langLatin1.ISO" /usr/share/i18n/SUPPORTED | sort | head -1) - 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) - 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 + ### SerialCon: Set up a single byte character set locale + ### TODO: Figure out how to make this ASCII or CP437. + # 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..." + locISO=$(grep "$langLatin1.ISO" /usr/share/i18n/SUPPORTED | sort | head -1) + 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) + 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 - ### SerialCon: Install serial login command scripts - 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 + ### SerialCon: Install serial login command scripts + 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 term command..." + sudo wget -qO /usr/local/bin/term ${scriptURL}setup/term.txt + sudo chmod ugo+x /usr/local/bin/term - ### SerialCon: Install USB serial port login - echo "A2CLOUD: Setting up USB shell login..." - sudo wget -qO /usr/local/sbin/usbgetty ${scriptURL}setup/usbgetty.txt - sudo chmod ugo+x /usr/local/sbin/usbgetty - if [[ -n "$isSystemd" ]]; then - # FIXME: Okay, the way we need to fix this is that we need to do the - # -scanttyUSB behavior and create a symlink in udev here. If we have - # a /dev/ttySerialConsole link, it's real easy to do this here with - # systemd, and it actually makes the script below not necessary. + ### SerialCon: Install USB serial port login + echo "A2CLOUD: Setting up USB shell login..." + sudo wget -qO /usr/local/sbin/usbgetty ${scriptURL}setup/usbgetty.txt + sudo chmod ugo+x /usr/local/sbin/usbgetty + if [[ -n "$isSystemd" ]]; then + # FIXME: Okay, the way we need to fix this is that we need to do the + # -scanttyUSB behavior and create a symlink in udev here. If we have + # a /dev/ttySerialConsole link, it's real easy to do this here with + # systemd, and it actually makes the script below not necessary. - # ID: I bandaided this by simply calling /usr/local/sbin/usbgetty from a getty - # service, just as it used to be called from /etc/inittab. However, - # the service doesn't automatically respawn when it dies, so ttyusbhandler - # (called by udev, as before) now restarts the service upon adapter insertion. - # This might not be the best way to do it, but it works for now, - # apart from a 30 second delay before the getty becomes available. - sudo wget -qO /etc/systemd/system/getty.target.wants/usbgetty@.service ${scriptURL}setup/usbgetty-systemd.service.txt - pwd=$PWD - cd /etc/systemd/system/getty.target.wants - grep -o 'SYMLINK+="ttyUSB.*,' /etc/udev/rules.d/50-usb.rules | cut -d '"' -f 2 | \ - while read ttyUSB; do - sudo rm usbgetty@${ttyUSB}.service 2> /dev/null - sudo ln -s usbgetty@.service usbgetty@${ttyUSB}.service - done - cd "$pwd" - sudo systemctl daemon-reload - elif [[ -n "$isSysVInit" ]]; then - echo "A2CLOUD: Removing ttyUSB0 shell login..." - sudo sed -i "s/^\([^#].*ttyUSB0.*\)$//" /etc/inittab + # ID: I bandaided this by simply calling /usr/local/sbin/usbgetty from a getty + # service, just as it used to be called from /etc/inittab. However, + # the service doesn't automatically respawn when it dies, so ttyusbhandler + # (called by udev, as before) now restarts the service upon adapter insertion. + # This might not be the best way to do it, but it works for now, + # apart from a 30 second delay before the getty becomes available. + sudo wget -qO /etc/systemd/system/getty.target.wants/usbgetty@.service ${scriptURL}setup/usbgetty-systemd.service.txt + pwd=$PWD + cd /etc/systemd/system/getty.target.wants + grep -o 'SYMLINK+="ttyUSB.*,' /etc/udev/rules.d/50-usb.rules | cut -d '"' -f 2 | \ + while read ttyUSB; do + sudo rm usbgetty@${ttyUSB}.service 2> /dev/null + sudo ln -s usbgetty@.service usbgetty@${ttyUSB}.service + done + cd "$pwd" + sudo systemctl daemon-reload + elif [[ -n "$isSysVInit" ]]; then + 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 "getty.*ttyUSB" - else - echo "A2CLOUD: USB port shell login already added." - fi - else - echo "A2CLOUD: Cannot set up USB shell login: Unrecognized init system" - fi + 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 "getty.*ttyUSB" + else + echo "A2CLOUD: USB port shell login already added." + fi + else + echo "A2CLOUD: Cannot set up USB shell login: Unrecognized init system" + fi fi if [[ $installCommTools ]]; then - if ! hash curl 2> /dev/null; then - ### CommTools: Install curl - 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 curl 2> /dev/null; then + ### CommTools: Install curl + 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 - ### CommTools: Install lrzsz - 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 sz 2> /dev/null; then + ### CommTools: Install lrzsz + 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 - ### CommTools: Install ftp - 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 ftp 2> /dev/null; then + ### CommTools: Install ftp + 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 - ### CommTools: Install cftp - 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-0.12.tar.gz http://nih.at/cftp/cftp-0.12.tar.gz - tar zxf cftp-0.12.tar.gz - 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 cftp 2> /dev/null; then + ### CommTools: Install cftp + 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-0.12.tar.gz http://nih.at/cftp/cftp-0.12.tar.gz + tar zxf cftp-0.12.tar.gz + 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 - ### CommTools: Install lynx - 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 lynx 2> /dev/null; then + ### CommTools: Install lynx + 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 - ### CommTools: Install links - 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 + if ! hash links 2> /dev/null; then + ### CommTools: Install links + 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 - ### CommTools: Install tin + a2news script - 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 - ### CommTools: Configure exim4 to use ipv4 to kill console errors - # 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 + ### CommTools: Install tin + a2news script + 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 + ### CommTools: Configure exim4 to use ipv4 to kill console errors + # 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 - ### CommTools: Install irssi + a2chat script - 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 + ### CommTools: Install irssi + a2chat script + 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 - ### CommTools: Install telnet - 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 + ### CommTools: Install telnet + 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 - ### CommTools: Install Oysttyer (formerly TTYtter) - # 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 - perlVersion=$(perl -e 'print $^V' | cut -c 2-) - if ! hash ttytter 2> /dev/null || [[ ! -f /usr/local/share/perl/${perlVersion}/Term/ReadLine/TTYtter.pm ]]; then - echo "A2CLOUD: Installing Oysttyer..." - # 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 - wget -qO- https://github.com/oysttyer/oysttyer/archive/2.7.2.tar.gz | sudo tar -zxP --transform 's|oysttyer-2.7.2/oysttyer.pl|/usr/local/bin/oysttyer|' oysttyer-2.7.2/oysttyer.pl - sudo rm /usr/local/bin/ttytter 2> /dev/null - sudo ln -s /usr/local/bin/oysttyer /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" || $perlVersion == "5.20.2" ]]; then - wget -qO- ${binaryURL}precompiled/ttytter_readline-rpi.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.33.tar.gz http://www.cpan.org/authors/id/J/JS/JSTOWE/TermReadKey-2.33.tar.gz - tar zxf TermReadKey-2.33.tar.gz - cd TermReadKey-2.33 - perl Makefile.PL &> /dev/null - if ! hash make 2> /dev/null; then - sudo apt-get -y install build-essential - sudo apt-get -y clean - fi - make &> /dev/null - sudo make install &> /dev/null - cd /tmp/a2cloud-install - rm -rf TermReadKey-2.33 - 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 - if ! hash make 2> /dev/null; then - sudo apt-get -y install build-essential - sudo apt-get -y clean - fi - 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: Oysttyer is already installed." - fi + ### CommTools: Install Oysttyer (formerly TTYtter) + # 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 + perlVersion=$(perl -e 'print $^V' | cut -c 2-) + if ! hash ttytter 2> /dev/null || [[ ! -f /usr/local/share/perl/${perlVersion}/Term/ReadLine/TTYtter.pm ]]; then + echo "A2CLOUD: Installing Oysttyer..." + # 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 + wget -qO- https://github.com/oysttyer/oysttyer/archive/2.7.2.tar.gz | sudo tar -zxP --transform 's|oysttyer-2.7.2/oysttyer.pl|/usr/local/bin/oysttyer|' oysttyer-2.7.2/oysttyer.pl + sudo rm /usr/local/bin/ttytter 2> /dev/null + sudo ln -s /usr/local/bin/oysttyer /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" || $perlVersion == "5.20.2" ]]; then + wget -qO- ${binaryURL}precompiled/ttytter_readline-rpi.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.33.tar.gz http://www.cpan.org/authors/id/J/JS/JSTOWE/TermReadKey-2.33.tar.gz + tar zxf TermReadKey-2.33.tar.gz + cd TermReadKey-2.33 + perl Makefile.PL &> /dev/null + if ! hash make 2> /dev/null; then + sudo apt-get -y install build-essential + sudo apt-get -y clean + fi + make &> /dev/null + sudo make install &> /dev/null + cd /tmp/a2cloud-install + rm -rf TermReadKey-2.33 + 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 + if ! hash make 2> /dev/null; then + sudo apt-get -y install build-essential + sudo apt-get -y clean + fi + 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: Oysttyer is already installed." + fi fi if [[ $installEmulators ]]; then - ### Emulators: GSport - if ! hash gsport 2> /dev/null || ! hash gsportx 2> /dev/null || ! hash gsportfb 2> /dev/null; then - # FIXME: This is a _TERRIBLE_ name/place for this... - gsportConfigFile='/usr/local/lib/config.txt' + ### Emulators: GSport + if ! hash gsport 2> /dev/null || ! hash gsportx 2> /dev/null || ! hash gsportfb 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 || ! hash gsportx 2> /dev/null || ! hash gsportfb 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 + 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 || ! hash gsportx 2> /dev/null || ! hash gsportfb 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 + 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 - buildGSport=1 - cp vars_fbrpilinux vars_fb - if [[ -n $isRpi ]]; then - cp vars_pi vars_x - else - cp vars_x86linux vars_x - if [[ $arch == "debian_x86" ]]; then - sed -i 's/-march=armv6/-march=i686/' vars_fb - elif [[ $arch == "debian_x64" ]]; then - sed -i 's/-march=i686/-march=x86-64/' vars_x - sed -i 's/-march=armv6/-march=x86-64/' vars_fb - else - buildGSport= - echo "A2CLOUD: cannot build GSport; unknown machine architecture." - fi - fi - sed -i 's/^LDFLAGS =.*$/LDFLAGS = -ldl/' vars_x - sed -i 's/^LDFLAGS =.*$/LDFLAGS = -ldl/' vars_fb - if [[ -n $buildGSport ]]; then - for varsFile in vars_x vars_fb; do - rm vars 2> /dev/null - cp $varsFile vars - make clean &> /dev/null - make &> /dev/null - sudo cp -P ../gsport${varsFile:5:2} /usr/local/bin - done - gcc -o ../to_pro to_pro.c &> /dev/null - gcc -o ../partls partls.c &> /dev/null - sudo cp -P ../to_pro ../partls /usr/local/bin - sudo cp ../config.txt "$gsportConfigFile" - sudo chmod ugo+w "$gsportConfigFile" - cd "${gsportConfigFile%/*}" - sudo ln -s "${gsportConfigFile##*/}" gsport_config.txt 2> /dev/null - fi - cd /tmp/a2cloud-install 2> /dev/null - rm -rf gsport 2> /dev/null - fi + buildGSport=1 + cp vars_fbrpilinux vars_fb + if [[ -n $isRpi ]]; then + cp vars_pi vars_x + else + cp vars_x86linux vars_x + if [[ $arch == "debian_x86" ]]; then + sed -i 's/-march=armv6/-march=i686/' vars_fb + elif [[ $arch == "debian_x64" ]]; then + sed -i 's/-march=i686/-march=x86-64/' vars_x + sed -i 's/-march=armv6/-march=x86-64/' vars_fb + else + buildGSport= + echo "A2CLOUD: cannot build GSport; unknown machine architecture." + fi + fi + sed -i 's/^LDFLAGS =.*$/LDFLAGS = -ldl/' vars_x + sed -i 's/^LDFLAGS =.*$/LDFLAGS = -ldl/' vars_fb + if [[ -n $buildGSport ]]; then + for varsFile in vars_x vars_fb; do + rm vars 2> /dev/null + cp $varsFile vars + make clean &> /dev/null + make &> /dev/null + sudo cp -P ../gsport${varsFile:5:2} /usr/local/bin + done + gcc -o ../to_pro to_pro.c &> /dev/null + gcc -o ../partls partls.c &> /dev/null + sudo cp -P ../to_pro ../partls /usr/local/bin + sudo cp ../config.txt "$gsportConfigFile" + sudo chmod ugo+w "$gsportConfigFile" + cd "${gsportConfigFile%/*}" + sudo ln -s "${gsportConfigFile##*/}" gsport_config.txt 2> /dev/null + fi + cd /tmp/a2cloud-install 2> /dev/null + rm -rf gsport 2> /dev/null + 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 [[ $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_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" + 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..." + ### 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 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 + 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 + 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 - echo "A2CLOUD: Building LinApple 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_src-2b.tar.bz2 http://downloads.sourceforge.net/project/linapple/linapple/linapple_2b/linapple_src-2b.tar.bz2 - tar jxf linapple_src-2b.tar.bz2 - cd linapple_src-2b/src - # doesn't compile with gcc 4.7, so use 4.6 -- needed for linapple 2a - #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: 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 + echo "A2CLOUD: Building LinApple 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_src-2b.tar.bz2 http://downloads.sourceforge.net/project/linapple/linapple/linapple_2b/linapple_src-2b.tar.bz2 + tar jxf linapple_src-2b.tar.bz2 + cd linapple_src-2b/src + # doesn't compile with gcc 4.7, so use 4.6 -- needed for linapple 2a + #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 addgroup gsport &> /dev/null - sudo usermod -a -G audio,video,netdev,gsport,plugdev $USER &> /dev/null + ### Emulators: Set Groups + sudo addgroup gsport &> /dev/null + sudo usermod -a -G audio,video,netdev,gsport,plugdev $USER &> /dev/null fi if [[ $installArchiveTools ]]; then - if ! hash nulib2 2> /dev/null; then + if ! hash nulib2 2> /dev/null; then - echo "A2CLOUD: Installing nulib2..." + echo "A2CLOUD: Installing nulib2..." - cd /tmp/a2cloud-install - if [[ $downloadBinaries ]]; then - ### ArchiveTools: Install nulib2 binaries - wget -qO- "${binaryURL}precompiled/nulib2-${arch}_${debianName}.tgz" | sudo tar Pzx - fi + cd /tmp/a2cloud-install + if [[ $downloadBinaries ]]; then + ### ArchiveTools: Install nulib2 binaries + wget -qO- "${binaryURL}precompiled/nulib2-${arch}_${debianName}.tgz" | sudo tar Pzx + fi - if ! hash nulib2 2> /dev/null; then - ### ArchiveTools: Install nulib2 from source - sudo apt-get -y install build-essential - sudo apt-get -y install zlib1g-dev - sudo apt-get -y clean + if ! hash nulib2 2> /dev/null; then + ### ArchiveTools: Install nulib2 from source + 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 + # 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 - ### ArchiveTools: Install undoit (sciibin, etc.) - echo "A2CLOUD: Installing sciibin, unblu, unbit, unexec, usq..." + if ! hash sciibin 2> /dev/null; then + ### ArchiveTools: Install undoit (sciibin, etc.) + 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 + 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..." - ### ArchiveTools: Install shk2image command - sudo wget -qO /usr/local/bin/shk2image ${scriptURL}setup/shk2image.txt - sudo chmod ugo+x /usr/local/bin/shk2image + echo "A2CLOUD: Setting up shk2image command..." + ### ArchiveTools: Install shk2image command + sudo wget -qO /usr/local/bin/shk2image ${scriptURL}setup/shk2image.txt + sudo chmod ugo+x /usr/local/bin/shk2image - # http://wakaba.c3.cx/s/apps/unarchiver.html - if ! hash unar 2> /dev/null; then + # http://wakaba.c3.cx/s/apps/unarchiver.html + if ! hash unar 2> /dev/null; then - ### ArchiveTools: Install unar package - echo "A2CLOUD: Installing The Unarchiver..." + ### ArchiveTools: Install unar package + 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 + # 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 ! 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 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 + 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 + 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 if [[ -f /usr/bin/X ]]; then - [[ -d /etc/xdg/lxsession/LXDE-pi ]] && lxde="lxde-pi" || lxde="lxde" - echo "A2CLOUD: Creating LXDE desktop and menu shortcuts..." + [[ -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 + # 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 - mkdir -p ~/Desktop - # GSport: - if [[ -f /usr/bin/gsport ]]; then - echo -e "[Desktop Entry]\nName=GSport\nComment=Apple IIgs Emulator\nExec=lxterminal -e /usr/bin/gsport\nIcon=/usr/local/share/gsport32.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/gsport.desktop > ~/Desktop/gsport.desktop - elif [[ -f /usr/local/bin/gsport ]]; then - echo -e "[Desktop Entry]\nName=GSport\nComment=Apple IIgs Emulator\nExec=lxterminal -e /usr/local/bin/gsport\nIcon=/usr/local/share/gsport32.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/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: - if [[ -f /usr/local/bin/linapple ]]; then - echo -e "[Desktop Entry]\nName=LinApple\nComment=Apple IIe Emulator\nExec=lxterminal -e /usr/local/bin/linapple\nIcon=/usr/local/linapple/icon.bmp\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/linapple.desktop > ~/Desktop/linapple.desktop - fi - # ADTPro Server: - if [[ -f /usr/local/bin/adtpro.sh ]]; then - echo -e "[Desktop Entry]\nName=ADTPro Server\nComment=Floppy Transfer Utility\nExec=/usr/local/bin/adtpro.sh\nIcon=/usr/local/adtpro/lib/ADTPro.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/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 $(grep -o '/.*lxterminal.desktop.*$' panel) ~/Desktop/lxterminal.desktop - fi + mkdir -p ~/Desktop + # GSport: + if [[ -f /usr/bin/gsport ]]; then + echo -e "[Desktop Entry]\nName=GSport\nComment=Apple IIgs Emulator\nExec=lxterminal -e /usr/bin/gsport\nIcon=/usr/local/share/gsport32.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/gsport.desktop > ~/Desktop/gsport.desktop + elif [[ -f /usr/local/bin/gsport ]]; then + echo -e "[Desktop Entry]\nName=GSport\nComment=Apple IIgs Emulator\nExec=lxterminal -e /usr/local/bin/gsport\nIcon=/usr/local/share/gsport32.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/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: + if [[ -f /usr/local/bin/linapple ]]; then + echo -e "[Desktop Entry]\nName=LinApple\nComment=Apple IIe Emulator\nExec=lxterminal -e /usr/local/bin/linapple\nIcon=/usr/local/linapple/icon.bmp\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/linapple.desktop > ~/Desktop/linapple.desktop + fi + # ADTPro Server: + if [[ -f /usr/local/bin/adtpro.sh ]]; then + echo -e "[Desktop Entry]\nName=ADTPro Server\nComment=Floppy Transfer Utility\nExec=/usr/local/bin/adtpro.sh\nIcon=/usr/local/adtpro/lib/ADTPro.ico\nTerminal=false\nType=Application\nCategories=AppleII\n" | sudo tee /usr/share/raspi-ui-overrides/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 $(grep -o '/.*lxterminal.desktop.*$' panel) ~/Desktop/lxterminal.desktop + fi fi @@ -1308,281 +1308,281 @@ fi ### DiskImage: Make/update A2CLOUD disks if [[ $updateADTPro || $createBootDisk ]] && hash acmd 2> /dev/null; then - a2CloudDisk=/usr/local/adtpro/disks/A2CLOUD.PO + a2CloudDisk=/usr/local/adtpro/disks/A2CLOUD.PO else - a2CloudDisk= + 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 + 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 - ### DiskImage: Use existing A2CLOUD disks + if [[ ! $makeA2CloudDisk ]]; then + ### DiskImage: Use existing A2CLOUD disks - a2CloudDiskUpdated= - if [[ $updateADTPro && -f "$a2CloudDisk" ]]; then - ### DiskImage: Update ADTPro on 800k image - sudo pkill -f ADTPro - 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 - ### DiskImage: Update ADTPro on 140k image - sudo pkill -f ADTPro - 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 - ### DiskImage: Building images from scratch - sudo pkill -f ADTPro - 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 + a2CloudDiskUpdated= + if [[ $updateADTPro && -f "$a2CloudDisk" ]]; then + ### DiskImage: Update ADTPro on 800k image + sudo pkill -f ADTPro + 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 + ### DiskImage: Update ADTPro on 140k image + sudo pkill -f ADTPro + 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 + ### DiskImage: Building images from scratch + sudo pkill -f ADTPro + 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 + # 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 + # start with a disk image + echo "A2CLOUD: Creating 800K disk image..." + cp /usr/local/adtpro/disks/ADTPRO-*PO $a2CloudDisk + acmd -n $a2CloudDisk A2CLOUD - ### DiskImage: Begin by modifying ADTPro image - echo "A2CLOUD: Preparing ADTPro..." + ### DiskImage: Begin by modifying ADTPro image + echo "A2CLOUD: Preparing ADTPro..." - acmd -d "$a2CloudDisk" BASIC - acmd -d "$a2CloudDisk" STARTUP.SYSTEM - acmd -d "$a2CloudDisk" 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" + 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 + # 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 - ### DiskImage: Add VEDRIVE to A2CLOUD disk - 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 + ### DiskImage: Add VEDRIVE to A2CLOUD disk + 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" + 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" - ### DiskImage: Add Apple System Utilities 3.1 support files to A2CLOUD disk - 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 + ### DiskImage: Add Apple System Utilities 3.1 support files to A2CLOUD disk + 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 - ### DiskImage: Add ProTERM 3.1 to A2CLOUD disk - 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 2> /dev/null - 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 + ### DiskImage: Add ProTERM 3.1 to A2CLOUD disk + 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 2> /dev/null + 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 - ### DiskImage: Add Z-Link to A2CLOUD disk - 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 + ### DiskImage: Add Z-Link to A2CLOUD disk + 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 - ### DiskImage: Add ShrinkIt to A2CLOUD disk - 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 + ### DiskImage: Add ShrinkIt to A2CLOUD disk + 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 - ### DiskImage: Add DSK2FILE to A2CLOUD disk - 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 + ### DiskImage: Add DSK2FILE to A2CLOUD disk + 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 - ### DiskImage: Add Apple System Utilities 3.1 to A2CLOUD disk - ### Required unar to unpack above (see ## ArchiveTools: Install unar package) - ### Apple_II_System_Disk_3.2.sea.bin - 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 + ### DiskImage: Add Apple System Utilities 3.1 to A2CLOUD disk + ### Required unar to unpack above (see ## ArchiveTools: Install unar package) + ### Apple_II_System_Disk_3.2.sea.bin + 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 - ### DiskImage: Add Filer to A2CLOUD disk - 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 + ### DiskImage: Add Filer to A2CLOUD disk + 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 - ### DiskImage: Add ADTPro client to A2CLOUD disk - echo "A2CLOUD: Copying ADTPro launch file..." - acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO - | acmd -p "$a2CloudDisk" ADTPRO SYS + ### DiskImage: Add ADTPro client to A2CLOUD disk + echo "A2CLOUD: Copying ADTPro launch file..." + acmd -g /usr/local/adtpro/disks/ADTPRO-*DSK ADTPRO - | acmd -p "$a2CloudDisk" ADTPRO SYS - ### DiskImage: Add VSDRIVE to A2CLOUD disk - 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 + ### DiskImage: Add VSDRIVE to A2CLOUD disk + 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 + fi - if [[ ! -f $a2CloudDisk140 || ( $(wc -c $a2CloudDisk140 | cut -f 1 -d ' ') != "143360" ) ]]; then + if [[ ! -f $a2CloudDisk140 || ( $(wc -c $a2CloudDisk140 | cut -f 1 -d ' ') != "143360" ) ]]; then - ### DiskImage: Create 140k disk image - 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 + ### DiskImage: Create 140k disk image + 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 + 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 + fi - if [[ -f /usr/local/adtpro/disks/Virtual.po && ! -L /usr/local/adtpro/disks/Virtual.po ]]; then - ### DiskImage: Virtual.po exists and is not a symlink - ### Move it and link it back into place - 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 - ### DiskImage: Virtual2.po exists and is not a symlink - if [[ $(sha1sum /usr/local/adtpro/disks/Virtual2.po | cut -d ' ' -f 1) == "41c178f9f596f94ea7607624672552137dccade2" ]]; then - ### DiskImage: We recognize it, just delete - rm /usr/local/adtpro/disks/Virtual2.po - else - ### DiskImage: We do NOT recognize this Virtual2.po file - ### ...just move it out of the way - mv /usr/local/adtpro/disks/Virtual2.po /usr/local/adtpro/disks/defaultVirtual2.po &> /dev/null - fi - fi - vsd2 -f $a2CloudDisk + if [[ -f /usr/local/adtpro/disks/Virtual.po && ! -L /usr/local/adtpro/disks/Virtual.po ]]; then + ### DiskImage: Virtual.po exists and is not a symlink + ### Move it and link it back into place + 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 + ### DiskImage: Virtual2.po exists and is not a symlink + if [[ $(sha1sum /usr/local/adtpro/disks/Virtual2.po | cut -d ' ' -f 1) == "41c178f9f596f94ea7607624672552137dccade2" ]]; then + ### DiskImage: We recognize it, just delete + rm /usr/local/adtpro/disks/Virtual2.po + else + ### DiskImage: We do NOT recognize this Virtual2.po file + ### ...just move it out of the way + mv /usr/local/adtpro/disks/Virtual2.po /usr/local/adtpro/disks/defaultVirtual2.po &> /dev/null + fi + fi + vsd2 -f $a2CloudDisk - ### DiskImage: Create pre 1.6.7 A2CLOUD.HDV compatibility symlink - ### Do we still need this? ID sez: not sure, but I think so - # for compatibility with pre-1.6.7 - ln -s /usr/local/adtpro/disks/A2CLOUD.PO /usr/local/adtpro/disks/A2CLOUD.HDV + ### DiskImage: Create pre 1.6.7 A2CLOUD.HDV compatibility symlink + ### Do we still need this? ID sez: not sure, but I think so + # 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 + 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 if [[ $newImageName ]]; then - ### DiskImage: This is where the new Virtual.po gets made (search newImageName) - # make new blank disk of specified size - echo "A2CLOUD: Creating new ${imageSize}K image for virtual drive 1 at" - echo " /usr/local/adtpro/disks/$newImageName..." - sudo pkill -f ADTPro - 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" + ### DiskImage: This is where the new Virtual.po gets made (search newImageName) + # make new blank disk of specified size + echo "A2CLOUD: Creating new ${imageSize}K image for virtual drive 1 at" + echo " /usr/local/adtpro/disks/$newImageName..." + sudo pkill -f ADTPro + 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 ### A2CLOUD: Setup the a2cloud-setup command @@ -1591,10 +1591,10 @@ sudo chmod ugo+x /usr/local/bin/a2cloud-setup if [[ ! $restartPrompt ]]; then - ### A2CLOUD: Start ADTPro - ### If we're not going to just reboot the system, ADTPro - ### should not be running yet. We'll start it here. - adtpro-start 2> /dev/null #start ADTPro if not running and USB adapter attached + ### A2CLOUD: Start ADTPro + ### If we're not going to just reboot the system, ADTPro + ### should not be running yet. We'll start it here. + adtpro-start 2> /dev/null #start ADTPro if not running and USB adapter attached fi echo @@ -1605,13 +1605,13 @@ echo "See http://ivanx.com/a2cloud for instructions." sudo apt-get -y clean if [[ $restartPrompt ]]; then - ### A2CLOUD: Ask about restarting your system - 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 + ### A2CLOUD: Ask about restarting your system + 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 ### A2CLOUD: Clean up temp files @@ -1622,12 +1622,12 @@ rm -rf /tmp/a2cloud-install &> /dev/null ### A2CLOUD: in case not restarting, make groups take effect immediately if hash gsport 2> /dev/null; then - if [[ ! $noSetGroups ]]; then - if ! groups | grep -q 'gsport'; then - touch /tmp/no-gsport - exec sudo su -l $USER; - fi - fi + if [[ ! $noSetGroups ]]; then + if ! groups | grep -q 'gsport'; then + touch /tmp/no-gsport + exec sudo su -l $USER; + fi + fi fi ### A2CLOUD: If restarting, restart @@ -1636,8 +1636,8 @@ fi # version history: # future -- local links for everything -# email -# chromium +# email +# chromium # version history: @@ -1995,110 +1995,110 @@ fi #= 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 +# 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 +# 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 +# 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 +# # 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 +# # 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 + # 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 diff --git a/setup/shk2image.txt b/setup/shk2image.txt old mode 100644 new mode 100755 index 63babee..a3334d7 --- a/setup/shk2image.txt +++ b/setup/shk2image.txt @@ -1,5 +1,5 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: origDir="$PWD" [[ ! -n $1 || ! -n $2 ]] && { echo "Usage: shk2image archiveFileName imageFileName [PRODOS.DIR.NAME]"; exit 1; }; @@ -15,11 +15,11 @@ cd /tmp/shk2image_temp shkFiles=$(nulib2 -xse "$archiveFile" | tr "\r" "~" | cut -d "~" -f 2 | cut -c 18-); cd "$origDir" while read thisFile; do - fileName=${thisFile%%#*}; - fileType=${thisFile##*#}; - echo "extracting $fileName..."; - acmd -d "$imageFileName" $dirName$fileName &>/dev/null; - acmd -p "$imageFileName" $dirName$fileName \$${fileType:0:2} \$${fileType:2:4} < /tmp/shk2image_temp/"$thisFile" - rm /tmp/shk2image_temp/"$thisFile" + fileName=${thisFile%%#*}; + fileType=${thisFile##*#}; + echo "extracting $fileName..."; + acmd -d "$imageFileName" $dirName$fileName &>/dev/null; + acmd -p "$imageFileName" $dirName$fileName \$${fileType:0:2} \$${fileType:2:4} < /tmp/shk2image_temp/"$thisFile" + rm /tmp/shk2image_temp/"$thisFile" done <<< $shkFiles rm -r /tmp/shk2image_temp diff --git a/setup/term.txt b/setup/term.txt old mode 100644 new mode 100755 index 58f3ca1..c30b684 --- a/setup/term.txt +++ b/setup/term.txt @@ -1,48 +1,48 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: if [[ $1 == "-d" ]]; then - shift - setgetty=1 + shift + setgetty=1 else - setgetty= + setgetty= fi if [[ $1 == "-f" ]]; then - shift - force=1 + shift + force=1 else - force= + force= fi if [[ ! $1 || $1 == "--help" || $1 == "-h" ]]; then - echo 'Usage: term [-d] mono|color|none|'; - echo ' -d sets default emulation for all serial port shells (takes effect on logout)' - echo ' omitting -d makes change temporary and immediate' - echo ' -f forces change even if not running on serial port (e.g. within "screen")' - echo ' Terminal emulation: mono->VT-100, color->PC-ANSI/ANSI-BBS, none->no emulation' + echo 'Usage: term [-d] mono|color|none|'; + echo ' -d sets default emulation for all serial port shells (takes effect on logout)' + echo ' omitting -d makes change temporary and immediate' + echo ' -f forces change even if not running on serial port (e.g. within "screen")' + echo ' Terminal emulation: mono->VT-100, color->PC-ANSI/ANSI-BBS, none->no emulation' else - if [[ $(tr [:upper:] [:lower:] <<< $1) == "mono" ]]; then - term="vt100" - elif [[ $(tr [:upper:] [:lower:] <<< $1) == "color" ]]; then - term="pcansi" - elif [[ $(tr [:upper:] [:lower:] <<< $1) == "none" ]]; then - term="dumb" - else - term="$1" - fi - if [[ $setgetty ]]; then - sudo sed -i "s/\(ttyAMA0 .*\) .*$/\1 $term/" /etc/inittab; - sudo sed -i "s/\(ttyUSB.* .*\) .*$/\1 $term/g" /etc/inittab; - sudo init q; - sudo pkill -f "/sbin/getty" - else - if [[ $force || $(tty | grep tty) ]]; then - TERM="$term" - else - echo 1>&2 "Not running on serial port. No action taken. Use -f to set anyway." - fi - fi + if [[ $(tr [:upper:] [:lower:] <<< $1) == "mono" ]]; then + term="vt100" + elif [[ $(tr [:upper:] [:lower:] <<< $1) == "color" ]]; then + term="pcansi" + elif [[ $(tr [:upper:] [:lower:] <<< $1) == "none" ]]; then + term="dumb" + else + term="$1" + fi + if [[ $setgetty ]]; then + sudo sed -i "s/\(ttyAMA0 .*\) .*$/\1 $term/" /etc/inittab; + sudo sed -i "s/\(ttyUSB.* .*\) .*$/\1 $term/g" /etc/inittab; + sudo init q; + sudo pkill -f "/sbin/getty" + else + if [[ $force || $(tty | grep tty) ]]; then + TERM="$term" + else + echo 1>&2 "Not running on serial port. No action taken. Use -f to set anyway." + fi + fi fi echo -e "$(tty) current emulation: $(tput bold)$TERM$(tput sgr0)" diff --git a/setup/ttyusbhandler.txt b/setup/ttyusbhandler.txt old mode 100644 new mode 100755 index 2031c50..ec4ff46 --- a/setup/ttyusbhandler.txt +++ b/setup/ttyusbhandler.txt @@ -1,5 +1,5 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: # called by udev as: # ttyusbhandler [add|remove] ttyUSBname @@ -21,42 +21,42 @@ # rescan for getty if [[ $1 == "remove" ]]; then - rm /tmp/udev-$2-removed &> /dev/null - touch /tmp/udev-$2-removed - pkill -f "$2.*ADTPro" + rm /tmp/udev-$2-removed &> /dev/null + touch /tmp/udev-$2-removed + pkill -f "$2.*ADTPro" elif [[ $1 == "add" ]]; then - [[ $2 == "ttyUSBlower" ]] && sleep 1.5 - [[ ${#2} -gt 11 ]] && sleep "${2:15:2}" - if [[ $2 == "ttyUSBlower" || \ - $2 == $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | head -1 | cut -c 6-) || \ - ( ${2:0:12} == "ttyUSBlower_" && $2 != $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | tail -1 | cut -c 6-) ) \ - ]]; then - rm /tmp/udev-ttyUSBlower-added &> /dev/null - touch /tmp/udev-ttyUSBlower-added - pkill -f "[A]DTPro" - pkill -f "[u]sbgetty" - exec echo "/usr/local/adtpro/adtpro.sh headless serial" | at -M now - else # ttyUSBupper - rm /tmp/udev-ttyUSBupper-added &> /dev/null - touch /tmp/udev-ttyUSBupper-added - pkill -f "[g]etty.*ttyUSB" - if [[ -f /bin/systemctl ]]; then # if systemd - # if USB-to-serial adapter is directly attached to upper port - if [[ -c /dev/ttyUSBupper ]]; then - ttyUSB=ttyUSBupper - # if hub in upper port, use highest numbered port on hub - elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 0 ]]; then - ttyUSB=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | tail -1 | cut -c 6-) - # if hub in lower port with multiple adapters, use highest numbered port on hub - elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 1 ]]; then - ttyUSB=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | tail -1 | cut -c 6-) - else - # by definition, this shouldn't happen - ttyUSB= - fi - exec systemctl restart usbgetty@$ttyUSB - fi - fi + [[ $2 == "ttyUSBlower" ]] && sleep 1.5 + [[ ${#2} -gt 11 ]] && sleep "${2:15:2}" + if [[ $2 == "ttyUSBlower" || \ + $2 == $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | head -1 | cut -c 6-) || \ + ( ${2:0:12} == "ttyUSBlower_" && $2 != $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | tail -1 | cut -c 6-) ) \ + ]]; then + rm /tmp/udev-ttyUSBlower-added &> /dev/null + touch /tmp/udev-ttyUSBlower-added + pkill -f "[A]DTPro" + pkill -f "[u]sbgetty" + exec echo "/usr/local/adtpro/adtpro.sh headless serial" | at -M now + else # ttyUSBupper + rm /tmp/udev-ttyUSBupper-added &> /dev/null + touch /tmp/udev-ttyUSBupper-added + pkill -f "[g]etty.*ttyUSB" + if [[ -f /bin/systemctl ]]; then # if systemd + # if USB-to-serial adapter is directly attached to upper port + if [[ -c /dev/ttyUSBupper ]]; then + ttyUSB=ttyUSBupper + # if hub in upper port, use highest numbered port on hub + elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 0 ]]; then + ttyUSB=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | tail -1 | cut -c 6-) + # if hub in lower port with multiple adapters, use highest numbered port on hub + elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 1 ]]; then + ttyUSB=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | tail -1 | cut -c 6-) + else + # by definition, this shouldn't happen + ttyUSB= + fi + exec systemctl restart usbgetty@$ttyUSB + fi + fi else - exit 2 + exit 2 fi diff --git a/setup/usbgetty.txt b/setup/usbgetty.txt old mode 100644 new mode 100755 index a0751ed..f2cde3d --- a/setup/usbgetty.txt +++ b/setup/usbgetty.txt @@ -1,48 +1,48 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: ttyUSB= pkill -f "sleep 86399" if [[ $(grep -e '-scanttyUSB' <<< "$*") ]]; then - # called with -scantty isntead of device name? - # echo "-scantty mode" + # called with -scantty isntead of device name? + # echo "-scantty mode" - # if upper USB port - if [[ -c /dev/ttyUSBupper ]]; then - ttyUSB=ttyUSBupper + # if upper USB port + if [[ -c /dev/ttyUSBupper ]]; then + ttyUSB=ttyUSBupper - # if hub in upper port, use highest numbered port on hub - elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 0 ]]; then - ttyUSB=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | tail -1 | cut -c 6-) + # if hub in upper port, use highest numbered port on hub + elif [[ $(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | wc -l) -gt 0 ]]; then + ttyUSB=$(ls -1 /dev/ttyUSBupper_hub* 2> /dev/null | tail -1 | cut -c 6-) - # if hub in lower port with multiple adapters, use highest numbered port on hub - elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 1 ]]; then - ttyUSB=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | tail -1 | cut -c 6-) + # if hub in lower port with multiple adapters, use highest numbered port on hub + elif [[ $(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | wc -l) -gt 1 ]]; then + ttyUSB=$(ls -1 /dev/ttyUSBlower_hub* 2> /dev/null | tail -1 | cut -c 6-) - # no port found eligible for getty - else - # echo "scantty no devices eligible: sleeping" - sleep 86399 - fi + # no port found eligible for getty + else + # echo "scantty no devices eligible: sleeping" + sleep 86399 + fi - # echo "result:$ttyUSB" + # echo "result:$ttyUSB" elif [[ $(grep -o 'ttyUSB[^ ]*' <<< "$*") ]]; then - # echo "device specified" - # if specified USB device name is found - ttyUSB=$(grep -o 'ttyUSB[^ ]*' <<< "$*") + # echo "device specified" + # if specified USB device name is found + ttyUSB=$(grep -o 'ttyUSB[^ ]*' <<< "$*") else - # echo "specified device failed: sleeping" - sleep 86399 + # echo "specified device failed: sleeping" + sleep 86399 fi if [[ -c /dev/$ttyUSB && ! $(ps aux | grep "[g]etty.*$ttyUSB") ]]; then - # if adapter seems to exist and doesn't already have a getty, - # kill all USB gettys and start the getty, otherwise do nothing - pkill -f "/sbin/getty.*ttyUSB" - exec /sbin/getty $(sed "s/-scanttyUSB/$ttyUSB/" <<< "$@"); + # if adapter seems to exist and doesn't already have a getty, + # kill all USB gettys and start the getty, otherwise do nothing + pkill -f "/sbin/getty.*ttyUSB" + exec /sbin/getty $(sed "s/-scanttyUSB/$ttyUSB/" <<< "$@"); else - # echo "getty already running or doesn't exist: sleeping" - sleep 86399 + # echo "getty already running or doesn't exist: sleeping" + sleep 86399 fi diff --git a/setup/vsd.txt b/setup/vsd.txt old mode 100644 new mode 100755 index 4ff7865..bc87e50 --- a/setup/vsd.txt +++ b/setup/vsd.txt @@ -1,42 +1,42 @@ #! /bin/bash -# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: skipWarning= drive= if [[ $1 == "-1" || $1 == "-d1" ]]; then - shift + shift elif [[ $1 = "-2" || $1 == "-d2" ]]; then - drive=2 - shift + drive=2 + shift fi if [[ ! $1 ]]; then - echo "virtual drive $(( drive ? 2 : 1 )): $(readlink /usr/local/adtpro/disks/Virtual${drive}.po)" + echo "virtual drive $(( drive ? 2 : 1 )): $(readlink /usr/local/adtpro/disks/Virtual${drive}.po)" else - if [[ $1 == "-f" ]]; then - shift - skipWarning=1 - fi - if [[ ! -f $1 ]]; then - echo "Image file '$1' was not found." - elif [[ -f /usr/local/adtpro/disks/Virtual${drive}.po && ! -L /usr/local/adtpro/disks/Virtual${drive}.po ]]; then - echo "/usr/local/adtpro/disks/Virtual${drive}.po is an actual disk image" - echo "file, not a symbolic link. Please move or rename it, and try again." - else - rm /usr/local/adtpro/disks/Virtual${drive}.po &>/dev/null; - [[ ${1:0:1} != "/" ]] && pwd="$PWD/"; - ln -s "$pwd$1" /usr/local/adtpro/disks/Virtual${drive}.po - [[ $drive ]] && VSD2="$pwd$1" || VSD1="$pwd$1" - if [[ $(ps aux | grep [A]DTPro) ]]; then - if [[ ! $skipWarning ]]; then - echo "Please make sure you're not writing to either virtual drive on your Apple II." - echo -n " Press return when ready, or control-C to cancel..." - read - fi - sudo pkill -f [A]DTPro - while [[ $(ps aux | grep [A]DTPro) ]]; do sleep 1; done - /usr/local/bin/adtpro-start - fi - fi + if [[ $1 == "-f" ]]; then + shift + skipWarning=1 + fi + if [[ ! -f $1 ]]; then + echo "Image file '$1' was not found." + elif [[ -f /usr/local/adtpro/disks/Virtual${drive}.po && ! -L /usr/local/adtpro/disks/Virtual${drive}.po ]]; then + echo "/usr/local/adtpro/disks/Virtual${drive}.po is an actual disk image" + echo "file, not a symbolic link. Please move or rename it, and try again." + else + rm /usr/local/adtpro/disks/Virtual${drive}.po &>/dev/null; + [[ ${1:0:1} != "/" ]] && pwd="$PWD/"; + ln -s "$pwd$1" /usr/local/adtpro/disks/Virtual${drive}.po + [[ $drive ]] && VSD2="$pwd$1" || VSD1="$pwd$1" + if [[ $(ps aux | grep [A]DTPro) ]]; then + if [[ ! $skipWarning ]]; then + echo "Please make sure you're not writing to either virtual drive on your Apple II." + echo -n " Press return when ready, or control-C to cancel..." + read + fi + sudo pkill -f [A]DTPro + while [[ $(ps aux | grep [A]DTPro) ]]; do sleep 1; done + /usr/local/bin/adtpro-start + fi + fi fi unset drive