Merge branch 'master' into jessie

This commit is contained in:
T. Joseph Carter 2016-01-11 06:11:17 -08:00
commit f97f6b1b2a
34 changed files with 0 additions and 7538 deletions

View File

@ -1,16 +0,0 @@
# Ivan Drucker's A2CLOUD setup
A2CLOUD grew up alongside A2SERVER, yet it ends up being substantially
different in many ways. Eseentially, it looks like Ivan wrote most of the
HTML for A2SERVER first, but had to rewrite the scripts a few times to be more
legible and robust.
A2CLOUD, by contrast, had a wordpress blog category turned into a user guide.
The HTML was more "proper" by modern standards (and HTML5-based rather than
HTML 3.2), but the scripts seem to be older and less refined. This can be
likely attributed to A2SERVER requiring more debugging and therefore more
effort to flesh out quickly bodged scripts into readable, debuggable pieces.
There's less documentation here to archive than there is the original A2CLOUD
setup that began this repository, but having it helps inform some design
decisions. So it's included here for completeness.

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
#!/bin/bash
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
fi
if [[ $1 == "-n" && $2 ]]; then
nickname=$2
elif [[ $1 == "-n" ]]; then
nickname="0"
elif [[ -f ~/.irssi/a2c.nickname ]]; then
nickname=$(cat ~/.irssi/a2c.nickname)
else
nickname=
fi
while [[ ! $nickname || ! $(grep -i '^[a-z_\-\\^{}|`][a-z0-9_\-\\^{}|`]*$' <<< $nickname) ]]; do
echo -n "Enter a nickname for chat (to change later, use 'a2chat -n'): "
read
nickname=$REPLY
done
mkdir -p ~/.irssi
echo $nickname > ~/.irssi/a2c.nickname
if [[ -f ~/.irssi/startup ]]; then
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
fi
irssi -n $nickname
rm ~/.irssi/startup &> /dev/null
if [[ -f ~/.irssi/startup.orig ]]; then
mv ~/.irssi/startup.orig ~/.irssi/startup
fi
rm ~/.irssi/config &> /dev/null
if [[ -f ~/.irssi/config.orig ]]; then
mv ~/.irssi/config.orig ~/.irssi/config
fi

View File

@ -1,87 +0,0 @@
# A2CLOUD aliases:
alias a2cloud-setup='wget -qO /tmp/a2cloud-setup ivanx.com/a2cloud/setup/; source /tmp/a2cloud-setup'
alias a2cloud-help='(IFS=""; while read thisLine; do [[ ${#thisLine} -eq 0 ]] && echo || echo "$(tput bold)${thisLine%% *}$(tput sgr0) ${thisLine#* }"; done < /usr/local/etc/a2cloud-help.txt | more)'
alias a2cloud-version='cat /usr/local/etc/A2CLOUD-version'
alias a2cloud-update='a2cloud-setup'
alias system-shutdown='sudo shutdown -h now'
alias system-restart='sudo shutdown -r now'
alias raspi-config='[[ -f /usr/bin/raspi-config ]] && sudo /usr/bin/raspi-config || echo "raspi-config not found. Are you using a Raspberry Pi with Raspbian?"'
alias appleiipi-update="sudo apt-get -y update && sudo apt-get -y --force-yes install a2pi apple2user gsport"
alias raspbian-update='wget -qO /tmp/raspbian-update ivanx.com/a2cloud/setup/raspbian-update.txt; source /tmp/raspbian-update'
alias rasppleii-update='raspbian-update a2cloud a2server'
alias welcome-message-edit='sudo nano /etc/motd'
alias showip='ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1'
alias showmac='ifconfig eth0 | grep "HWaddr" | cut -dH -f2 | cut -c7-23'
alias showip-wifi='ifconfig wlan0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1'
alias showmac-wifi='ifconfig wlan0 | grep "HWaddr" | cut -dH -f2 | cut -c7-23'
alias ifreset='sudo rm /etc/udev/rules.d/70-persistent-net.rules; echo Interfaces removed. You should system-restart now.'
alias adtpro-stop='sudo pkill -f [A]DTPro'
alias adtpro-restart='sudo pkill -f [A]DTPro; while [[ $(ps aux | grep [A]DTPro) ]]; do sleep 1; done; adtpro-start'
alias usblogin-off='sudo sed -i "s/^\(.*-scanttyUSB\)/#\1/" /etc/inittab; sudo init q; sudo pkill -f [g]etty'
alias usblogin-on='sudo sed -i "s/^#\(.*-scanttyUSB\)/\1/" /etc/inittab; sudo init q'
alias term='source term'
alias vsd1='source /usr/local/bin/vsd -d1'
alias vsd2='source /usr/local/bin/vsd -d2'
forfloppy () { [[ $1 ]] && { mv "$1" /usr/local/adtpro/disks && echo "moved $1 to /usr/local/adtpro/disks" || echo "Unsuccessful. $1 was not moved."; } || echo "Usage: forfloppy imageFileName"; }
alias vsdsync='adtpro-restart'
alias nulib=nulib2
alias a2cat='acmd -l'
VSD1=$(readlink /usr/local/adtpro/disks/Virtual.po)
VSD2=$(readlink /usr/local/adtpro/disks/Virtual2.po)
ADTDISKS=/usr/local/adtpro/disks; A2DISKS=/usr/local/adtpro/disks
A2CLOUD=/usr/local/adtpro/disks/A2CLOUD.HDV
GSDISKS=/usr/local/share/gsdisks
GSHD=/usr/local/share/gsdisks/gsoshd.hdv
ttytter () { ( ansi=; seven=; [[ $(grep ttyUSB <<< $myTTY) || $(grep ttyAMA <<< $myTTY) ]] && { seven="-seven"; [[ $TERM=="ansi" || $TERM=="pcansi" ]] && ansi="-ansi"; }; [[ -f /usr/bin/ttytter ]] && /usr/bin/ttytter -ssl $seven $ansi $@ || /usr/local/bin/ttytter -ssl $seven $ansi $@ ); }
alias raspple-update='rasppleii-update'
alias rasappleii-update='rasppleii-update'
alias rasapple-update='rasppleii-update'

View File

@ -1,87 +0,0 @@
A2CLOUD commands:
(note : new commands may be added; use a2cloud-setup to refresh)
a2cloud-help : show this list of commands
a2cloud-version : see installed version of A2CLOUD
a2cloud-update : update A2CLOUD, or add features
system-shutdown : shut down the A2CLOUD machine (or VM)
system-restart : shut down and restart the A2CLOUD machine (or VM)
Raspberry Pi commands, if you're using one:
raspi-config : configure Raspberry Pi
appleiipi-update : update Apple II Pi and GSport
raspbian-update : update Raspbian operating system
rasppleii-update : update Raspbian OS, A2CLOUD, A2SERVER, Apple II Pi
Apple II Pi: for help, visit http://schmenk.is-a-geek.com/wordpress
welcome-message-edit : change the welcome message
showip : show the current ethernet IP address of the server
showmac : show the MAC (Ethernet hardware) address of the server
showip-wifi : show the current wifi IP address of the server
showmac-wifi : show the MAC (wifi hardware) address of the server
ifreset : reset all network interfaces (requires restart)
adtpro-stop : stop the ADTPro service
adtpro-start : start the ADTPro service
(note: autostarts on appearance of eligible USB-to-serial adapter)
adtpro-restart : restart the ADTPro service
usblogin-off : disable shell login for USB-to-serial adapter
usblogin-on : enable shell login with USB-to-serial adapter on upper
USB port or hub attached to it, or highest-numbered port on hub
attached to lower USB port
term [-d] mono : use VT-100 (mostly monochrome) emulation in serial
shell login for ProTERM, Spectrum, Z-Link, etc. (-d sets default)
term [-d] color : use ANSI color and PC graphic text in serial shell
login for Spectrum or other PC-ANSI terminal (-d sets default)
baud : show or set serial port shell baud rate
screen : switch between multiple terminal screens
vsd1 : show or set the disk image assigned to virtual drive 1
vsd2 : show or set the disk image assigned to virtual drive 2
forfloppy : move the disk image to the ADTPro disk images folder
(/usr/local/adtpro/disks) in preparation for transfer
vsdsync : update ADTPro server with the current virtual drive images
nulib2 : create, extract, and work with NuFX (ShrinkIt) archive files
sciibin : decode BinSCII file (they start with 'FiLeStArTfIlEsTaRt')
unblu/usq/unbit/unexec : decode Binary II, Squeezed, Executioner,
or monitor hex entry EXEC file (old Apple II distribution formats)
unar : extract non-Apple II archive files (multiformat)
lsar : list contents of non-Apple II archive files (multiformat)
a2cat: catalog Apple II disk image (any format)
acmd : do stuff with files inside Apple II disk images
mkpo : make blank ProDOS disk image file
dos2pro: copy files from DOS 3.3 disk image to ProDOS disk image
dopo : convert DOS-ordered disk image to ProDOS, or vice-versa
cppo : catalog and copy files from ProDOS image file (slow, but works)
shk2image : extract files from ShrinkIt archive to disk image file
environment variables :
$VSD1 = disk image currently "inserted" in virtual drive 1
$VSD2 = disk image currently "inserted" in virtual drive 2
$ADTDISKS = ADTPro disks directory (/usr/local/adtpro/disks)
$A2CLOUD = 800K A2CLOUD disk (/usr/local/adtpro/disks/A2CLOUD.HDV)
$GSDISKS = GSport/KEGS disks directory (/usr/local/share/gsdisks)
$GSHD = GSport/KEGS hard drive (/usr/local/share/gsdisks/gsoshd.hdv)
internet tools:
ftp : connect to an FTP site (command line operation)
cftp : connect to an FTP site (full screen operation)
lynx : browse the web (in text only, of course)
links : browse the web (alternative to lynx; press ESC for menu)
wget : download a single URL from an FTP or web site
irssi : IRC chat (general purpose)
a2chat : IRC chat (automatically opens to Apple II channel)
a2news : read and post on Usenet discussions (default Apple II topics)
ttytter : tweet like there's no tomorrow
emulators:
gsport : GSport Apple IIgs emulator
kegs : KEGS Apple IIgs emulator
linapple : LinApple Apple IIe emulator

