mirror of
https://github.com/RasppleII/a2server.git
synced 2024-12-24 14:31:21 +00:00
287 lines
9.2 KiB
Bash
Executable File
287 lines
9.2 KiB
Bash
Executable File
#! /bin/bash
|
|
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
|
|
|
# mkatinit by Ivan Drucker, http://appleii.ivanx.com
|
|
# not licensed; please modify and redistribute as you like
|
|
# 1.0b4 1-30-11
|
|
|
|
# 1.1d1 -- uses bashByter. NOT TESTED.
|
|
|
|
# This script creates the ATINIT file required for netbooting Apple IIe and
|
|
# IIGS clients from a netatalk server. ATINIT is put in the in the
|
|
# (sharename)/USERS hierarchy, or the current directory if it can't.
|
|
# The user can specify the ProDOS startup system program and default prefix.
|
|
# If an argument is supplied, it is used as the username and the prompt is
|
|
# skipped.
|
|
|
|
# The ATINIT file is not as complete as the ones generated by AppleShare 3.0,
|
|
# and features such as default printer are not used.
|
|
|
|
# to do
|
|
# possibly require confirmation if AFPD_GUEST is not set correctly
|
|
# or offer to change it
|
|
|
|
# from ID-bashByter library
|
|
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")"
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
#---- mkatinit starts here
|
|
IFS=''
|
|
|
|
#defaults
|
|
sharepath=$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1)
|
|
prefix=/$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f2)
|
|
gsprefix=$prefix
|
|
startprog="$prefix/BASIC.SYSTEM"
|
|
gsstartprog="$prefix/SYSTEM/FINDER"
|
|
filename="ATINIT"
|
|
user=$(whoami)
|
|
|
|
echo
|
|
|
|
usersfolder=1
|
|
while [ -n "$1" ] && [ "${1:0:1}" = '-' ]; do
|
|
flag="$1"
|
|
if [ $flag = "-gs" ]; then
|
|
gs=1
|
|
shift
|
|
continue
|
|
elif [ $flag = "-d" ]; then
|
|
noprompt=1
|
|
shift
|
|
continue
|
|
elif [ $flag = "-f" ]; then
|
|
overwrite=1
|
|
shift
|
|
continue
|
|
elif [ $flag = "-g" ]; then
|
|
alsoguest=1
|
|
shift
|
|
continue
|
|
elif [ $flag = "-c" ]; then
|
|
usersfolder=0
|
|
shift
|
|
continue
|
|
else
|
|
badflag=1
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ $usersfolder -eq 0 ] && [ -n "$alsoguest" ]; then
|
|
badflag=1
|
|
fi
|
|
|
|
if [ $badflag ]; then
|
|
echo "usage: mkatinit [-gs] [-d] [-f] [-g | -c] [<username>|guest]"
|
|
echo
|
|
echo "<username> should be the name of a netatalk user, or 'guest'"
|
|
echo "-gs sets the default ProDOS netboot system startup program and"
|
|
echo " prefix for GS/OS (if omitted, ProDOS 8 defaults are used)"
|
|
echo "-d use the default start program and prefix, without prompting"
|
|
echo "-f overwrite existing ATINIT file if present, without warning"
|
|
echo "-g create an ATINIT file for Guest as well as the specified user"
|
|
echo "-c write ATNIT to current directory instead of USERS hierarchy"
|
|
echo
|
|
exit
|
|
fi
|
|
|
|
arg="$1"
|
|
|
|
[[ -z $arg ]] && arg=$user
|
|
|
|
while : ; do
|
|
|
|
if [ ${#arg} -gt 32 ]; then
|
|
echo "User name is too long. Exiting with no action."
|
|
exit
|
|
elif [ -n "$arg" ]; then
|
|
if [ `echo $arg | tr '[:upper:]' '[:lower:]'` = "guest" ]; then
|
|
username='<Any User>'
|
|
alsoguest=
|
|
if [[ ! $(grep -F -s $(ls -1 /home) /etc/default/netatalk) ]]; then
|
|
echo 'Warning: The AFPD_GUEST setting in /etc/default/netatalk is not assigned to a'
|
|
echo 'user with a folder in /home. Guest users may be able to boot over the network'
|
|
echo 'into ProDOS 8 for read-only access, but will not be able to boot into GS/OS.'
|
|
if [ $gs ]; then
|
|
echo ' Using ProDOS 8 defaults.'
|
|
gs=
|
|
else
|
|
echo
|
|
fi
|
|
echo
|
|
fi
|
|
else
|
|
username="$arg"
|
|
if [[ ! $(ls -1 /home | grep -F -s $username) ]]; then
|
|
echo "Warning: This username ($username) does not have a folder in /home. This user may"
|
|
echo "not be able to boot over the network into ProDOS 8 or GS/OS."
|
|
echo
|
|
fi
|
|
fi
|
|
if [ $gs ]; then
|
|
startprog="$gsstartprog"
|
|
prefix="$gsprefix"
|
|
fi
|
|
fi
|
|
|
|
# make username all caps
|
|
username=`echo $username | tr '[:lower:]' '[:upper:]'`
|
|
|
|
# prompt for folders
|
|
if [ ! $doalsoguest ] && [ ! $noprompt ]; then
|
|
while : ; do
|
|
echo "Enter the ProDOS path to the startup system program."
|
|
echo "default (CR to accept): $startprog"
|
|
read
|
|
if [ ${#REPLY} -gt 64 ]; then
|
|
continue
|
|
elif [ -n "$REPLY" ]; then
|
|
startprog="`echo $REPLY | tr '[:lower:]' '[:upper:]'`"
|
|
echo
|
|
fi
|
|
break
|
|
done
|
|
|
|
while : ; do
|
|
echo "Enter the initial ProDOS prefix:"
|
|
echo "default (CR to accept): $prefix"
|
|
read
|
|
if [ ${#REPLY} -gt 64 ]; then
|
|
continue
|
|
elif [ -n "$REPLY" ]; then
|
|
prefix="`echo $REPLY | tr '[:lower:]' '[:upper:]'`"
|
|
echo
|
|
fi
|
|
break
|
|
done
|
|
fi
|
|
|
|
# create folders if needed
|
|
filepath="$PWD/$filename"
|
|
|
|
while [ $usersfolder -eq 1 ]; do
|
|
# create folders for ATINIT
|
|
while [ ! -d "$sharepath" ]; do
|
|
echo "Shared volume '$sharepath' not found. Edit mkatinit to change the default."
|
|
echo "Enter the local path to the netatalk shared volume used for netboot:"
|
|
read sharepath
|
|
done
|
|
|
|
if [ ! -d "$sharepath/USERS" ]; then
|
|
mkdir "$sharepath/USERS"
|
|
if [ $? -ne 0 ]; then
|
|
break
|
|
fi
|
|
fi
|
|
if [ ! -d "$sharepath/USERS/$username" ]; then
|
|
mkdir "$sharepath/USERS/$username"
|
|
if [ $? -ne 0 ]; then
|
|
break
|
|
fi
|
|
fi
|
|
if [ ! -d "$sharepath/USERS/$username/SETUP" ]; then
|
|
mkdir "$sharepath/USERS/$username/SETUP"
|
|
if [ $? -ne 0 ]; then
|
|
break
|
|
fi
|
|
else
|
|
if [ ! -w "$sharepath/USERS/$username/SETUP" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
|
|
# we have a valid USERS folder target for ATINIT
|
|
filepath="$sharepath/USERS/$username/SETUP/$filename"
|
|
usersfolder=2
|
|
done
|
|
|
|
if [ $usersfolder -eq 1 ]; then
|
|
echo "Could not write to shared volume. Creating ATINIT in current directory."
|
|
if [ -n "$alsoguest" ]; then
|
|
echo "ATINIT for Guest user will not be created."
|
|
fi
|
|
echo
|
|
alsoguest=
|
|
fi
|
|
|
|
if [ ! $doalsoguest ]; then
|
|
echo "netboot start program: $startprog"
|
|
echo "netboot start prefix : $prefix"
|
|
echo
|
|
fi
|
|
|
|
#remove ATINIT if present
|
|
if [ ! $overwrite ] && [ -f "$filepath" ]; then
|
|
echo -n "$filepath already exists. Overwrite? "
|
|
while read -s -n 1 > /dev/null 2>&1; do
|
|
if [ -z "$REPLY" ]; then
|
|
continue
|
|
elif [ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ]; then
|
|
echo
|
|
break
|
|
elif [ "$REPLY" = "N" ] || [ "$REPLY" = "n" ]; then
|
|
echo
|
|
echo "Exiting with no action."
|
|
exit
|
|
fi
|
|
done
|
|
fi
|
|
|
|
#write the file. start with zeroes
|
|
dd if=/dev/zero of="$filepath" bs=1 count=276 2> /dev/null
|
|
#put in startprog, prefix, username (first byte of each field is length)
|
|
# ( echo -n "${#startprog}" | awk '{printf("%c",$0);}'; echo -n "$startprog"; ) | dd of="$filepath" bs=1 seek=7 conv=notrunc 2> /dev/null
|
|
# ( echo -n "${#prefix}" | awk '{printf("%c",$0);}'; echo -n "$prefix"; ) | dd of="$filepath" bs=1 seek=78 conv=notrunc 2> /dev/null
|
|
# ( echo -n "${#username}" | awk '{printf("%c",$0);}'; echo -n "$username"; ) | dd of="$filepath" bs=1 seek=143 conv=notrunc 2> /dev/null
|
|
( decToChar "${#startprog}"; echo -n "$startprog"; ) | writechars "$filepath" 7
|
|
( decToChar "${#prefix}"; echo -n "$prefix"; ) | writechars "$filepath" 78
|
|
( decToChar "${#username}"; echo -n "$username"; ) | writechars "$filepath" 143
|
|
|
|
echo "Created $filepath"
|
|
if [ ! $alsoguest ]; then
|
|
break
|
|
fi
|
|
|
|
if [ $usersfolder -eq 2 ]; then
|
|
usersfolder=1
|
|
fi
|
|
doalsoguest=1
|
|
arg='guest'
|
|
done
|
|
|
|
echo
|