#! /bin/bash # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: 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 [] copy filename out of any" echoerr " disk image. Using - for outputFilename will copy to stdout." echoerr "-e [] like -g, with conversion" echoerr " to modern file format if possible." echoerr "-p [[$|0x]] [[$|0x]] copy filename" echoerr " into ProDOS disk image. is either three-letter or numeric" echoerr " ProDOS file type (BIN if omitted). Will read from stdin if supplied." echoerr " ProDOS subdirectories in will be created if needed." echoerr "-c [[$|0x]] [[$|0x]] 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