View File

@ -1,34 +0,0 @@
source /usr/local/etc/a2cloud-aliases
if [[ -f /usr/local/java/bin/java ]]; then
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
elif [[ -f /usr/lib/jvm/java-8-oracle/bin/java ]]; then # webupd8
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
elif [[ -f /usr/lib/jvm/jdk-7-oracle-armhf/bin/java ]]; then # RPi
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
fi
[[ ! $(grep java <<< $PATH) ]] && PATH=$PATH:$JAVA_HOME/bin
if [[ -f /usr/local/etc/a2cloud-lang ]]; then
lang8bit=$(cat /usr/local/etc/a2cloud-lang)
else
lang8bit=C
fi
if [[ ${TERM:0:6} == "screen" ]]; then
myTTY=$(ps hp $(ps hp $(ps hp $$ -o ppid) -o ppid) -o tty)
else
myTTY=$(tty)
export ttyTERM="$TERM"
fi
if [[ $(grep ttyUSB <<< $myTTY) || $(grep ttyAMA <<< $myTTY) ]]; then
LANG=$lang8bit
fi
if [[ ${TERM:0:6} == "screen" ]]; then
TERM=$ttyTERM
fi

View File

@ -1,59 +0,0 @@
#!/bin/bash
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
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
fi
while [[ $1 == "-s" || $1 == "-m" ]]; do
if [[ $1 == "-s" && $2 ]]; then
nntpServer=$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
fi
if [[ $nntpServer || ! -f ~/.tin/nntp.server ]]; then
[[ ! $nntpServer ]] && nntpServer="$defaultNNTP"
echo "$nntpServer" > ~/.tin/nntp.server
else
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
fi
NNTPSERVER=$nntpServer tin -r "$@"

View File

@ -1,151 +0,0 @@
#!/bin/bash
decToHex () {
# converts single-byte decimal value to hexadecimal equivalent
# arg: decimal value from 0-255
# out: two-digit hex value from 00-FF
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
[[ $arg1 ]] || return 11
[[ $2 ]] && return 8
[[ ( $(printf %d "$arg1" 2> /dev/null) == $arg1 ) \
&& ( $arg1 -ge 0 ) && ( $arg1 -le 255 ) ]] || return 21
# args are valid
printf %02X "$arg1"
}
echoerr() {
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 <imagename> <filename> [<outputFilename>] copy filename out of any"
echoerr " disk image. Using - for outputFilename will copy to stdout."
echoerr "-e <imagename> <filename> [<outputFilename>] like -g, with conversion"
echoerr " to modern file format if possible."
echoerr "-p <imagename> <filename> [[$|0x]<type>] [[$|0x]<auxtype>] copy filename"
echoerr " into ProDOS disk image. <type> is either three-letter or numeric"
echoerr " ProDOS file type (BIN if omitted). Will read from stdin if supplied."
echoerr " ProDOS subdirectories in <filename> will be created if needed."
echoerr "-c <filename> <imagename> [[$|0x]<type>] [[$|0x]<auxtype>] synonym for -p"
echoerr " with filename and imagename reversed."
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
}
arg1=$1
acmdStdErr="/tmp/acmd_$RANDOM$RANDOM"
[[ -f /usr/local/adtpro/adtpro.sh ]] && adtPath="/usr/local/adtpro" || adtPath=$(ls -1d /Applications/ADTPro* | head -1);
if [[ ! $2 || $arg1 == "-h" ]]; then
java -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar 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)"
fi
if [[ ( $arg1 == "-p" || $arg1 == "-c" || $arg1 == "-g" || $arg1 == "-e" ) && $2 && $3 ]]; then
getArg=
if [[ $arg1 == "-p" ]]; then
prodosArg="$3"
imageArg="$2"
elif [[ $arg1 == "-c" ]]; then
prodosArg="$2"
imageArg="$3"
elif [[ $arg1 == "-g" || $arg1 == "-e" ]]; then
fileArg="$3"
imageArg="$2"
getArg="$arg1"
else
exit 2;
fi
shift
if [[ $getArg ]]; then # get file
outFile=
[[ $3 && $3 != "-" ]] && outFile="$3"
[[ ! $3 ]] && outFile="${2##*/}"
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar $getArg "$imageArg" "$fileArg" $outFile 2> $acmdStdErr
else # put file
# test ProDOS name legitimacy
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"
# process filetype
[[ ${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=$(decToHex $ftArg | tr [:upper:] [:lower:])
fi
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;
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"
# 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; }
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -d "$imageArg" $prodosPath &> /dev/null
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -p "$imageArg" $prodosPath $ft $auxType < $prodosArg 2> $acmdStdErr
else
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -d "$imageArg" $prodosPath &> /dev/null
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -p "$imageArg" $prodosPath $ft $auxType 2> $acmdStdErr
fi
fi
else
imageArg="$2"
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar "$@" 2> $acmdStdErr
fi
helpExit

View File

@ -1,33 +0,0 @@
#!/bin/bash
# don't do anything if ADTPro is already running
if [[ $(ps aux | grep [A]DTPro) ]]; then
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
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

View File

@ -1,141 +0,0 @@
#!/bin/bash
# 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')
#
# 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
#
# Set default ADTPRO_HOME to be the fully qualified
# current working directory.
#export ADTPRO_HOME="`dirname \"$0\"`"
#cd "$ADTPRO_HOME"
#export ADTPRO_HOME=`pwd`
# Uncomment and modify one or both of the lines below if you
# want to specify a particular location for Java or ADTPro.
# NOTE: be sure to include a trailing slash on MY_JAVA_HOME,
# but not on ADTPRO_HOME.
#
# export MY_JAVA_HOME=/usr/local/java/bin/
# export ADTPRO_HOME=~/myuser/adtpro
usageExit () {
echo "usage:" 1>&2
echo "adtpro.sh [headless] [serial|ethernet|audio|localhost] [serialPortName]" 1>&2
exit 1
}
export ADTPRO_HOME=/usr/local/adtpro
cd "$ADTPRO_HOME"
OS=`uname`
OS_ARCH=`uname -m`
[[ $1 == "headless" ]] && { headless=1; shift; } || headless=
if [[ $1 && ( $1 != "serial" && $1 != "ethernet" && $1 != "audio" && $1 != "localhost" ) ]]; then
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
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/' 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"
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
fi
# For Solaris, use this:
if [ "$OS" = "SunOS" ]; then
export RXTXLIB=lib/rxtx/rxtx-2.2pre2-local/sparc-sun-solaris2.10-32
fi
# Set up the library location.
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
fi
if [[ $serialPortName && $(ps aux | grep "/sbin/getty.*$serialPortName") ]]; then
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..."
fi
sleep 30

View File

@ -1,29 +0,0 @@
#!/bin/bash
if [[ $1 == "-d" ]]; then
shift
setgetty=1
else
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'
else
if [[ $setgetty ]]; then
sudo sed -i "s/ttyAMA0 .* /ttyAMA0 $1 /" /etc/inittab;
sudo sed -i "s/ttyAMA0,[0-9]*/ttyAMA0,$1/g" /boot/cmdline.txt;
sudo sed -i "s/\(ttyUSB.*\) .* /\1 $1 /g" /etc/inittab;
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)"
echo -e "$(tput bold)default speed at login: $(grep ttyUSB /etc/inittab | sed 's/^.*ttyUSB[^ ]* \(.*\) .*$/\1/') baud$(tput sgr0)"

View File

@ -1,761 +0,0 @@
#!/bin/bash
# need to test:
# does both -e and -ad work as expected? what if you do both?
#--ID-bashbyter routines
decToHex () {
# converts single-byte decimal value to hexadecimal equivalent
# arg: decimal value from 0-255
# out: two-digit hex value from 00-FF
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
[[ $1 ]] || return 11
[[ $2 ]] && return 8
[[ ( $(printf %d "$1" 2> /dev/null) == $1 ) \
&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21
# args are valid
printf %02X "$1"
}
hexToDec () {
# converts single-byte hexadecimal value to decimal equivalent
# arg: two-digit hex value from 00-FF
# out: decimal value
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
[[ $1 ]] || return 11
[[ $2 ]] && return 8
[[ ${#1} -eq 2 ]] || return 21
[[ $(printf %02X "0x$1" 2> /dev/null) == \
$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21
# args are valid
printf %d "0x$1"
}
hexToBin () {
# converts single-byte hexadecimal value to binary string
# arg: two-digit hex value from 00-FF
# out: binary string value
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
[[ $1 ]] || return 11
[[ $2 ]] && return 8
[[ ${#1} -eq 2 ]] || return 21
[[ $(printf %02X "0x$1" 2> /dev/null) == \
$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21
# args are valid
for n in 0 1; do
if [[ ${1:n:1} == "0" ]]; then b="0000"
elif [[ ${1:n:1} == "1" ]]; then b="0001"
elif [[ ${1:n:1} == "2" ]]; then b="0010"
elif [[ ${1:n:1} == "3" ]]; then b="0011"
elif [[ ${1:n:1} == "4" ]]; then b="0100"
elif [[ ${1:n:1} == "5" ]]; then b="0101"
elif [[ ${1:n:1} == "6" ]]; then b="0110"
elif [[ ${1:n:1} == "7" ]]; then b="0111"
elif [[ ${1:n:1} == "8" ]]; then b="1000"
elif [[ ${1:n:1} == "9" ]]; then b="1001"
elif [[ ${1:n:1} == "A" ]]; then b="1010"
elif [[ ${1:n:1} == "B" ]]; then b="1011"
elif [[ ${1:n:1} == "C" ]]; then b="1100"
elif [[ ${1:n:1} == "D" ]]; then b="1101"
elif [[ ${1:n:1} == "E" ]]; then b="1110"
elif [[ ${1:n:1} == "F" ]]; then b="1111"
fi
echo -n $b
done
}
binToDec () {
# converts single-byte binary string (8 bits) value to decimal
# warning: no error checking
# arg: binary string up to 8 bits
# out: decimal value
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
}
binToHex () {
# converts single-byte binary string (8 bits) value to hex
# warning: no error checking
# arg: binary string up to 8 bits
# out: hex value
echo $(decToHex $(binToDec $1))
}
charToDec () {
# converts single character to corresponding decimal value
# stdin OR arg: one character
# [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)]
# out: decimal value from 0-255
#exit: 8=extraneous arg, 9=invalid stdin,
# 11=missing stdin/arg, 21=invalid arg
[[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; }
[[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; }
# arg/stdin is potentially valid (additional check below)
charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)"
[[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 ))
# above line verifies that arg/stdin is valid
[[ ${#charX} -ne 2 ]] && { echo -n 0; return 0; }
echo -n "${charX:0:1}" | od -t u1 | \
head -1 | sed 's/[0\ ]*//' | tr -d ' \n'
}
charToHex () {
# converts single character to corresponding hexadecimal value
# stdin OR arg: one character
# [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)]
# out: decimal value from 0-255
#exit: 8=extraneous arg, 9=invalid stdin,
# 11=missing stdin/arg, 21=invalid arg
[[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; }
[[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; }
# arg/stdin is potentially valid (additional check below)
charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)"
[[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 ))
# above line verifies that stdin/arg is valid
[[ ${#charX} -ne 2 ]] && { echo -n "00"; return 0; }
printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \
head -1 | sed 's/[0\ ]*//' | tr -d ' \n')
}
decToChar () {
# converts single-byte decimal value to equivalent character
# arg: decimal number from 0-255
# out: one character
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
[[ $1 ]] || return 11
[[ $2 ]] && return 8
[[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \
&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21
# args are valid
echo -n -e "\x$(printf %02X "$1")"
}
hexToChar () {
# converts single-byte hexadecimal value to corresponding character
# arg: two-digit hexadecimal number from 00-FF
# out: one character
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
[[ $1 ]] || return 11
[[ $2 ]] && return 8
[[ ${#1} -eq 2 ]] || return 21
[[ $(printf %02X "0x$1" 2> /dev/null) == \
$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21
# args are valid
echo -n -e "\x$1"
}
readchars () {
# read one or more characters from a file
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# arg3: (optional) # of chars to read (default is until end of file)
# 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
}
readcharDec () {
# read one character from file & convert to equivalent decimal value
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# 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'
}
readcharHex () {
# read one character from file & convert to corresponding hex value
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# 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')
}
### 2-15-11 above tested on OS X and Linux
writechars () {
# write one or more characters (bytes) to file
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before writing)
# arg3 OR stdin: sequence of characters
# [stdin required if writing NUL (0) or trailing LF (0x0A) chars]
# out: nothing
# exit: 8=extraneous arg, 11=missing arg1,
# 13=missing stdin/arg3, 22=invalid arg2
[[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; }
[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \
( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } }
[[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; }
[[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; }
# args are valid
if [[ -t 0 ]]; then
echo -n "$3" | \
dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
else
dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
fi
}
writecharDec () {
# write corresponding character of single-byte decimal value into file
# arg1: filename
# arg2: offset (# of bytes to skip before writing)
# arg3: decimal number from 0-255
# exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2,
# 13=missing arg3, 22=invalid arg2, 23=invalid arg3
# out: nothing
[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13
[[ $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
# args are valid
echo -n -e "\x$(printf %02X "$3")" | \
dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
}
writecharHex () {
# write corresponding character of single-byte hex value into file
# arg1: filename
# arg2: offset (# of bytes to skip before writing)
# arg3: two-digit hexadecimal number from 00-FF
# 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
[[ $(printf %02X "0x$3" 2> /dev/null) == \
$(echo -n "$3" | tr [a-z] [A-Z]) ]] || return 23
# args are valid
echo -n -e "\x$3" | \
dd of="$1" bs=1 seek=$2 conv=notrunc 2> /dev/null
}
writecharsHex () {
# write corresponding characters of hex values into file
# arg1: filename
# arg2: offset (# of bytes to skip before writing)
# arg3: string of two-digit hexadecimal numbers from 00-FF, period delimited (not checked!)
# 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
}
# ---
pdosDateToUnixDate () {
# input: ProDOS date/time bit sequence string in format:
# yyyyyyymmmmddddd000hhhhh00mmmmmm
# output: seconds since Unix epoch (1-Jan-1970), or current date/time if no ProDOS date
year=$(( $(binToDec ${1:0:7}) + 1900 ))
(( $year < 1940 )) && (( year+=100 ))
month=$(binToDec ${1:7:4})
day=$(binToDec ${1:11:5})
hour=$(binToDec ${1:19:5})
minute=$(binToDec ${1:26:6})
date -d "$year-$month-$day $hour:$minute:00" "+%s" 2> /dev/null
}
unixDateToADDate () {
# 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 four period-delimited hex bytes (big endian)
adDate=$(( $1 - 946684800 ));
if (( $adDate < 0 )); then
(( adDate+=4294967296 )) # to get negative hex number
fi
adDateHex=$(printf %08X $adDate)
echo "${adDateHex:0:2}.${adDateHex:2:2}.${adDateHex:4:2}.${adDateHex:6:2}"
}
# cppo support routines:
# arg1: directory block
# arg2: file index (if applicable)
# arg3: directory chunk # (if applicable)
# returns byte position in disk image file
getStartPos () {
echo $(( ($1 * 512) + (39 * ( ($2 + ($2>11) ) % 13) ) + ( ($2>11) ? 4 : 43) ))
}
getStorageType () {
start=$(getStartPos $1 $2)
firstByte=$(readcharDec "$image" $start)
echo $(($firstByte/16))
}
getFileName () {
start=$(getStartPos $1 $2)
firstByte=$(readcharDec "$image" $start)
entryType=$(($firstByte/16))
nameLength=$(($firstByte-$entryType*16))
echo $(readchars "$image" $(($start+1)) $nameLength)
}
getFileType () {
start=$(getStartPos $1 $2)
echo $(readcharHex "$image" $(($start+16)) )
}
getKeyPointer () {
start=$(getStartPos $1 $2)
echo $(( $(readcharDec "$image" $(($start+17)) ) + \
$(readcharDec "$image" $(($start+18)) ) * 256 ))
}
getFileLength () {
start=$(getStartPos $1 $2)
echo $(( $(readcharDec "$image" $(($start+21)) ) + \
$(readcharDec "$image" $(($start + 22)) ) * 256 + \
$(readcharDec "$image" $(($start + 23)) ) * 65536 ))
}
getAuxType () {
start=$(getStartPos $1 $2)
echo $(readcharHex "$image" $(($start+32)) ).$(readcharHex "$image" $(($start+31)) )
}
getCreationDate () {
#outputs prodos creation date/time as Unix time (seconds since Jan 1 1970 GMT)
#or "NONE" if there is none
start=$(getStartPos $1 $2)
pdosDate=\
$( hexToBin $(readcharHex "$image" $(($start+25)) ) )\
$( hexToBin $(readcharHex "$image" $(($start+24)) ) )\
$( hexToBin $(readcharHex "$image" $(($start+27)) ) )\
$( hexToBin $(readcharHex "$image" $(($start+26)) ) )
pdosDateToUnixDate $pdosDate || echo "NONE"
}
getModifiedDate () {
#outputs prodos modified date/time as Unix time (seconds since Jan 1 1970 GMT)
start=$(getStartPos $1 $2)
pdosDate=\
$( hexToBin $(readcharHex "$image" $(($start+34)) ) )\
$( hexToBin $(readcharHex "$image" $(($start+33)) ) )\
$( hexToBin $(readcharHex "$image" $(($start+36)) ) )\
$( hexToBin $(readcharHex "$image" $(($start+35)) ) )
pdosDateToUnixDate $pdosDate || echo "NONE"
}
#isLocked () {
# #returns 1 (meaning locked) if bit 7, 6, or 1 are clear; otherwise returns 0
# start=$(getStartPos $1 $2)
# access=$( $hexToBin $(readcharHex "$image" $(($start+30)) ) )
# if [[ ${access:0:1} != "1" || ${access:1:1} != "1" || ${access:7:1} != "1" ]]; then
# echo 1
# else
# echo 0
# fi
#}
getVolumeName () {
echo $(getWorkingDirName 2)
}
getWorkingDirName () {
start=$(( $1 * 512 ))
firstByte=$(readcharDec "$image" $(($start+4)) )
entryType=$(($firstByte/16))
nameLength=$(($firstByte-$entryType*16))
echo $(readchars "$image" $(($start+5)) $nameLength)
}
getDirEntryCount () {
start=$(( $1 * 512 ))
echo $(( $(readcharDec "$image" $(($start+37)) ) + \
$(readcharDec "$image" $(($start+38)) ) * 256 ))
}
getDirNextChunkPointer () {
start=$(( $1 * 512 ))
echo $(( $(readcharDec "$image" $(($start+2)) ) + \
$(readcharDec "$image" $(($start+3)) ) * 256 ))
}
# -- script begins in earnest here
copyFile () {
activeFileBytesCopied=0
storageType=$(getStorageType $1 $2)
keyPointer=$(getKeyPointer $1 $2)
fileLen=$(getFileLength $1 $2)
if (( $storageType == 1 )); then #seedling
copyBlock $keyPointer $fileLen
elif (( $storageType == 2 )); then #sapling
processIndexBlock $keyPointer
elif (( $storageType == 3 )); then #tree
processMasterIndexBlock $keyPointer
elif (( $storageType == 5)); then #forked fileLen
processForkedFile $keyPointer
fi
}
copyBlock () {
#arg1: block to copy
#arg2: bytes to write (should be 512, unless final block with less than 512 bytes)
#echo $1 $2 $activeFileBytesCopied
(( $1 == 0 )) && blockSource=/dev/zero || blockSource="$image"
if (( $resourceFork > 0 )); then
[[ $AD ]] && dd if="$blockSource" of="$ADdir/$targetName" bs=1 count=$2 skip=$(($1*512)) seek=$(($activeFileBytesCopied + 741)) 2> /dev/null
[[ $EX ]] && dd if="$blockSource" of="$targetDir/${eTargetName}r" bs=1 count=$2 skip=$(($1*512)) seek=$activeFileBytesCopied 2> /dev/null
else
dd if="$blockSource" of="$targetDir/$targetName" bs=1 count=$2 skip=$(($1*512)) seek="$activeFileBytesCopied" 2> /dev/null
fi
activeFileBytesCopied=$(( $activeFileBytesCopied + $2 ))
}
processDir () {
# arg1: dirBlock
# arg2/3/4/5: for non-key chunks: entryCount, entry#,
# workingDirName, processedEntryCount
local entryCount
local e
local pe
local workingDirName
if [[ $2 ]]; then
entryCount=$2
e=$3
workingDirName=$4
pe=$5
else
e=0
pe=0
entryCount=$(getDirEntryCount $1)
workingDirName=$(getWorkingDirName $1)
DIRPATH="$DIRPATH/$workingDirName"
if [[ $PDOSPATH_INDEX ]]; then
if (( $PDOSPATH_INDEX == 1 )); then
if [[ "/$PDOSPATH_SEGMENT" != "$DIRPATH" ]]; then
echo "ProDOS volume name does not match disk image."
exit 2
else
(( PDOSPATH_INDEX++ ))
PDOSPATH_SEGMENT=${PDOSPATH[PDOSPATH_INDEX]}
fi
fi
else
echo $DIRPATH
fi
fi
while (( $pe < $entryCount )); do
if (( $(getStorageType $1 $e) > 0 )); then
processEntry $1 $e
(( pe++ ))
fi
(( e++ ))
(( ($e + ( $e>11 ) ) % 13 )) || { processDir $(getDirNextChunkPointer $1) $entryCount $e $workingDirName $pe; break; }
done
}
processEntry () {
#echo $(getFileName $1 $2) $(getStorageType $1 $2) $(getFileType $1 $2) $(getKeyPointer $1 $2) $(getFileLength $1 $2) $(getAuxType $1 $2) $(getCreationDate $1 $2) $(getModifiedDate $1 $2)
activeFileName=$(getFileName $1 $2)
activeFileSize=$(getFileLength $1 $2)
[[ $PDOSPATH_INDEX ]] || echo " $activeFileName"
if [[ ( ! $PDOSPATH_INDEX ) || ( $activeFileName == $PDOSPATH_SEGMENT ) ]]; then
if (( $(getStorageType $1 $2) == 13 )); then
[[ $PDOSPATH_INDEX ]] || targetDir="$targetDir/$activeFileName"
ADdir="$targetDir/.AppleDouble"
[[ $DIR || -d $targetDir ]] || mkdir -p $targetDir
[[ $DIR || ! $AD || -d $ADdir ]] || mkdir -p $ADdir
if [[ $PDOSPATH_SEGMENT ]]; then
(( PDOSPATH_INDEX++ ))
PDOSPATH_SEGMENT=${PDOSPATH[PDOSPATH_INDEX]}
fi
processDir $(getKeyPointer $1 $2)
DIRPATH=${DIRPATH%/*}
[[ $PDOSPATH_INDEX ]] || targetDir="$targetDir/.."
ADdir="$targetDir/.AppleDouble"
else
[[ $DIR ]] && return
[[ $targetName ]] || targetName=$activeFileName
[[ $EX ]] && eTargetName="$targetName#$(getFileType $1 $2 | tr [:upper:] [:lower:])$(getAuxType $1 $2 | sed 's/\.//' | tr [:upper:] [:lower:])"
touch "$targetDir/$targetName"
makeADfile
copyFile $1 $2
creationDate=$(getCreationDate $1 $2);
modifiedDate=$(getModifiedDate $1 $2);
if [[ $creationDate == "NONE" && $modifiedDate != "NONE" ]]; then
creationDate=$modifiedDate
elif [[ $creationDate != "NONE" && $modifiedDate == "NONE" ]]; then
modifiedDate=$creationDate
elif [[ $creationDate == "NONE" && $modifiedDate == "NONE" ]]; then
creationDate=$(date "+%s")
modifiedDate=$creationDate
fi
if [[ $AD ]]; then # AppleDouble
# set dates
ADfilePath="$ADdir/$targetName"
writecharsHex "$ADfilePath" 637 $(unixDateToADDate $creationDate).$(unixDateToADDate $modifiedDate)
writecharHex "$ADfilePath" 645 80
writecharHex "$ADfilePath" 649 80
#set type/creator
writechars "$ADfilePath" 653 "p"
writecharsHex "$ADfilePath" 654 "$(getFileType $1 $2).$(getAuxType $1 $2)"
writechars "$ADfilePath" 657 "pdos"
fi
touch -d @$modifiedDate "$targetDir/$targetName"
if [[ $EX ]]; then # extended name
mv "$targetDir/$targetName" "$targetDir/$eTargetName"
[[ -f $targetDir/${eTargetName}r ]] && touch -d @$modifiedDate "$targetDir/${eTargetName}r"
fi
[[ $PDOSPATH_SEGMENT ]] && syncExit
targetName=
fi
#else
#echo "$activeFileName doesn't match $PDOSPATH_SEGMENT"
fi
}
processForkedFile () {
# finder info except type/creator
fInfoA_entryType=$(readcharDec "$image" 9)
fInfoB_entryType=$(readcharDec "$image" 27)
if (( $fInfoA_entryType==1 )); then
readchars "$image" 18 8 | writechars "$image" 661
elif (( $fInfoA_entryType==2 )); then
readchars "$image" 10 16 | writechars "$image" 669
fi
if (( $fInfoB_entryType==1 )); then
readchars "$image" 36 8 | writechars "$image" 661
elif (( $fInfoB_entryType==2 )); then
readchars "$image" 28 16 | writechars "$image" 669
fi
for f in 0 256; do
resourceFork=$f
activeFileBytesCopied=0
forkStart=$(( ($1 * 512) )) # start of Forked File key block
# echo --$forkStart
forkStorageType=$(readcharDec "$image" $(($forkStart+$f+0)) )
forkKeyPointer=$(( $(readcharDec "$image" $(($forkStart+$f+1)) ) + \
$(readcharDec "$image" $(($forkStart+$f+2)) ) * 256 ))
forkFileLen=$(( $(readcharDec "$image" $(($forkStart+$f+5)) ) + \
$(readcharDec "$image" $(($forkStart+$f+6)) ) * 256 + \
$(readcharDec "$image" $(($forkStart+$f+7)) ) * 65536 ))
activeFileSize=$forkFileLen
if (( $resourceFork > 0 )); then
rsrcForkLenHex=$(readcharHex "$image" $(($forkStart+$f+7)) ).\
$(readcharHex "$image" $(($forkStart+$f+6)) ).\
$(readcharHex "$image" $(($forkStart+$f+5)) )
# echo ">>>$rsrcForkLenHex"
echo " [resource fork]"
[[ $AD ]] && writecharsHex "$ADdir/$targetName" 35 "$rsrcForkLenHex"
else
echo " [data fork]"
fi
if (( $forkStorageType == 1 )); then #seedling
copyBlock $forkKeyPointer $forkFileLen
elif (( $forkStorageType == 2 )); then #sapling
processIndexBlock $forkKeyPointer
elif (( $forkStorageType == 3 )); then #tree
processMasterIndexBlock $forkKeyPointer
fi
done
# echo
resourceFork=0
}
processMasterIndexBlock() {
processIndexBlock $1 1
}
processIndexBlock () {
#arg1: indexBlock
#arg2: if set, it's a Master Index Block
local pos=0
local bytesRemaining
while (( $activeFileBytesCopied < $activeFileSize )); do
targetBlock=$(( $(readcharDec $image $(($1*512+$pos)) ) + $(readcharDec $image $(($1*512+($pos+256) )) )*256 ))
if [[ $2 ]]; then
processIndexBlock $targetBlock
else
bytesRemaining=$(($activeFileSize - $activeFileBytesCopied))
bs=$(( $bytesRemaining<512 ? $bytesRemaining : 512 ))
copyBlock $targetBlock $bs
fi
(( pos++ ))
(( $pos > 255 )) && break # go to next entry in Master Index Block (tree)
done
}
makeADfile () {
ADfilePath="$ADdir/$targetName"
[[ ! $AD ]] && return
dd if=/dev/zero of="$ADfilePath" bs=741 count=1 2> /dev/null
writecharsHex "$ADfilePath" $(hexToDec 00) "00.05.16.07.00.02.00.00" # ADv2 header
writecharsHex "$ADfilePath" $(hexToDec 18) "00.0D" # number of entries
writecharsHex "$ADfilePath" $(hexToDec 1A) "00.00.00.02.00.00.02.E5.00.00.00.00" # Resource Fork
writecharsHex "$ADfilePath" $(hexToDec 26) "00.00.00.03.00.00.00.B6.00.00.00.00" # Real Name
writecharsHex "$ADfilePath" $(hexToDec 32) "00.00.00.04.00.00.01.B5.00.00.00.00" # Comment
writecharsHex "$ADfilePath" $(hexToDec 3E) "00.00.00.08.00.00.02.7D.00.00.00.10" # Dates Info
writecharsHex "$ADfilePath" $(hexToDec 4A) "00.00.00.09.00.00.02.8D.00.00.00.20" # Finder Info
writecharsHex "$ADfilePath" $(hexToDec 56) "00.00.00.0B.00.00.02.C1.00.00.00.08" # ProDOS file info
writecharsHex "$ADfilePath" $(hexToDec 62) "00.00.00.0D.00.00.02.B5.00.00.00.00" # AFP short name
writecharsHex "$ADfilePath" $(hexToDec 6E) "00.00.00.0E.00.00.02.B1.00.00.00.04" # AFP File Info
writecharsHex "$ADfilePath" $(hexToDec 7A) "00.00.00.0F.00.00.02.AD.00.00.00.04" # AFP Directory ID
# dbd (second time) will create DEV, INO, SYN, SV~
}
syncExit () {
if [[ -d /usr/local/etc/netatalk && $AD ]]; then
echo "File(s) have been copied to the target directory. If the directory" 1>&2
echo "is shared by Netatalk, please use 'afpsync' now." 1>&2
fi
exit 0
}
usage () {
echo "usage:"
echo "copy all files: cppo [-ad|-e] imagefile targetDirectory"
echo "copy one file : cppo [-ad|-e] imagefile /FULL/PRODOS/FILE/PATH targetPath"
echo "catalog image : cppo -cat imagefile"
echo
echo "cppo copies either one file or all files from a ProDOS raw disk image"
echo "to a folder shared by Netatalk. -cat displays all files on the image."
echo "No verification or validation of the disk image is performed."
echo
echo "-ad enables creating AppleDouble header files and copying resource forks."
echo "-e appends the ProDOS type and auxtype to filenames, and copies resource"
echo " forks, so they can be preserved when added to ShrinkIt archives by"
echo " nulib2 (using its -e option)."
echo
echo "Wildcard matching (*) is not supported."
exit 1
}
# --- start
if [[ $1 == "-ad" ]]; then
AD=1
shift
fi
if [[ $1 == "-e" ]]; then
[[ $AD ]] && usage
EX=1
shift
fi
if [[ $1 == "-cat" ]]; then
DIR=1
shift
fi
[[ ( $DIR && $1 ) || ( $1 && $2 ) ]] || usage
[[ $3 && ( ${2:0:1} != "/" ) && ( ${2:0:1} != ":" ) ]] && usage
image="$1"
[[ -f "$image" ]] || { echo "Source image not found."; exit 2; }
if [[ $3 ]]; then
pdospath=$(echo $2 | tr [:lower:] [:upper:])
targetPath=$3
if [[ -d $targetPath ]]; then
targetDir=$targetPath
else
targetDir="${targetPath%/*}"
targetName="${targetPath##*/}"
fi
[[ -d $targetDir ]] || { echo "Target directory not found."; exit 2; }
else
if [[ ! $DIR ]]; then
[[ -d "$2" ]] || { echo "Target directory not found."; exit 2; }
fi
fi
activeDirBlock=0
activeFileName=""
activeFileSize=0
activeFileBytesCopied=0
resourceFork=0
if [[ $3 ]]; then
IFS='/:'
PDOSPATH=($pdospath)
unset IFS
[[ ! ${PDOSPATH[0]} ]] && (( PDOSPATH_INDEX++ ))
PDOSPATH_SEGMENT=${PDOSPATH[PDOSPATH_INDEX]}
ADdir="$targetDir/.AppleDouble"
[[ ! $AD || -d $ADdir ]] || mkdir $ADdir
processDir 2
echo "ProDOS file not found within image file."
exit 2
else
if [[ ! $DIR ]]; then
targetDir="$2/$(getVolumeName)"
ADdir="$targetDir/.AppleDouble"
[[ -d $targetDir ]] || mkdir -p $targetDir
[[ ! $AD || -d $ADdir ]] || mkdir -p $ADdir
fi
processDir 2
[[ $DIR ]] || syncExit
fi

View File

@ -1,882 +0,0 @@
#!/usr/bin/env python
"""cppo: Copy or catalog one or all files from a ProDOS raw disk image.
copy all files:
cppo [-ad|-e] imagefile target_directory
copy one file:
cppo [-ad|-e] imagefile /FULL/PRODOS/FILE/PATH target_path
catalog image:
cppo -cat imagefile
-ad : Create AppleDouble header files and preserve resource forks.
-e : Append ProDOS type and auxtype to filenames, and copy resource
forks, for adding to ShrinkIt archives with Nulib2
using its -e option.
Wildcard matching/globbing (*) is not supported.
No verification or validation of the disk image is performed.
(Compatible with Python 2.6 and later, including 3.x.)
"""
# cppo by Ivan X, ivan@ivanx.com, ivanx.com/appleii
# If anyone's looking at this, and feels it's not sufficiently Pythonic,
# I know that. It's pretty much a line-for-line conversion of the original
# Bash script. I did start a beautiful from-the-ground-up object-oriented
# version, then realized it would be faster to translate it ugly and quick.
# imports for python 3 code compatibility
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
import sys
import os
import time
import datetime
# Intentially fails on pre-2.6 so user can see what's wrong
b'ERROR: cppo requires Python 2.6 or later, including 3.x.'
class Globals(object):
pass
g = Globals()
g.imageData = b''
g.outFileData = bytearray(b'')
g.adFileData = bytearray(b'')
g.exFileData = bytearray(b'')
g.activeDirBlock = None
g.activeFileName = None
g.activeFileSize = None
g.activeFileBytesCopied = 0
g.resourceFork = 0
g.PDOSPATH = []
g.PDOSPATH_INDEX = 0
g.PDOSPATH_SEGMENT = None
g.DIRPATH = ""
g.targetName = None
g.targetDir = ""
g.ADdir = None
g.imageFile = None
g.AD = 0
g.EX = 0
g.DIR = 0
g.silent = 0
# 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
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
# cppo support routines:
# arg1: directory block
# arg2: file index (if applicable)
# arg3: directory chunk # (if applicable)
#most of these not tested yet in Python
# returns byte position in disk image file
def getStartPos(arg1, arg2):
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 (firstByte//16)
def getFileName(arg1, arg2):
start = getStartPos(arg1, arg2)
firstByte = readcharDec(g.imageData, start)
entryType = (firstByte//16)
nameLength = (firstByte - entryType*16)
return readchars(g.imageData, start+1, nameLength)
def getFileType(arg1, arg2):
start = getStartPos(arg1, arg2)
return readcharHex(g.imageData, start+16)
def getKeyPointer(arg1, arg2):
start = getStartPos(arg1, arg2)
return (readcharDec(g.imageData, start+17) +
readcharDec(g.imageData, start+18)*256)
def getFileLength(arg1, arg2):
start = getStartPos(arg1, arg2)
return (readcharDec(g.imageData, start+21) +
readcharDec(g.imageData, start+22)*256 +
readcharDec(g.imageData, start+23)*65536)
def getAuxType(arg1, arg2):
start = getStartPos(arg1, arg2)
return (readcharHex(g.imageData, start+32) +
readcharHex(g.imageData, start+31))
def getCreationDate(arg1, arg2):
#outputs prodos creation date/time as Unix time
# (seconds since Jan 1 1970 GMT)
#or None if there is none
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
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)
def getWorkingDirName(arg1):
start = ( arg1 * 512 )
firstByte = readcharDec(g.imageData, start+4)
entryType = (firstByte//16)
nameLength = (firstByte - entryType*16)
return readchars(g.imageData, start+5, nameLength)
def getDirEntryCount(arg1):
start = ( arg1 * 512 )
return (readcharDec(g.imageData, start+37) +
readcharDec(g.imageData, start+38)*256)
def getDirNextChunkPointer(arg1):
start = ( arg1 * 512 )
return (readcharDec(g.imageData, start+2) +
readcharDec(g.imageData, start+3)*256)
# -- script begins in earnest here
def copyFile(arg1, arg2):
g.outFileData = bytearray(b'')
g.exFileData = bytearray(b'')
g.activeFileBytesCopied = 0
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)
def copyBlock(arg1, arg2):
#arg1: block to copy
#arg2: bytes to write (should be 512,
# unless final block with less than 512 bytes)
#print(arg1 + " " + arg2 + " " + g.activeFileBytesCopied)
if (arg1 == 0):
outBytes = (b'\x00' * arg2)
else:
outBytes = slyce(g.imageData, arg1*512, arg2)
if (g.resourceFork > 0):
if g.AD:
g.adFileData[g.activeFileBytesCopied+741:
(g.activeFileBytesCopied+741 + arg2)] = outBytes
if g.EX:
g.exFileData[g.activeFileBytesCopied:
(g.activeFileBytesCopied + 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: dirBlock
# arg2/3/4/5: for non-key chunks: entryCount, entry#,
# workingDirName, processedEntryCount
entryCount = None
e = None
pe = None
workingDirName = None
if arg2:
entryCount = arg2
e = arg3
workingDirName = arg4
pe = arg5
else:
e = 0
pe = 0
entryCount = getDirEntryCount(arg1)
workingDirName = getWorkingDirName(arg1).decode("L1")
g.DIRPATH = (g.DIRPATH + "/" + workingDirName)
if g.PDOSPATH_INDEX:
if (g.PDOSPATH_INDEX == 1):
if (("/" + g.PDOSPATH_SEGMENT) != g.DIRPATH):
print("ProDOS volume name does not match disk image.")
sys.exit(2)
else:
g.PDOSPATH_INDEX += 1
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
else:
print(g.DIRPATH)
while (pe < entryCount):
if (getStorageType(arg1, e) > 0):
processEntry(arg1, e)
pe += 1
e += 1
if not ((e + ( e>11 ) ) % 13):
processDir(getDirNextChunkPointer(arg1),
entryCount,
e,
workingDirName,
pe)
break
def processEntry(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))
'''
g.activeFileName = getFileName(arg1 ,arg2).decode("L1")
g.activeFileSize = getFileLength(arg1, arg2)
if ((not g.PDOSPATH_INDEX) or (g.activeFileName == g.PDOSPATH_SEGMENT)):
if (getStorageType(arg1, arg2) == 13): # if ProDOS directory
if not g.PDOSPATH_INDEX:
g.targetDir = (g.targetDir + "/" + g.activeFileName)
g.ADdir = (g.targetDir + "/.AppleDouble")
if not (g.DIR or os.path.isdir(g.targetDir)):
makedirs(g.targetDir)
if not (g.DIR 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))
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: # if ProDOS file
if not g.PDOSPATH_INDEX:
print(" " + g.activeFileName)
if g.DIR:
return
if not g.targetName:
g.targetName = g.activeFileName
if g.EX:
eTargetName = (g.targetName + "#" +
getFileType(arg1, arg2).lower() +
getAuxType(arg1, arg2).lower())
touch(g.targetDir + "/" + g.targetName)
if g.AD: makeADfile()
copyFile(arg1, arg2)
saveFile((g.targetDir + "/" + g.targetName), 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.adFileData,
637,
(unixDateToADDate(creationDate) +
unixDateToADDate(modifiedDate)))
writecharHex(g.adFileData, 645, "80")
writecharHex(g.adFileData, 649, "80")
#set type/creator
writechars(g.adFileData, 653, b'p')
writecharsHex(g.adFileData,
654,
(getFileType(arg1, arg2) +
getAuxType(arg1, arg2)))
writechars(g.adFileData, 657, b'pdos')
saveFile(ADfilePath, g.adFileData)
touch((g.targetDir + "/" + g.targetName), modifiedDate)
if g.EX: # extended name
os.rename((g.targetDir + "/" + g.targetName),
(g.targetDir + "/" + eTargetName))
if (len(g.exFileData) > 0):
saveFile((g.targetDir + "/" + eTargetName + "r"),
g.exFileData)
touch((g.targetDir + "/" + eTargetName + "r"),
modifiedDate)
if g.PDOSPATH_SEGMENT:
syncExit()
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))
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)
print(" [resource fork]")
if g.AD:
writecharsHex(g.adFileData, 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)
def processIndexBlock(arg1, arg2=False):
#arg1: indexBlock
#arg2: if True, it's a Master Index Block
pos = 0
bytesRemaining = g.activeFileSize
while (g.activeFileBytesCopied < g.activeFileSize):
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.adFileData = bytearray(b'\x00' * 741)
# ADv2 header
writecharsHex(g.adFileData, hexToDec("00"), "0005160700020000")
# number of entries
writecharsHex(g.adFileData, hexToDec("18"), "000D")
# Resource Fork
writecharsHex(g.adFileData, hexToDec("1A"), "00000002000002E500000000")
# Real Name
writecharsHex(g.adFileData, hexToDec("26"), "00000003000000B600000000")
# Comment
writecharsHex(g.adFileData, hexToDec("32"), "00000004000001B500000000")
# Dates Info
writecharsHex(g.adFileData, hexToDec("3E"), "000000080000027D00000010")
# Finder Info
writecharsHex(g.adFileData, hexToDec("4A"), "000000090000028D00000020")
# ProDOS file info
writecharsHex(g.adFileData, hexToDec("56"), "0000000B000002C100000008")
# AFP short name
writecharsHex(g.adFileData, hexToDec("62"), "0000000D000002B500000000")
# AFP File Info
writecharsHex(g.adFileData, hexToDec("6E"), "0000000E000002B100000004")
# AFP Directory ID
writecharsHex(g.adFileData, hexToDec("7A"), "0000000F000002AD00000004")
# dbd (second time) will create DEV, INO, SYN, SV~
def syncExit():
if (not g.silent 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.")
# saveFile(g.imageFile, g.imageData)
sys.exit(0)
def usage():
print(sys.modules[__name__].__doc__)
sys.exit(1)
# --- ID bashbyter functions (adapted)
def decToHex(arg1):
# converts single-byte decimal value to hexadecimal equivalent
# 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()
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)
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)
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])
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()
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)
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()
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)
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)
def readchars(arg1, arg2=0, arg3=0):
# read one or more characters from a bytes variable
# arg1: bytes or bytearray variable
# arg2: (optional) offset (# of bytes to skip before reading)
# 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)
def readcharDec(arg1, arg2=0):
# read one character from bytes var & convert to equivalent dec value
# arg1: bytes var
# 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))
def readcharHex(arg1, arg2=0):
# read one character from bytes var & convert to corresponding hex value
# arg1: bytes var
# 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))
def writechars(arg1, arg2, arg3):
# write one or more characters (bytes) to bytearray
# arg1: bytearray variable
# arg2: offset (# of bytes to skip before writing)
# 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
def writecharDec(arg1, arg2, arg3):
# write corresponding char of single-byte decimal value into bytearray
# arg1: bytearray
# arg2: offset (# of bytes to skip before writing)
# 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)
def writecharHex(arg1, arg2, arg3):
# write corresponding character of single-byte hex value into bytearray
# arg1: bytearray
# arg2: offset (# of bytes to skip before writing)
# 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().decode())): sys.exit(23)
arg1[arg2:arg2+1] = to_bytes(arg3)
def writecharsHex(arg1, arg2, arg3):
# write corresponding characters of hex values into bytearray
# arg1: bytearray
# arg2: offset (# of bytes to skip before writing)
# 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().decode())): 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"""
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):
# .encode().decode() always returns unicode in both P2 and P3
return (hex(val)[2:].split("L")[0]).encode("L1").decode("L1")
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))
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))
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))
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().decode())): # hex-ustr
return int(val, 16)
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().decode())): # 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().decode())): # hex-ustr
return a2b_hex(bytes(val.encode("L1"))) # works on both P2 and P3
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.
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
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
def touch(filePath, modTime=None):
# http://stackoverflow.com/questions/1158076/implement-touch-using-python
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
def makedirs(dirPath):
import os
if (os.name == "nt"):
if dirPath[-1] == ".": dirPath += "-"
dirPath = dirPath.replace("./", ".-/")
try:
os.makedirs(dirPath)
except FileExistsError:
pass
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()
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)
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
#---- end IvanX general purpose functions ----#
# --- start
args = sys.argv
if (len(args) == 1):
usage()
if (args[1] == "-s"):
g.silent=1
args = args[1:] #shift
if (args[1] == "-ad"):
g.AD = 1
args = args[1:] #shift
if (args[1] == "-e"):
if g.AD: usage()
g.EX = 1
args = args[1:] #shift
if (args[1] == "-cat"):
g.DIR = 1
args = args[1:]
if not ((g.DIR and len(args) >= 2) or (len(args) >= 3)):
usage()
if ((len(args) == 4) and
(slyce(args[2],0,1) != "/") and
(slyce(args[2],0,1) != ":")):
usage()
g.imageFile = args[1]
if not os.path.isfile(g.imageFile):
print("Source " + g.imageFile + " was not found.")
sys.exit(2)
g.imageData = loadFile(g.imageFile)
if (len(args) == 4):
g.PDOSPATH = args[2].upper()
targetPath = args[3]
if os.path.isdir(targetPath):
g.targetDir = targetPath
else:
g.targetDir = targetPath.rsplit("/", 1)[0]
g.targetName = targetPath.rsplit("/", 1)[1]
if not os.path.isdir(g.targetDir):
print("Target directory not found.")
sys.exit(2)
else:
if not g.DIR:
if not os.path.isdir(args[2]):
print("Target directory not found.")
sys.exit(2)
g.activeDirBlock = 0
g.activeFileName = ""
g.activeFileSize = 0
g.activeFileBytesCopied = 0
g.resourceFork = 0
g.PDOSPATH_INDEX = 0
if (len(args) == 4):
g.PDOSPATH = g.PDOSPATH.replace(':', '/').split('/')
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.")
sys.exit(2)
else:
if not g.DIR:
# 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.DIR:
syncExit()

View File

@ -1,80 +0,0 @@
#!/bin/bash
# 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;
else
stdout=
fi
# use stdin?
if [[ ! $1 || "$1" == "-" ]]; then
stdin=1
stdout=1
elif [[ $1 && ! -f "$1" ]]; then
echo "usage: dopo [-c] [-|140KdiskImageFilename] 1>&2";
exit 1;
else
stdin=
fi
if [[ ! $stdout ]]; then
#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 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"
else
ofile="/tmp/$$.dopo_out"
fi
if [[ ! $stdin ]]; then
# set infile param for dd
ifile="$1"
elif [[ -t 0 ]]; then
echo "usage: dopo [-c] [-|140KdiskImageFilename]" 1>&2; exit 1;
else
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
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
done
# remove the old one
[[ ! $stdin && ! $stdout ]] && rm "$1" &> /dev/null
# dump to stdout if -c or stdin used
[[ $stdout ]] && { cat $ofile; rm $ofile &> /dev/null; }
[[ $stdin ]] && rm $ifile &> /dev/null;

View File

@ -1,124 +0,0 @@
#!/bin/bash
readcharDec () {
# read one character from file & convert to equivalent decimal value
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# 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'
}
readcharHex () {
# read one character from file & convert to corresponding hex value
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# 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')
}
### 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
}
[[ $1 == "-h" || $1 == "--help" || ! $1 || ! -f "$1" ]] && usage
dosImage="$1"
fileName="$2"
dosImageBasename=$(basename "$dosImage")
proImage="${dosImageBasename%.*}_prodos.po"
if [[ ! -f "$proImage" ]]; then
echo "Creating $proImage..."
mkpo -b 280 "$proImage"
else
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
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
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')
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
fi

View File

@ -1,6 +0,0 @@
wget -qO /tmp/gsport-setup appleii.ivanx.com/a2cloud/setup/gsport-setup.txt
if [[ $(wc -c /tmp/gsport-setup | grep '^0 ') ]]; then
echo "Please connect to the internet to set up GSport."
else
source /tmp/gsport-setup "$@"
fi

View File

@ -1,573 +0,0 @@
#!/bin/bash
readcharHex () {
# read one character from file & convert to corresponding hex value
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# 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]
}
readchars () {
# read one or more characters from a file
# arg1: filename
# arg2: (optional) offset (# of bytes to skip before reading)
# arg3: (optional) # of chars to read (default is until end of file)
# 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
}
writecharsHex () {
# write corresponding characters of hex values into file
# arg1: filename
# arg2: offset (# of bytes to skip before writing)
# arg3: string of two-digit hexadecimal numbers from 00-FF, period delimited (not checked!)
# 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
}
### start
[[ -f /usr/bin/raspi-config ]] && isRpi=1 || isRpi=
emulatorName="GSport"
emulatorStart="gsport"
emulatorSetup="gsport-setup"
romFileName="ROM"
configFileName="config.txt"
imagesDir="/usr/local/share/gsdisks"
gsosHD="gsoshd.hdv"
gsosHDvolName="GSOS.HD"
tempDir="/tmp/gs"
rom=ROM3
slot6=
autoAnswerYes=
noDisks=
gisk=
installDisks=
kegs=
{ acmd &> /dev/null || [[ $? -ne 127 ]]; } && acmdOK=1 || acmdOK=
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
elif [[ $arg == "k" ]]; then
kegs=1
shift
else
echo "Usage: $emulatorSetup [rom1|rom3] [-6] [-y [-g|-i|-n]]"
echo "rom1: use GS ROM 01"
echo "rom3: use GS ROM 03"
echo "-k: set up KEGS (rather than GSport)"
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
if [[ $kegs ]]; then
emulatorName="KEGS"
emulatorStart="kegs"
emulatorSetup="kegs-setup"
romFileName="rom.kegs"
configFileName="config.kegs"
fi
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
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
fi
sudo mkdir -p "$imagesDir"
sudo chmod ugo+rw "$imagesDir"
mkdir -p "$tempDir"
cd "$tempDir"
echo "Updating package lists..."
sudo apt-get -y update > /dev/null
if [[ ! -f /usr/local/bin/unar ]]; then
echo "Installing The Unarchiver..."
sudo apt-get -y install libgnustep-base1.22
sudo apt-get -y clean
wget -qO- appleii.ivanx.com/a2cloud/setup/unar.tgz | sudo tar Pzx
fi
if [[ ! -f /usr/local/bin/mkpo ]]; then
echo "Installing mkpo..."
sudo wget -qO /usr/local/bin/mkpo appleii.ivanx.com/a2cloud/setup/mkpo.txt
sudo chmod ugo+x /usr/local/bin/mkpo
fi
if [[ ! -f /usr/local/bin/nulib2 ]]; then
echo "Installing nulib2..."
wget -qO- appleii.ivanx.com/a2cloud/setup/nulib2.tgz | sudo tar Pzx
fi
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
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
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
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- ivanx.com/a2cloud/files/slot6.tgz | sudo tar Pzx 2> /dev/null
fi
fi
if [[ ! $kegs ]]; then
# 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
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
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 /tmp/GSport_Internet_Starter_Kit.zip http://sourceforge.net/projects/gsport/files/Emulator%20Software%20Images/GSport_Internet_Starter_Kit.zip
unzip -d /tmp /tmp/GSport_Internet_Starter_Kit.zip "GSport Internet Starter Kit/GSport Internet Starter Kit.2mg"
sudo mv "/tmp/GSport Internet Starter Kit/GSport Internet Starter Kit.2mg" $imagesDir
rm -r /tmp/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
fi
fi
# non-GISK; get installer disks
if [[ ! -f $imagesDir/INSTALL.HDV ]] \
|| [[ ! -f $imagesDir/SYSTEM.DISK.HDV ]] \
|| [[ ! -f $imagesDir/SYSTEMTOOLS1.HDV ]] \
|| [[ ! -f $imagesDir/SYSTEMTOOLS2.HDV ]] \
|| [[ ! -f $imagesDir/FONTS.HDV ]] \
|| [[ ! -f $imagesDir/SYNTHLAB.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
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 /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- ivanx.com/a2cloud/files/${emulatorName}SPLASH.SYS | dd of="PRODOS#ff0000" conv=notrunc &> /dev/null
echo "Copying Teach..."
cppo -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
nulib2 -a -e $gsosHD.shk "PRODOS#"* "GSHK#"* "TEACH#"* &> /dev/null
acmd -convert $gsosHD.shk $imagesDir/"$gsosHD" 65535
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
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 [[ -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
if [[ ! $kegs ]]; then
mkdir -p /tmp/spectrum
cd /tmp/spectrum
imageName="/tmp/spectrum/spectrum.dmg"
hfsName="/tmp/spectrum/spectrumH.dmg"
ullName="/tmp/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/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
mkdir -p mnt
mkdir -p extract
mkdir -p shkstage
cp "$imageName" "$hfsName"
sudo mount -r -t hfs "$imageName" mnt
hmount "$hfsName"
IFS=''
cd /tmp/spectrum/mnt
find Spectrum.2.5.3 -type d | while read thisDirPath; do
mkdir -p /tmp/spectrum/shkstage/"$thisDirPath"
hcd
IFS='/'
for thisDir in $thisDirPath; do
hcd $thisDir
done
echo " Copying: $(hpwd)"
IFS=''
cd /tmp/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 /tmp/spectrum/shkstage/"$thisDirPath"/"${thisFile}#${fileType}${auxType}r"
[[ -f "$thisFile".data ]] && mv "$thisFile".data /tmp/spectrum/shkstage/"$thisDirPath"/"${thisFile}#${fileType}${auxType}"
rm "$thisFile".info 2> /dev/null
fi
done
cd /tmp/spectrum/mnt
done
cd /tmp/spectrum/shkstage/Spectrum*
humount
sudo umount /tmp/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"
echo "Making archive for conversion to disk image..."
rm /tmp/spectrum/spectrum.shk 2> /dev/null
nulib2 -a -r -0 -e /tmp/spectrum/spectrum.shk * &> /dev/null
echo "Converting archive to disk image..."
acmd -convert /tmp/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
cd /tmp
rm -rf /tmp/spectrum/extract /tmp/spectrum/shkstage /tmp/spectrum/spectrum.shk /tmp/spectrum/mnt &> /dev/null
fi
# Spectrum ends here
fi
fi
cd
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."
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
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"
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
fi

View File

@ -1,122 +0,0 @@
#!/bin/bash
if [[ ( $(grep USB <<< $myTTY) || $(grep AMA <<< $myTTY) || $SSH_CLIENT || $REMOTEHOST ) && ! $DISPLAY ]]; then
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 [[ ! $(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
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
# echo "If you wish to run GSport in the console window, the mouse will not work"
# echo "unless you uninstall VirtualBox Guest Additions. If you don't want to do"
# echo "this, you can instead run GSport in an X window (e.g. by typing 'startx')."
# echo "If you're not sure, just uninstall it now. Nothing terrible will happen."
# echo
# echo -n "Do you want to uninstall VirtualBox Guest Additions now? "
# read
# if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
# echo "Ok, on the case..."
# sudo /etc/init.d/vboxadd-service stop 2> /dev/null
# sudo /etc/init.d/virtualbox-guest-utils stop &> /dev/null
# sudo rmmod vboxvideo 2> /dev/null
# sudo rmmod vboxsf 2> /dev/null
# sudo rmmod vboxguest 2> /dev/null
# while { lsmod | grep -q vbox; }; do
# sleep 1
# sudo rmmod vboxvideo 2> /dev/null
# sudo rmmod vboxsf 2> /dev/null
# sudo rmmod vboxguest 2> /dev/null
# done
# if [ -f /opt/VBoxGuestAdditions*/uninstall.sh ]; then
# sudo /opt/VBoxGuestAdditions*/uninstall.sh &> /dev/null
# sudo rmdir /opt/VBoxGuestAdditions* 2> /dev/null
# fi
# if { dpkg -l 2> /dev/null | grep -q -i virtualbox; }; then
# sudo apt-get -y purge $(dpkg -l 2> /dev/null | grep -i virtualbox | cut -f 3 -d ' ' | tr '\n' ' ') &> /dev/null
# fi
# touch /tmp/gsport-consolesetup
# 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 [[ -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 gsportx
else
exec gsportfb
fi
else
echo "GSport has a problem. Please try updating A2CLOUD by"
echo "typing 'a2cloud-setup'."
fi
fi

View File

@ -1,6 +0,0 @@
wget -qO /tmp/gsport-setup ivanx.com/a2cloud/setup/gsport-setup.txt
if [[ $(wc -c /tmp/gsport-setup | grep '^0 ') ]]; then
echo "Please connect to the internet to set up KEGS."
else
source /tmp/gsport-setup -k "$@"
fi

View File

@ -1,6 +0,0 @@
if [[ -f /usr/local/bin/gsport-setup ]]; then
wget -O /tmp/gsport-setup ivanx.com/a2cloud/gsport-setup.txt
source /tmp/gsport-setup -k "$@"
else
gsport-setup -k "$@"
fi

View File

@ -1,27 +0,0 @@
#!/bin/bash
if [[ ! $DISPLAY ]]; then
echo "Please run KEGS in an X Window."
echo "(If you are using the console, type 'startx'.)"
else
if [[ -f /usr/local/lib/rom.kegs ]]; then
if [[ ! $(grep snd-pcm-oss /etc/modules) ]]; then
echo "Configuring KEGS 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 KEGS fonts..."
sudo apt-get -y update
sudo apt-get -y install xfonts-base &> /dev/null
sudo apt-get -y clean
fi
exec xkegs
else
kegs-setup
[[ $? -ne 0 ]] && exit 1
exec kegs
fi
fi

View File

@ -1,52 +0,0 @@
#!/bin/bash
if [[ ( $(grep USB <<< $myTTY) || $(grep AMA <<< $myTTY) || $SSH_CLIENT || $REMOTEHOST ) && ! $DISPLAY ]]; then
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
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 [[ -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
fi

View File

@ -1,160 +0,0 @@
#!/bin/bash
# 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
};
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
};
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
};
# mkpo
[[ ! -n $1 ]] && { echo "Usage: mkpo [-b totalBlocks] newImageName [PRODOS.VOL.NAME]"; exit 1; };
[[ -f /usr/local/adtpro/adtpro.sh ]] && adtPath="/usr/local/adtpro" || adtPath=$(ls -1d /Applications/ADTPro* | head -1);
[[ ! -d "$adtPath" ]] && { echo "AppleCommander not found."; exit 1; }
if [[ $1 == "-b" ]]; then
totalBlocks="$2"
shift
shift
fi
[[ -f $1 ]] && { echo "Image '$1' already exists."; exit 1; }
[[ $2 ]] && prodosVolName="$2" || prodosVolName="UNTITLED"
# 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;
fi
# see if nulib2 is available; if so, acmd -convert will create image
# with specified block size
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"
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
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
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
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}";
# 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;
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

View File

@ -1,16 +0,0 @@
Welcome to A2CLOUD!
Instructions and help: http://appleii.ivanx.com
Type 'a2cloud-help' for a list of A2CLOUD commands.
Type 'system-shutdown' to turn off your Raspberry Pi.
Type 'raspi-config' to configure your Raspberry Pi.
Type 'startx' to start the Raspbian desktop.
Type 'lynx' or 'links' to browse the web and 'cftp' to log into FTP sites.
Type 'a2chat' or 'a2news' to talk about Apple II stuff with others.
Type 'ttytter' to tweet. Type 'term color' for a color terminal on a IIgs.
Type 'gsport' or 'kegs' to use the GSport or KEGS Apple IIgs emulators.
Type 'linapple' to use the LinApple Apple IIe emulator.

View File

@ -1,16 +0,0 @@
Welcome to A2CLOUD!
Instructions and help: http://appleii.ivanx.com
Type 'a2cloud-help' for a list of A2CLOUD commands.
Type 'system-shutdown' to turn off your Raspberry Pi.
Type 'raspi-config' to configure your Raspberry Pi.
Type 'startx' to start the Raspbian desktop.
Type 'lynx' or 'links' to browse the web and 'cftp' to log into FTP sites.
Type 'a2chat' or 'a2news' to talk about Apple II stuff with others.
Type 'ttytter' to tweet. Type 'term color' for a color terminal on a IIgs.
Type 'gsport' or 'kegs' to use the GSport or KEGS Apple IIgs emulators.
Type 'linapple' to use the LinApple Apple IIe emulator.

View File

@ -1 +0,0 @@
motd-rpi.txt

View File

@ -1,233 +0,0 @@
#!/bin/bash
# raspbian-update
# updates Raspbian to latest version, including NOOBS if installed
[[ -f /usr/bin/raspi-config ]] && isRpi=1 || isRpi=
if [[ ! $isRpi ]]; then
echo "This ain't a Raspberry Pi."
[[ $0 == "-bash" ]] && return 1 || exit 1
fi
skipRepoUpdate=
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
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"
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
fi
origDir="$PWD"
cd /tmp
if [[ ! $skipRepoUpdate ]]; then
echo "Updating package repositories..."
sudo apt-get -y update > /dev/null
else
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
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..."
# 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 '^<tr><td' | tail -1 | grep -P -o 'href=".*?"' | cut -c 6- | tr -d '"')
noobsUrl=$noobsRoot$noobsDir$(wget -qO- $noobsRoot$noobsDir | grep -P -o 'href=".*.zip"' | cut -c 6- | tr -d '"')
noobsOSurl="downloads.raspberrypi.org/raspbian"
distDir="Raspbian"
sudo mkdir -p /tmp/p3/os/$distDir
sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspbian.png
wget -qO- $noobsOSurl/marketing.tar | sudo tar -C /tmp/p3/os/$distDir -x
fi
sudo rm -rf /tmp/p3/cache 2> /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
sudo sed -i 's/\(Raspple II release.*[^u]$\)/\1u/' /etc/issue
fi
echo
echo "*** Raspbian update completed. ***"
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
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
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
else
echo "*** raspbian-update completed. ***"
sudo shutdown -r now
fi

View File

@ -1 +0,0 @@
v1.8.2.txt

View File

@ -1,24 +0,0 @@
#!/bin/bash
origDir="$PWD"
[[ ! -n $1 || ! -n $2 ]] && { echo "Usage: shk2image archiveFileName imageFileName [PRODOS.DIR.NAME]"; exit 1; };
imageFileName="$2";
prodosDir="$3";
[[ ! -f "$1" ]] && { echo "Archive file '$1' was not found."; exit 1; };
[[ ! -f "$imageFileName" ]] && mkpo "$imageFileName";
[[ -n $prodosDir ]] && dirName="$prodosDir/" || dirName=;
IFS="";
[[ ${1:0:1} == "/" ]] && archiveFile="$1" || archiveFile="$origDir/$1"
mkdir -p /tmp/shk2image_temp
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"
done <<< $shkFiles
rm -r /tmp/shk2image_temp

View File

@ -1,46 +0,0 @@
if [[ $1 == "-d" ]]; then
shift
setgetty=1
else
setgetty=
fi
if [[ $1 == "-f" ]]; then
shift
force=1
else
force=
fi
if [[ ! $1 || $1 == "--help" || $1 == "-h" ]]; then
echo 'Usage: term [-d] mono|color|none|<terminalName>';
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
fi
echo -e "$(tty) current emulation: $(tput bold)$TERM$(tput sgr0)"
echo -e "default serial port emulation at login: $(tput bold)$(grep ttyUSB /etc/inittab | sed 's/^.*ttyUSB[^ ]* .* \(.*\)$/\1/')$(tput sgr0)"

View File

@ -1,45 +0,0 @@
#!/bin/bash
# called by udev as:
# ttyusbhandler [add|remove] ttyUSBname
# depending on what port ttyUSB adapter was added or removed from,
# automatically launches or kills ADTPro as needed
# restarts getty as needed
# remove:
# kill any ADTPro for this port
# if a getty is on this port, do nothing here, it will be killed and respawn
# iteself
# add:
# stagger adds by port number to prevent problems during simultaneous add at startup
# if lower port, solo adapter on lower port USB hub, or lower port of any USB hub,
# kill any ADTPro, rescan for getty if sleeping, and launch adtPro
# if upper port, solo adapter on upper port USB hub, or higher port of any USB hub,
# rescan for getty
if [[ $1 == "remove" ]]; then
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 /usr/local/adtpro/adtpro.sh headless serial
else # ttyUSBupper
rm /tmp/udev-ttyUSBupper-added &> /dev/null
touch /tmp/udev-ttyUSBupper-added
pkill -f "[g]etty.*ttyUSB"
fi
else
exit 2
fi

View File

@ -1,47 +0,0 @@
#!/bin/bash
ttyUSB=
pkill -f "sleep 86399"
if [[ $(grep -e '-scanttyUSB' <<< "$*") ]]; then
# called with -scantty isntead of device name?
# echo "-scantty mode"
# 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 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
# echo "result:$ttyUSB"
elif [[ $(grep -o 'ttyUSB[^ ]*' <<< "$*") ]]; then
# echo "device specified"
# if specified USB device name is found
ttyUSB=$(grep -o 'ttyUSB[^ ]*' <<< "$*")
else
# 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/" <<< "$@");
else
# echo "getty already running or doesn't exist: sleeping"
sleep 86399
fi

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
#!/bin/bash
skipWarning=
drive=
if [[ $1 == "-1" || $1 == "-d1" ]]; then
shift
elif [[ $1 = "-2" || $1 == "-d2" ]]; then
drive=2
shift
fi
if [[ ! $1 ]]; then
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
fi
unset drive
unset pwd