mirror of
https://github.com/RasppleII/a2server.git
synced 2025-04-20 00:37:49 +00:00
Compare commits
60 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e499a3db46 | ||
|
5010a496e6 | ||
|
a033151c66 | ||
|
f9b11b6dde | ||
|
98ed939e9f | ||
|
f1b141bd9c | ||
|
d71b2a4048 | ||
|
16e1306dbb | ||
|
7d3ae1d200 | ||
|
6229dba43f | ||
|
f3ae970d37 | ||
|
33d1d058ba | ||
|
c7d64f692c | ||
|
aaea9245de | ||
|
7079684744 | ||
|
5e709f0e2e | ||
|
e9c53fae66 | ||
|
2b52ad8429 | ||
|
9382387000 | ||
|
20bf50bc98 | ||
|
7aae31fda7 | ||
|
82183ad909 | ||
|
923a86899e | ||
|
cb7b429927 | ||
|
106555bc95 | ||
|
099eccd9da | ||
|
14058b1990 | ||
|
456ed6e721 | ||
|
04974d7e03 | ||
|
45c00cb920 | ||
|
a939111f6a | ||
|
02ebf26cf2 | ||
|
14a9adf673 | ||
|
15027e8423 | ||
|
4cba6ff2c0 | ||
|
23a8d1ca0d | ||
|
a263603985 | ||
|
8eabd3768d | ||
|
3cd48ab4b3 | ||
|
a4ab0c3d26 | ||
|
ce2ac0d02d | ||
|
080242d969 | ||
|
af9ebdc4da | ||
|
a7ff9544bc | ||
|
0299a65e45 | ||
|
0a893dc8fd | ||
|
95fc0ef629 | ||
|
e131b8de40 | ||
|
85d30152f2 | ||
|
b60fd31d60 | ||
|
3a405377db | ||
|
1a3cae37d3 | ||
|
ae89fef8b4 | ||
|
94d17f56cc | ||
|
ee4078ab23 | ||
|
530b8d57f5 | ||
|
202d5e6321 | ||
|
8897610d95 | ||
|
27d40503be | ||
|
1c8acba1ae |
0
.a2server_source
Normal file
0
.a2server_source
Normal file
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@ -0,0 +1,14 @@
|
||||
# This is the topmost .editorconfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.sh]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
121
COPYING_CC0.txt
Normal file
121
COPYING_CC0.txt
Normal file
@ -0,0 +1,121 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
81
README.md
81
README.md
@ -13,84 +13,7 @@ relatively modern piece of it. As such they should be preserved as they are.
|
||||
|
||||
## Developer note
|
||||
|
||||
To use the scripts on your own server, including your local machine:
|
||||
|
||||
~~~ bash
|
||||
export A2SERVER_SCRIPT_URL=http://yoururl.com/
|
||||
~~~
|
||||
|
||||
To prevent needing to recompile various packages from source code during
|
||||
installation, a number of precompiled binary files are downloaded for Raspbian,
|
||||
Debian-x86, and Debian-amd64. If you wish to host these on your own server:
|
||||
|
||||
~~~ bash
|
||||
export A2SERVER_BINARY_URL=http://yoururl.com/files/
|
||||
~~~
|
||||
|
||||
You do not need to use a subdirectory called "files", or the same server, but
|
||||
that's the normal arrangement. The precompiled packages are available here:
|
||||
`http://ivanx.com/a2server/files/dist/a2serverbinaries.tar.gz`
|
||||
|
||||
Several Apple II third-party binaries are downloaded during installation, as
|
||||
well as third-party source code if precompiled binaries are unavailable or
|
||||
you don't wish to use them. If you want these external dependencies locally
|
||||
during development, they need to go into a folder called "external" in
|
||||
the binaries URL, and that needs to contain folders called "appleii" and
|
||||
"source". To download all of these external packages, download and run the
|
||||
shell script at
|
||||
`http://ivanx.com/a2server/files/dist/getexternal.sh`.
|
||||
|
||||
Once you have those:
|
||||
|
||||
~~~ bash
|
||||
export A2SERVER_NO_EXTERNAL=1
|
||||
~~~
|
||||
|
||||
You may want to put the above exports into `~/.bashrc` or `~/.bash_profile`.
|
||||
|
||||
If you want to host scripts locally installed on your own machine or another
|
||||
computer on your LAN, type the following, and export "http://localhost:8000/"
|
||||
or "http://lan.ip.address:8000/" for the above URL's.
|
||||
|
||||
~~~
|
||||
python -m SimpleHTTPServer
|
||||
~~~
|
||||
|
||||
Once you're set, you can then run the following snippet to install A2SERVER:
|
||||
|
||||
~~~
|
||||
wget -O setup ${A2SERVER_SCRIPT_URL}setup/index.txt; source setup
|
||||
~~~
|
||||
|
||||
|
||||
Offline install:
|
||||
|
||||
Using locally hosted binaries and external dependencies, it's possible to
|
||||
install completely offline if dependent packages have been installed.
|
||||
|
||||
If precompiled binaries are available, on Wheezy:
|
||||
|
||||
~~~
|
||||
sudo apt-get -y install unzip libgnustep-base1.22 libdb5.1 libgcrypt11 libssl1.0.0 attr fuse libglib2.0-0 libattr1 libfuse2
|
||||
~~~
|
||||
|
||||
If precompiled binaries are available, on Jessie:
|
||||
|
||||
~~~
|
||||
sudo apt-get -y install unzip unar libdb5.3 libgcrypt20 libssl1.0.0 attr fuse libglib2.0-0 libattr1 libfuse2
|
||||
~~~
|
||||
|
||||
If precompiled binaries are not available, on Wheezy:
|
||||
|
||||
~~~
|
||||
sudo apt-get -y install unzip build-essential zlib1g-dev libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev libdb5.1-dev libgcrypt11-dev libglib2.0-dev libattr1-dev libfuse-dev
|
||||
~~~
|
||||
|
||||
If precompiled binaries are not available, on Jessie:
|
||||
|
||||
~~~
|
||||
sudo apt-get -y install unzip unar build-essential zlib1g-dev unzip libssl-dev libdb5.3-dev libgcrypt11-dev libglib2.0-dev libattr1-dev libfuse-dev
|
||||
~~~
|
||||
|
||||
This section used to describe how to run these scripts directly. That's
|
||||
changing. Watch this space.
|
||||
|
||||
[Ivan's site]: http://appleii.ivanx.com/a2server/
|
||||
|
54
files/dist/getexternal.sh
vendored
54
files/dist/getexternal.sh
vendored
@ -1,8 +1,8 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
if ! hash wget; then
|
||||
echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew."
|
||||
echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew."
|
||||
fi
|
||||
|
||||
echo "Downloading items..."
|
||||
@ -36,30 +36,30 @@ wget -O files/external/appleii/sam2.bxy "$samUrl"
|
||||
wget -O files/external/appleii/snap.bxy "$snapUrl"
|
||||
|
||||
for gsosInstall in {1..3}; do
|
||||
activeDisk=0
|
||||
mkdir -p files/external/appleii/gsos60${gsosInstall}
|
||||
|
||||
diskNames=( Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB )
|
||||
if (( $gsosInstall == 1 )); then
|
||||
gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/"
|
||||
wget --max-redirect 0 -O files/external/appleii/gsos601/Disk_7_of_7-Apple_II_Setup.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/Disk_7_of_7-Apple_II_Setup.sea.bin
|
||||
elif (( $gsosInstall == 2 )); then
|
||||
gsosURL="http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Software/Operating%20Systems/Apple%20IIGS%20System/Disk%20Images/"
|
||||
diskNames=( Install System.Disk SystemTools1 SystemTools2 SystemTools3 Fonts1 Fonts2 synthLAB )
|
||||
diskWebNames=( Install System%20disk System%20tools%201 System%20tools%202 System%20tools%203 Fonts%201 Fonts%202 Synthlab )
|
||||
elif (( $gsosInstall == 3 )); then
|
||||
gsosURL="ftp://ftp.apple.asimov.net/pub/apple_II/images/gs/os/gsos/Apple_IIGS_System_6.0.3/"
|
||||
fi
|
||||
activeDisk=0
|
||||
mkdir -p files/external/appleii/gsos60${gsosInstall}
|
||||
|
||||
for diskname in ${diskNames[@]}; do
|
||||
outfile="files/external/appleii/gsos60${gsosInstall}/$diskname.po"
|
||||
(( activeDisk++ ))
|
||||
if (( $gsosInstall == 1 )); then
|
||||
wget --max-redirect 0 -O files/external/appleii/gsos601/"Disk_${activeDisk}_of_7-${diskname}.sea.bin" "${gsosURL}Disk_${activeDisk}_of_7-${diskname}.sea.bin"
|
||||
elif (( $gsosInstall == 2 )); then
|
||||
wget -O $outfile "$gsosURL/IIGS%20System%206.0.2%20-%20Disk%20${activeDisk}%20${diskWebNames[$activeDisk-1]}.po"
|
||||
elif (( $gsosInstall == 3 )); then
|
||||
wget -O $outfile "$gsosURL/$diskname.po"
|
||||
fi
|
||||
done
|
||||
diskNames=( Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB )
|
||||
if (( $gsosInstall == 1 )); then
|
||||
gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/"
|
||||
wget --max-redirect 0 -O files/external/appleii/gsos601/Disk_7_of_7-Apple_II_Setup.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/Disk_7_of_7-Apple_II_Setup.sea.bin
|
||||
elif (( $gsosInstall == 2 )); then
|
||||
gsosURL="http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Software/Operating%20Systems/Apple%20IIGS%20System/Disk%20Images/"
|
||||
diskNames=( Install System.Disk SystemTools1 SystemTools2 SystemTools3 Fonts1 Fonts2 synthLAB )
|
||||
diskWebNames=( Install System%20disk System%20tools%201 System%20tools%202 System%20tools%203 Fonts%201 Fonts%202 Synthlab )
|
||||
elif (( $gsosInstall == 3 )); then
|
||||
gsosURL="ftp://ftp.apple.asimov.net/pub/apple_II/images/gs/os/gsos/Apple_IIGS_System_6.0.3/"
|
||||
fi
|
||||
|
||||
for diskname in ${diskNames[@]}; do
|
||||
outfile="files/external/appleii/gsos60${gsosInstall}/$diskname.po"
|
||||
(( activeDisk++ ))
|
||||
if (( $gsosInstall == 1 )); then
|
||||
wget --max-redirect 0 -O files/external/appleii/gsos601/"Disk_${activeDisk}_of_7-${diskname}.sea.bin" "${gsosURL}Disk_${activeDisk}_of_7-${diskname}.sea.bin"
|
||||
elif (( $gsosInstall == 2 )); then
|
||||
wget -O $outfile "$gsosURL/IIGS%20System%206.0.2%20-%20Disk%20${activeDisk}%20${diskWebNames[$activeDisk-1]}.po"
|
||||
elif (( $gsosInstall == 3 )); then
|
||||
wget -O $outfile "$gsosURL/$diskname.po"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
@ -45,7 +45,7 @@ HOSTNAME=`/bin/hostname`
|
||||
|
||||
# Read in netatalk configuration.
|
||||
if [ -f /etc/default/netatalk ]; then
|
||||
. /etc/default/netatalk
|
||||
. /etc/default/netatalk
|
||||
fi
|
||||
|
||||
# Start Netatalk servers.
|
||||
@ -53,9 +53,9 @@ atalk_startup() {
|
||||
if [ x"$ATALKD_RUN" = x"yes" ]; then
|
||||
|
||||
# Try to load the AppleTalk kernel module if it was intended.
|
||||
if grep -q '^appletalk$' /etc/modules; then
|
||||
if grep -q '^appletalk$' /etc/modules; then
|
||||
/sbin/modprobe appletalk || echo "[could not load appletalk module]"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start atalkd server.
|
||||
/usr/local/sbin/atalkd
|
||||
@ -66,30 +66,30 @@ atalk_startup() {
|
||||
|
||||
echo -n " atalkd"
|
||||
fi
|
||||
|
||||
|
||||
# prepare startup of file services
|
||||
if [ "x$CNID_METAD_RUN" = "xyes" -a -x /usr/local/sbin/cnid_metad ] ; then
|
||||
echo -n " cnid_metad"
|
||||
/usr/local/sbin/cnid_metad $CNID_CONFIG
|
||||
fi
|
||||
|
||||
/usr/local/sbin/cnid_metad $CNID_CONFIG
|
||||
fi
|
||||
|
||||
if [ x"$AFPD_RUN" = x"yes" ]; then
|
||||
/usr/local/sbin/afpd $AFPD_UAMLIST -g $AFPD_GUEST -c $AFPD_MAX_CLIENTS \
|
||||
-n "$ATALK_NAME$ATALK_ZONE"
|
||||
echo -n " afpd"
|
||||
fi
|
||||
|
||||
if [ "x$ATALKD_RUN" = "xyes" ]; then
|
||||
if [ "x$PAPD_RUN" = "xyes" ]; then
|
||||
/usr/local/sbin/papd
|
||||
echo -n " papd"
|
||||
fi
|
||||
if [ "x$ATALKD_RUN" = "xyes" ]; then
|
||||
if [ "x$PAPD_RUN" = "xyes" ]; then
|
||||
/usr/local/sbin/papd
|
||||
echo -n " papd"
|
||||
fi
|
||||
|
||||
if [ x"$TIMELORD_RUN" = x"yes" ]; then
|
||||
/usr/local/sbin/timelord
|
||||
echo -n " timelord"
|
||||
fi
|
||||
fi
|
||||
if [ x"$TIMELORD_RUN" = x"yes" ]; then
|
||||
/usr/local/sbin/timelord
|
||||
echo -n " timelord"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
@ -111,25 +111,25 @@ case "$1" in
|
||||
|
||||
echo -n " cnid_metad"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/cnid_metad
|
||||
|
||||
|
||||
if test -x /usr/local/sbin/papd; then
|
||||
echo -n " papd"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/papd
|
||||
fi
|
||||
|
||||
echo -n " papd"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/papd
|
||||
fi
|
||||
|
||||
if test -x /usr/local/sbin/timelord; then
|
||||
echo -n " timelord"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/timelord
|
||||
fi
|
||||
echo -n " timelord"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/timelord
|
||||
fi
|
||||
|
||||
if test -x /usr/local/sbin/atalkd; then
|
||||
echo -n " atalkd"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd
|
||||
fi
|
||||
|
||||
echo -n " atalkd"
|
||||
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd
|
||||
fi
|
||||
|
||||
echo "."
|
||||
;;
|
||||
|
||||
|
||||
restart)
|
||||
$0 force-reload
|
||||
;;
|
||||
@ -144,7 +144,7 @@ case "$1" in
|
||||
echo "done."
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|force-reload}" >&2
|
||||
exit 1
|
||||
|
114
fix/fix.txt
114
fix/fix.txt
@ -1,114 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo
|
||||
echo "A2SERVER fix: This utility will make a Raspberry Pi SD card boot if it"
|
||||
echo "kernel panics (crashes) on startup after updating its operating system"
|
||||
echo "while A2SERVER is installed."
|
||||
echo
|
||||
echo -n "Continue? "
|
||||
read
|
||||
doFix=
|
||||
if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then
|
||||
while true; do
|
||||
echo
|
||||
echo "If attached, remove the Raspberry Pi's SD card from this computer."
|
||||
echo -n "Press return to continue..."; read; echo
|
||||
|
||||
ls -1 /dev/sd? > /tmp/sd1 2> /dev/null
|
||||
|
||||
echo "Insert the Raspberry Pi's SD card into this computer, using a USB"
|
||||
echo "reader if you don't have an SD slot. If this is a virtual machine,"
|
||||
echo "make sure you select the reader or SD slot from its USB menu."
|
||||
echo -n "Press return to continue..."; read; echo
|
||||
|
||||
ls -1 /dev/sd? > /tmp/sd2 2> /dev/null
|
||||
|
||||
# if exactly one drive has been inserted, exit loop
|
||||
if { ! diff /tmp/sd1 /tmp/sd2 &> /dev/null; }; then
|
||||
# files are different, get dev name
|
||||
if [[ $(wc -c /tmp/sd1 | cut -f 1 -d ' ') -eq 0 ]]; then
|
||||
if [[ $(wc -l /tmp/sd2 | cut -f 1 -d ' ') -eq 1 ]]; then
|
||||
devName=$(cat /tmp/sd2)
|
||||
break
|
||||
else
|
||||
echo "More than one volume seems to have appeared. Trying again..."
|
||||
echo
|
||||
fi
|
||||
else
|
||||
devName=$(grep -v "$(cat /tmp/sd1)" /tmp/sd2)
|
||||
if [[ $(wc -l <<< $devName) -eq 1 ]]; then
|
||||
break
|
||||
else
|
||||
echo "More than one volume seems to have appeared. Trying again..."
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "No SD card found. Trying again..."
|
||||
echo
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
mkdir -p /tmp/sd
|
||||
sudo mount ${devName}6 /tmp/sd
|
||||
|
||||
raspbianDate=$(date -d "$(zcat /tmp/sd/usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 ' --' | rev | cut -f 1-6 -d ' ' | rev)" +%s)
|
||||
doFix=
|
||||
if [[ $raspbianDate -lt 1403204265 ]]; then
|
||||
echo "This doesn't appear to be a version of Raspbian that requires fixing."
|
||||
echo -n "Are you sure you want to continue? "
|
||||
read
|
||||
if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then
|
||||
doFix=1
|
||||
fi
|
||||
else
|
||||
doFix=1
|
||||
fi
|
||||
|
||||
if [[ $doFix ]]; then
|
||||
while read kernelRelease; do
|
||||
kernelReplaced=
|
||||
kernelMajorRelease=$(cut -d '.' -f 1 <<< $kernelRelease)
|
||||
kernelMinorRelease=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
|
||||
kernelPatchRelease=$(cut -d '.' -f 3- <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
|
||||
# if kernel 3.12 below 3.12.25+, delete defective AppleTalk kernel
|
||||
if [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -eq 12 && $kernelPatchRelease -lt 25 ]]; then
|
||||
if [[ -f /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then
|
||||
if [[ $(sha1sum /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d ' ') != "ecb239fc084c36de93f6926e7749b80f6024f269" ]]; then
|
||||
echo "Removing defective AppleTalk module from kernel $kernelRelease..."
|
||||
sudo rm -rf /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk 2> /dev/null
|
||||
wget -qO /tmp/appletalk.ko.gz ${A2SERVER_SCRIPT_URL}files/appletalk-$kernelRelease.ko.gz
|
||||
if [[ $? -eq 0 ]]; then
|
||||
# if we found a prebuilt one on a2server site, so install it
|
||||
gunzip -f /tmp/appletalk.ko.gz
|
||||
sudo mkdir -p /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk
|
||||
sudo mv /tmp/appletalk.ko /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk
|
||||
echo "Installed fixed AppleTalk module for kernel $kernelRelease."
|
||||
kernelReplaced=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done <<< "$(ls -1 /tmp/sd/lib/modules | sort -V)"
|
||||
sudo umount /tmp/sd
|
||||
|
||||
echo kern:$kernelReplaced
|
||||
if [[ $kernelReplaced ]]; then
|
||||
echo
|
||||
echo "All set. Remove your SD card, put it back in your Pi, and boot it."
|
||||
echo
|
||||
echo "You should be able to connect from your Apple II, but if you can't,"
|
||||
echo "log in to your Pi and type 'a2server-setup' to complete the fix."
|
||||
else
|
||||
echo
|
||||
echo "Okey doke. Half done. Remove your SD card, and put it back in your Pi."
|
||||
echo "After it boots, log in and type 'a2server-setup' to complete the fix."
|
||||
fi
|
||||
echo "See the A2SERVER web site at http://ivanx.com/a2server for more help."
|
||||
echo "(You can type 'sudo shutdown -h now' if you're done on this machine.)"
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
|
||||
rm fix &> /dev/null
|
81
install.sh
Executable file
81
install.sh
Executable file
@ -0,0 +1,81 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# install.sh - a2server main installation script
|
||||
#
|
||||
# To the extent possible under law, T. Joseph Carter and Ivan Drucker have
|
||||
# waived all copyright and related or neighboring rights to the a2server
|
||||
# scripts themselves. Software used or installed by these scripts is subject
|
||||
# to other licenses. This work is published from the United States.
|
||||
|
||||
a2serverVersion="1.9.0" # Leave this quoted!
|
||||
|
||||
if test "x$BASH" = "x"; then
|
||||
printf "This script requires bash. Please run\nit as ./install.sh from the source\ndirectory.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find the path of our source directory
|
||||
top_src="$( dirname "${BASH_SOURCE[0]}" )"
|
||||
pushd $top_src >/dev/null
|
||||
top_src="$PWD"
|
||||
popd >/dev/null
|
||||
if [[ ! -f "$top_src/.a2server_source" ]]; then
|
||||
printf "\na2server: cannot find a2server source directory in $top_src.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
noPicoPkg=
|
||||
autoAnswerYes=
|
||||
|
||||
process_args() {
|
||||
while [[ $1 ]]; do
|
||||
if [[ $1 == "-c" ]]; then
|
||||
shift
|
||||
noPicoPkg="-c"
|
||||
elif [[ $1 == "-y" ]]; then
|
||||
shift
|
||||
autoAnswerYes="-y"
|
||||
else
|
||||
shift
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
process_args "$@"
|
||||
|
||||
# FIXME: Show version, changes, config, allow reconfig, etc…
|
||||
"$top_src/scripts/show_changes"
|
||||
cat <<EOF
|
||||
|
||||
Your system will be set up for a2server, providing you with
|
||||
AppleTalk for your Apple IIgs/IIe and Macintosh systems using
|
||||
netatalk, as well as SMB via Samba.
|
||||
|
||||
If a2server is already installed, it will be upgraded to the
|
||||
latest version. It would sure be handy if we had an up to
|
||||
date website to send you to for details. You should harass
|
||||
iKarith about that if you haven't recently.
|
||||
|
||||
A full installation could take quite awhile on very low-end
|
||||
systems like the Raspberry Pi Zero.
|
||||
|
||||
Also, some actions will need to be performed as the root
|
||||
(administrator) user. We are assuming you have access to the
|
||||
sudo command for that.
|
||||
EOF
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
printf "\nContinue? "
|
||||
read
|
||||
if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then
|
||||
[[ $0 == "-bash" ]] && return 2 || exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix any mistakes we've made in previous versions
|
||||
. "$top_src/scripts/fixup"
|
||||
|
||||
# Run the legacy setup script for anything not yet ported
|
||||
if [[ -e "${top_src}/setup/ivan.sh" ]]; then
|
||||
"${top_src}/setup/ivan.sh" "$@"
|
||||
fi
|
@ -1,31 +1,11 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# --- Setting up the share volume
|
||||
|
||||
# 1.3.0: move /media/A2SHARED (pre-1.3.0) to /srv/A2SERVER
|
||||
if [[ -d /media/A2SHARED ]]; then
|
||||
echo "A2SERVER: Moving /media/A2SHARED to /srv/A2SERVER..."
|
||||
sudo /etc/init.d/netatalk stop &> /dev/null
|
||||
sudo /etc/init.d/samba stop &> /dev/null
|
||||
[[ ! -d /srv ]] && sudo mkdir -p /srv
|
||||
sudo mv /media/A2SHARED /srv/A2SERVER
|
||||
sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /usr/local/etc/netatalk/AppleVolumes.default
|
||||
[[ -f /etc/samba/smbd.conf ]] && sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /etc/samba/smbd.conf
|
||||
|
||||
fi
|
||||
|
||||
# skip if we're already set up
|
||||
if [[ -d /srv/A2SERVER ]]; then
|
||||
|
||||
echo "A2SERVER: Shared volume is already prepared for use."
|
||||
|
||||
if [[ ! -d /srv/A2SERVER ]]; then
|
||||
echo "A2SERVER: Preparing the shared files volume..."
|
||||
mygroup="$(id -ng)"
|
||||
sudo install -d -m 755 -u "$USER" -g "$mygroup" "/srv/A2SERVER"
|
||||
else
|
||||
|
||||
echo "A2SERVER: Preparing the shared files volume..."
|
||||
|
||||
sudo mkdir -p /srv/A2SERVER
|
||||
|
||||
sudo chown $USER:$USER /srv/A2SERVER
|
||||
|
||||
echo "A2SERVER: Shared volume is already prepared for use."
|
||||
fi
|
||||
|
@ -1,111 +1,109 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# download and install a2server tools:
|
||||
# mkatinit, mkvolinfo, afptype, afpsync, aliases, nulib2
|
||||
|
||||
# Ensure URL we'll use ends in a /
|
||||
case "$A2SERVER_SCRIPT_URL" in
|
||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||
esac
|
||||
case "$A2SERVER_BINARY_URL" in
|
||||
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
||||
*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;;
|
||||
esac
|
||||
a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/master"
|
||||
a2sBinaryURL="http://blocksfree.com/downloads"
|
||||
|
||||
# Find the path of our source directory
|
||||
top_src="$( dirname "${BASH_SOURCE[0]}" )/.."
|
||||
pushd $top_src >/dev/null
|
||||
top_src="$PWD"
|
||||
popd >/dev/null
|
||||
if [[ ! -f "$top_src/.a2server_source" ]]; then
|
||||
printf "\na2server: cannot find a2server source directory in $top_src.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
useExternalURL=1
|
||||
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
|
||||
|
||||
debianVersion=$(cat /etc/debian_version 2> /dev/null)
|
||||
debianVersion="$(lsb_release -rs)"
|
||||
isRpi=
|
||||
arch=
|
||||
if [[ -f /usr/bin/raspi-config ]]; then
|
||||
isRpi=1
|
||||
arch='rpi'
|
||||
elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then
|
||||
uname_m="$(uname -m)"
|
||||
if [[ $uname_m == "i686" ]]; then
|
||||
arch='debian_x86'
|
||||
elif [[ $uname_m == "x86_64" ]]; then
|
||||
arch='debian_x64'
|
||||
fi
|
||||
isRpi=1
|
||||
arch='rpi'
|
||||
elif [[ "$(lsb_release -ds)" = Debian* ]]; then
|
||||
if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then
|
||||
uname_m="$(uname -m)"
|
||||
if [[ $uname_m == "i686" ]]; then
|
||||
arch='debian_x86'
|
||||
elif [[ $uname_m == "x86_64" ]]; then
|
||||
arch='debian_x64'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
debianName=
|
||||
if [[ $debianVersion ]]; then
|
||||
debianMajor=$(cut -d . -f 1 <<< $debianVersion)
|
||||
if [[ $debianMajor == "9" ]]; then
|
||||
debianName="stretch"
|
||||
elif [[ $debianMajor == "8" ]]; then
|
||||
debianName="jessie"
|
||||
elif [[ $debianMajor == "7" ]]; then
|
||||
debianName="wheezy"
|
||||
else
|
||||
debianName="unknown"
|
||||
fi
|
||||
fi
|
||||
debianName=$(lsb_release -cs)
|
||||
|
||||
echo "A2SERVER: Installing A2SERVER tools..."
|
||||
|
||||
# delete older nulib2 which doesn't correctly handle zero-length forks in GSHK-created archives
|
||||
if hash nulib2 &> /dev/null; then
|
||||
nulib2version=$(nulib2 | sed -n 2p | sed 's|^.*v\([0-9]\)\.\([0-9]\)\.\([0-9]\).*$|\1\2\3|' 2> /dev/null)
|
||||
if (( $nulib2version < 310 )); then
|
||||
sudo apt-get -y purge nulib2 &> /dev/null
|
||||
sudo rm $(command -v nulib2) &> /dev/null
|
||||
fi
|
||||
# FIXME make this sed more robust
|
||||
nulib2version=$(nulib2 | sed -n 2p | sed 's|^.*v\([0-9]\)\.\([0-9]\)\.\([0-9]\).*$|\1\2\3|' 2> /dev/null)
|
||||
if (( $nulib2version < 310 )); then
|
||||
sudo apt-get -y purge nulib2 &> /dev/null
|
||||
sudo rm $(command -v nulib2) &> /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! hash nulib2 &> /dev/null; then
|
||||
|
||||
echo "A2SERVER: Installing nulib2..."
|
||||
echo "A2SERVER: Installing nulib2..."
|
||||
|
||||
cd /tmp
|
||||
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||
{ wget -qO- "${binaryURL}precompiled/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||
fi
|
||||
|
||||
if ! hash nulib2 &> /dev/null; then
|
||||
cd /tmp
|
||||
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||
{ wget -qO- "${a2sBinaryURL}/picopkg/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||
fi
|
||||
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
if ! hash nulib2 &> /dev/null; then
|
||||
|
||||
# Dependencies: build-dep for nulib
|
||||
sudo apt-get -y install build-essential zlib1g-dev
|
||||
sudo apt-get -y clean
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
|
||||
cd /tmp
|
||||
rm -rf /tmp/nulib2 &> /dev/null
|
||||
mkdir /tmp/nulib2
|
||||
cd /tmp/nulib2
|
||||
if [[ $useExternalURL ]]; then
|
||||
wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7efb4d37fedf807416c16d74d51d893ea48a.zip"
|
||||
unzip nulib2-3.1.0a2.zip 2> /dev/null
|
||||
rm nulib2-3.1.0a2.zip &> /dev/null
|
||||
fi
|
||||
if [ ! -d nulib2* ]; then
|
||||
wget -q -O nulib2-3.1.0a2.zip "${binaryURL}external/source/nulib2-3.1.0a2.zip"
|
||||
unzip nulib2-3.1.0a2.zip 2> /dev/null
|
||||
rm nulib2-3.1.0a2.zip &> /dev/null
|
||||
fi
|
||||
cd nulib2*
|
||||
cd nufxlib
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
cd ../nulib2
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
cd
|
||||
rm -rf /tmp/nulib2
|
||||
fi
|
||||
# Dependencies: build-dep for nulib
|
||||
sudo apt-get -y install build-essential zlib1g-dev
|
||||
sudo apt-get -y clean
|
||||
|
||||
cd /tmp
|
||||
rm -rf /tmp/nulib2 &> /dev/null
|
||||
mkdir /tmp/nulib2
|
||||
cd /tmp/nulib2
|
||||
if [[ $useExternalURL ]]; then
|
||||
# nulib2 does not have this tagged so we use github's auto-zipball feature
|
||||
# note: topdir is nulib2-<full hash>
|
||||
# note2: .tar.gz also works
|
||||
wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7ef.zip"
|
||||
unzip nulib2-3.1.0a2.zip 2> /dev/null
|
||||
rm nulib2-3.1.0a2.zip &> /dev/null
|
||||
fi
|
||||
if [ ! -d nulib2* ]; then
|
||||
wget -q -O nulib2-3.1.0a2.zip "${a2sBinaryURL}/source/nulib2-3.1.0a2.zip"
|
||||
unzip nulib2-3.1.0a2.zip 2> /dev/null
|
||||
rm nulib2-3.1.0a2.zip &> /dev/null
|
||||
fi
|
||||
cd nulib2*
|
||||
cd nufxlib
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
cd ../nulib2
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
cd
|
||||
rm -rf /tmp/nulib2
|
||||
fi
|
||||
|
||||
else
|
||||
echo "A2SERVER: Nulib2 has already been installed."
|
||||
echo "A2SERVER: Nulib2 has already been installed."
|
||||
fi
|
||||
|
||||
# download and install The Unarchiver, for expanding Apple disk images
|
||||
@ -113,101 +111,104 @@ fi
|
||||
|
||||
if ! hash unar &> /dev/null; then
|
||||
|
||||
echo "A2SERVER: Installing The Unarchiver..."
|
||||
echo "A2SERVER: Installing The Unarchiver..."
|
||||
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
|
||||
# jessie and later: Just use the unar package
|
||||
if [[ $debianMajor -ge 8 ]]; then
|
||||
sudo apt-get -y install unar
|
||||
sudo apt-get clean
|
||||
fi
|
||||
|
||||
if ! hash unar &> /dev/null; then
|
||||
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||
# Dependencies: for unar
|
||||
sudo apt-get -y install libgnustep-base1.22
|
||||
sudo apt-get clean
|
||||
{ wget -qO- "${binaryURL}precompiled/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||
fi
|
||||
# jessie and later: Just use the unar package
|
||||
if [[ "$debianName" != "wheezy" ]]; then
|
||||
sudo apt-get -y install unar
|
||||
sudo apt-get clean
|
||||
fi
|
||||
|
||||
# If all else fails, compile from source.
|
||||
if ! hash unar &> /dev/null; then
|
||||
if ! hash unar &> /dev/null; then
|
||||
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||
# Dependencies: for unar
|
||||
sudo apt-get -y install libgnustep-base1.22
|
||||
sudo apt-get clean
|
||||
{ wget -qO- "${a2sBinaryURL}/picopkg/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||
fi
|
||||
|
||||
# Dependencies: build-deps for unar
|
||||
sudo apt-get -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip
|
||||
sudo apt-get clean
|
||||
# If all else fails, compile from source.
|
||||
if ! hash unar &> /dev/null; then
|
||||
|
||||
rm -rf /tmp/unar &> /dev/null
|
||||
mkdir /tmp/unar
|
||||
cd /tmp/unar
|
||||
if [[ $useExternalURL ]]; then
|
||||
wget -O unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip
|
||||
unzip -o unar-1.8.1.zip &> /dev/null
|
||||
fi
|
||||
if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob
|
||||
wget -O unar-1.8.1.zip ${binaryURL}external/source/unar-1.8.1.zip
|
||||
unzip -o unar-1.8.1.zip &> /dev/null
|
||||
fi
|
||||
cd *Unarchiver*/XADMaster
|
||||
make -f Makefile.linux
|
||||
sudo mv lsar unar /usr/local/bin
|
||||
cd ../Extra
|
||||
sudo mv lsar.1 unar.1 /usr/local/man/man1
|
||||
cd
|
||||
rm -rf /tmp/unar
|
||||
fi
|
||||
sudo mandb &> /dev/null
|
||||
fi
|
||||
# Dependencies: build-deps for unar
|
||||
sudo apt-get -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip
|
||||
sudo apt-get clean
|
||||
|
||||
rm -rf /tmp/unar &> /dev/null
|
||||
mkdir /tmp/unar
|
||||
cd /tmp/unar
|
||||
if [[ $useExternalURL ]]; then
|
||||
wget -O unar-1.8.1.zip "https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip"
|
||||
unzip -o unar-1.8.1.zip &> /dev/null
|
||||
fi
|
||||
if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob
|
||||
wget -O unar-1.8.1.zip "${a2sBinaryURL}/source/unar-1.8.1.zip"
|
||||
unzip -o unar-1.8.1.zip &> /dev/null
|
||||
fi
|
||||
cd *Unarchiver*/XADMaster
|
||||
make -f Makefile.linux
|
||||
sudo mv lsar unar /usr/local/bin
|
||||
cd ../Extra
|
||||
sudo mv lsar.1 unar.1 /usr/local/man/man1
|
||||
cd
|
||||
rm -rf /tmp/unar
|
||||
fi
|
||||
sudo mandb &> /dev/null
|
||||
fi
|
||||
else
|
||||
echo "A2SERVER: The Unarchiver has already been installed."
|
||||
echo "A2SERVER: The Unarchiver has already been installed."
|
||||
fi
|
||||
|
||||
if ! hash unzip &> /dev/null; then
|
||||
echo "A2SERVER: Installing unzip..."
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
echo "A2SERVER: Installing unzip..."
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
|
||||
# Dependencies: unzip
|
||||
sudo apt-get -y install unzip
|
||||
sudo apt-get clean
|
||||
# Dependencies: unzip
|
||||
sudo apt-get -y install unzip
|
||||
sudo apt-get clean
|
||||
else
|
||||
echo "A2SERVER: unzip has already been installed."
|
||||
echo "A2SERVER: unzip has already been installed."
|
||||
fi
|
||||
|
||||
sudo wget -q -O /usr/local/bin/afpsync "${scriptURL}scripts/tools/afpsync.txt"
|
||||
sudo chmod ugo+x /usr/local/bin/afpsync
|
||||
sudo wget -q -O /usr/local/bin/afptype "${scriptURL}scripts/tools/afptype.txt"
|
||||
sudo chmod ugo+x /usr/local/bin/afptype
|
||||
sudo wget -q -O /usr/local/bin/mkatinit "${scriptURL}scripts/tools/mkatinit.txt"
|
||||
sudo chmod ugo+x /usr/local/bin/mkatinit
|
||||
sudo wget -q -O /usr/local/bin/mkvolinfo "${scriptURL}scripts/tools/mkvolinfo.txt"
|
||||
sudo chmod ugo+x /usr/local/bin/mkvolinfo
|
||||
sudo wget -q -O /usr/local/bin/cppo "${scriptURL}scripts/tools/cppo.txt"
|
||||
sudo chmod ugo+x /usr/local/bin/cppo
|
||||
sudo wget -q -O /usr/local/etc/a2server-help.txt "${scriptURL}scripts/tools/a2server-help.txt"
|
||||
sudo wget -q -O /usr/local/etc/a2server-aliases "${scriptURL}scripts/tools/a2server-aliases.txt"
|
||||
sudo wget -q -O /usr/local/etc/a2serverrc "${scriptURL}scripts/tools/a2serverrc.txt"
|
||||
a2sTools="afpsync afptype mkatinit mkvolinfo cppo debupdate"
|
||||
a2sHelp="a2server-help.txt"
|
||||
a2sConfScripts="a2server-aliases a2serverrc"
|
||||
for _tool in $a2sTools; do
|
||||
sudo install -m 755 "$top_src/scripts/tools/$_tool" "/usr/local/bin/$_tool"
|
||||
done
|
||||
for _help in $a2sHelp; do
|
||||
sudo install -m 644 "$top_src/scripts/tools/$_help" "/usr/local/etc/$_help"
|
||||
done
|
||||
for _confscript in $a2sConfScripts; do
|
||||
sudo install -m 755 "$top_src/scripts/tools/$_confscript" "/usr/local/etc/$_tool"
|
||||
done
|
||||
|
||||
# 1.3.0: a2serverrc is now called from /etc/bash.bashrc,
|
||||
# which in turn calls a2server-aliases
|
||||
grep 'a2server-aliases' /etc/bash.bashrc > /dev/null && \
|
||||
sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc
|
||||
grep 'a2serverrc' /etc/bash.bashrc > /dev/null || \
|
||||
echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc > /dev/null
|
||||
if grep 'a2server-aliases' /etc/bash.bashrc >/dev/null; then
|
||||
sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc
|
||||
fi
|
||||
if ! grep 'a2serverrc' /etc/bash.bashrc >/dev/null; then
|
||||
echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc >/dev/null
|
||||
fi
|
||||
|
||||
motd="/etc/motd"
|
||||
if [[ ! $(grep A2SERVER $motd) ]]; then
|
||||
echo | sudo tee -a $motd > /dev/null
|
||||
echo "Type 'system-shutdown' to turn off A2SERVER." | sudo tee -a $motd > /dev/null
|
||||
echo "Type 'a2server-setup' to configure network boot." | sudo tee -a $motd > /dev/null
|
||||
echo "Type 'a2server-help' for a list of other commands." | sudo tee -a $motd > /dev/null
|
||||
echo | sudo tee -a $motd > /dev/null
|
||||
sudo tee -a $motd >/dev/null <<EOF
|
||||
|
||||
Type 'system-shutdown' to turn off A2SERVER.
|
||||
Type 'a2server-setup' to configure network boot.
|
||||
Type 'a2server-help' for a list of other commands.
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,86 +1,98 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# Set up A2SERVER to support Samba (Windows File Sharing)
|
||||
# this script can also be used if new shares are introduced
|
||||
|
||||
[[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes=
|
||||
autoAnswerYes=
|
||||
if [[ -f /tmp/a2server-autoAnswerYes ]]; then
|
||||
autoAnswerYes=1
|
||||
fi
|
||||
|
||||
if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then
|
||||
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo -n "Should Windows computers be able to connect to A2SERVER? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo -n "Should Windows computers be able to connect to A2SERVER? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
|
||||
echo "A2SERVER: Setting up Windows file sharing..."
|
||||
sudo true
|
||||
echo "A2SERVER: Setting up Windows file sharing..."
|
||||
sudo true
|
||||
|
||||
sudo update-rc.d samba defaults &> /dev/null
|
||||
[[ ! -f /etc/init.d/samba ]] && installSamba=1
|
||||
sudo update-rc.d samba defaults &> /dev/null
|
||||
if [[ ! -f /etc/init.d/samba ]]; then
|
||||
installSamba=1
|
||||
fi
|
||||
|
||||
if (( $installSamba )); then
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
if (( $installSamba )); then
|
||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||
# prepare for installing packages
|
||||
sudo apt-get -y update
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
fi
|
||||
|
||||
# Dependency: samba for Windows/modern Macs
|
||||
# FIXME: Figure out when smbpasswd moved and adjust this as necessary
|
||||
sudo apt-get -y install samba
|
||||
hash smbpasswd &> /dev/null || sudo apt-get -y install samba-common-bin
|
||||
sudo apt-get clean
|
||||
fi
|
||||
# Dependency: samba for Windows/modern Macs
|
||||
# FIXME: Figure out when smbpasswd moved and adjust this as necessary
|
||||
sudo apt-get -y install samba
|
||||
hash smbpasswd &> /dev/null || sudo apt-get -y install samba-common-bin
|
||||
sudo apt-get clean
|
||||
fi
|
||||
|
||||
sudo /etc/init.d/samba start &> /dev/null
|
||||
sudo /etc/init.d/samba start &> /dev/null
|
||||
|
||||
workgroup=$(grep -o "^ workgroup = .*$" /etc/samba/smb.conf 2> /dev/null | cut -c 16-)
|
||||
[[ $workgroup ]] || workgroup="WORKGROUP"
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo "Enter workgroup name (or press return for '${workgroup}'): "
|
||||
read
|
||||
[[ $REPLY ]] && workgroup=$REPLY
|
||||
fi
|
||||
sudo sed -i 's/^ workgroup = .*$/ workgroup = '$workgroup'/' /etc/samba/smb.conf 2> /dev/null
|
||||
sudo sed -i 's/^# security = user/ security = user/' /etc/samba/smb.conf 2> /dev/null
|
||||
workgroup=$(grep -o "^ workgroup = .*$" /etc/samba/smb.conf 2> /dev/null | cut -c 16-)
|
||||
if [[ -z "$workgroup" ]]; then
|
||||
workgroup="WORKGROUP"
|
||||
fi
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo "Enter workgroup name (or press return for '${workgroup}'): "
|
||||
read
|
||||
# FIXME validation?
|
||||
if [[ $REPLY ]]; then
|
||||
workgroup=$REPLY
|
||||
fi
|
||||
fi
|
||||
sudo sed -i 's/^ workgroup = .*$/ workgroup = '$workgroup'/' /etc/samba/smb.conf 2> /dev/null
|
||||
sudo sed -i 's/^# security = user/ security = user/' /etc/samba/smb.conf 2> /dev/null
|
||||
|
||||
# remove GSFILES if no longer serving it
|
||||
if ! grep ^/srv/A2SERVER/GSFILES /usr/local/etc/netatalk/AppleVolumes.default; then
|
||||
sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*\[#\n[#' /etc/samba/smb.conf
|
||||
sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*$#\n#' /etc/samba/smb.conf
|
||||
fi
|
||||
# remove GSFILES if no longer serving it
|
||||
if ! grep ^/srv/A2SERVER/GSFILES /usr/local/etc/netatalk/AppleVolumes.default; then
|
||||
sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*\[#\n[#' /etc/samba/smb.conf
|
||||
sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*$#\n#' /etc/samba/smb.conf
|
||||
fi
|
||||
|
||||
grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | cut -d" " -f2 \
|
||||
| while read sharename; do
|
||||
if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then
|
||||
echo "A2SERVER: $sharename is already set up for Windows file sharing."
|
||||
else
|
||||
echo "[$sharename]" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo " path = /srv/A2SERVER/$sharename" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo " browsable = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo " guest ok = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo " read only = no" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo " create mask = 0666" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo " force user = $USER" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
echo "A2SERVER: $sharename has been set up for Windows file sharing."
|
||||
fi
|
||||
done
|
||||
grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | cut -d" " -f2 \
|
||||
| while read sharename; do
|
||||
if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then
|
||||
echo "A2SERVER: $sharename is already set up for Windows file sharing."
|
||||
else
|
||||
sudo tee -a /etc/samba/smb.conf >/dev/null <<EOF
|
||||
[$sharename]
|
||||
path = /srv/A2SERVER/$sharename
|
||||
browsable = yes
|
||||
guest ok = yes
|
||||
read only = no
|
||||
create mask = 0666
|
||||
force user = $USER
|
||||
EOF
|
||||
echo "A2SERVER: $sharename has been set up for Windows file sharing."
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "A2SERVER: Setting Windows file sharing password to 'apple2'."
|
||||
echo -e 'apple2\napple2' | sudo smbpasswd -s -a $USER
|
||||
echo
|
||||
echo "A2SERVER: Setting Windows file sharing password to 'apple2'."
|
||||
echo -e 'apple2\napple2' | sudo smbpasswd -s -a $USER
|
||||
|
||||
echo
|
||||
echo "A2SERVER: Windows file sharing is now running."
|
||||
else
|
||||
sudo /etc/init.d/samba stop &> /dev/null
|
||||
sudo update-rc.d -f samba remove &> /dev/null
|
||||
echo "A2SERVER: Windows file sharing has been turned off."
|
||||
fi
|
||||
echo
|
||||
echo "A2SERVER: Windows file sharing is now running."
|
||||
else
|
||||
sudo /etc/init.d/samba stop &> /dev/null
|
||||
sudo update-rc.d -f samba remove &> /dev/null
|
||||
echo "A2SERVER: Windows file sharing has been turned off."
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
fi
|
||||
|
@ -1,27 +1,36 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# This script helps when running on the Linux console within a VirtualBox VM.
|
||||
|
||||
echo
|
||||
|
||||
userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':')
|
||||
[[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw=
|
||||
[[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw=
|
||||
isApple2Pw=
|
||||
if [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]]; then
|
||||
isApple2Pw=1
|
||||
fi
|
||||
isRaspberryPw=
|
||||
if [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]]; then
|
||||
isRaspberryPw=1
|
||||
fi
|
||||
|
||||
password="your password"
|
||||
[[ $isApple2Pw ]] && password="'apple2'"
|
||||
[[ $isRaspberryPw ]] && password="'raspberry'"
|
||||
|
||||
isDebian=
|
||||
b_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -d . -f 1 < /etc/debian_version) -ge "7" ) ]] && isDebian=1
|
||||
if [[ "$(lsb_release -ds)" = Debian* ]]; then
|
||||
if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then
|
||||
isDebian=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $isDebian ]]; then
|
||||
if { lspci 2> /dev/null | grep -q VirtualBox; }; then
|
||||
echo "A2SERVER: Disabling VirtualBox console screen blanking..."
|
||||
sudo sed -i 's/^BLANK_DPMS=off/BLANK_DPMS=on/' /etc/kbd/config
|
||||
sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config
|
||||
sudo /etc/init.d/kbd restart &> /dev/null
|
||||
sudo /etc/init.d/console-setup restart &> /dev/null
|
||||
fi
|
||||
if lspci 2>/dev/null | grep -q VirtualBox; then
|
||||
echo "A2SERVER: Disabling VirtualBox console screen blanking..."
|
||||
sudo sed -i 's/^BLANK_DPMS=off/BLANK_DPMS=on/' /etc/kbd/config
|
||||
sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config
|
||||
sudo /etc/init.d/kbd restart &> /dev/null
|
||||
sudo /etc/init.d/console-setup restart &> /dev/null
|
||||
fi
|
||||
fi
|
||||
|
@ -71,7 +71,7 @@ def find_slash_pos(day): # 799 REM Finds position of /
|
||||
for i in range(0,3): # 810 FOR I = 1 TO 3
|
||||
if day[i:i+1] == "/": x = i; break # 820 IF MID$ (DAY$,I,1) = "/" THEN X = I:I = 3
|
||||
# 830 NEXT I
|
||||
return x # 840 RETURN
|
||||
return x # 840 RETURN
|
||||
|
||||
while True: # 999 REM get the user's input and convert
|
||||
if not day:
|
||||
@ -110,7 +110,7 @@ while True: # 999 REM get the user's input
|
||||
mo == 2 and
|
||||
da > 28): x = -1; continue
|
||||
input_ok = True
|
||||
if x != -1: break
|
||||
if x != -1: break
|
||||
else: dow_str = ""; day = ""
|
||||
|
||||
while True:
|
||||
|
35
scripts/compare_version
Executable file
35
scripts/compare_version
Executable file
@ -0,0 +1,35 @@
|
||||
#! /usr/bin/env python3
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=python:
|
||||
|
||||
import sys
|
||||
from pkg_resources import parse_version
|
||||
|
||||
def usage():
|
||||
print("Usage: compare_version <version> <operator> <version>")
|
||||
print(" where operator is one of lt, le, eq, ge, gt, or ne")
|
||||
sys.exit(2)
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
usage()
|
||||
|
||||
ver1 = parse_version(sys.argv[1])
|
||||
ver2 = parse_version(sys.argv[3])
|
||||
|
||||
# I suppose you could do something clever with meta-method mapping here
|
||||
result = False
|
||||
if sys.argv[2] == 'lt':
|
||||
result = ver1 < ver2
|
||||
elif sys.argv[2] == 'le':
|
||||
result = ver1 <= ver2
|
||||
elif sys.argv[2] == 'eq':
|
||||
result = ver1 == ver2
|
||||
elif sys.argv[2] == 'ge':
|
||||
result = ver1 >= ver2
|
||||
elif sys.argv[2] == 'gt':
|
||||
result = ver1 > ver2
|
||||
elif sys.argv[2] == 'ne':
|
||||
result = ver1 != ver2
|
||||
else:
|
||||
usage()
|
||||
|
||||
sys.exit(0 if result else 1)
|
69
scripts/fixup
Executable file
69
scripts/fixup
Executable file
@ -0,0 +1,69 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# fixup - correct any mistakes from previous versions
|
||||
#
|
||||
# To the extent possible under law, T. Joseph Carter and Ivan Drucker have
|
||||
# waived all copyright and related or neighboring rights to the a2server
|
||||
# scripts themselves. Software used or installed by these scripts is subject
|
||||
# to other licenses. This work is published from the United States.
|
||||
|
||||
# The idea behind this script is to prevent other scripts from becoming a
|
||||
# minefield of ancient and deprecated code designed to compensate for other
|
||||
# even more ancient and replaced code that is no longer needed, no longer
|
||||
# useful, and honestly complicates maintenance of that code. Everything here
|
||||
# will explain what it does, when it was put here, and it should remain clear
|
||||
# when the legacy code may be removed.
|
||||
#
|
||||
# The use of functions which get immediately called is to try and prevent the
|
||||
# long spidery conditional blocks a2cloud was originally known for.
|
||||
|
||||
# # Added 2000-00-00
|
||||
# fix_some_stupid_mistake()
|
||||
# {
|
||||
# # Needed until: Upgrades from 0.0.0 no longer supported
|
||||
# :
|
||||
# }
|
||||
# fix_some_stupid_mistake
|
||||
|
||||
|
||||
# Added 2018-09-07
|
||||
move_media_a2shared()
|
||||
{
|
||||
# # Needed until: Upgrades from versions < 1.3.0 are not supported
|
||||
local netatalk_restart
|
||||
if [[ -d /media/A2SHARED ]]; then
|
||||
cat <<-EOF
|
||||
a2server: As of version 1.3.0, the standard location for
|
||||
netatalk to store Apple II files is /srv/A2SERVER.
|
||||
We will move /media/A2SHARED to the new location.
|
||||
If you need to do that yourself (you'll know if
|
||||
you do), press ctrl-c now. Otherwise press Return.
|
||||
EOF
|
||||
read
|
||||
|
||||
# netatalk doesn't much like its sharepoint just disappearing
|
||||
if service netatalk status >/dev/null; then
|
||||
netatalk_restart=1
|
||||
sudo service netatalk stop
|
||||
fi
|
||||
|
||||
# Debated: Create /media/A2SHARED symlink? Nah, bad idea.
|
||||
sudo mv /media/A2SHARED /srv/A2SERVER
|
||||
sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /usr/local/etc/netatalk/AppleVolumes.default
|
||||
if [[ $netatalk_restart ]]; then
|
||||
sudo service netatalk start
|
||||
fi
|
||||
|
||||
# Samba can just be reloaded after modifying the config
|
||||
if [[ -f /etc/samba/smbd.conf ]]; then
|
||||
sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /etc/samba/smbd.conf
|
||||
if service smbd status >/dev/null; then
|
||||
sudo service smbd reload
|
||||
elif service samba status >/dev/null; then
|
||||
sudo service samba reload
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
move_media_a2shared
|
@ -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; } &> /dev/null
|
||||
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; } &> /dev/null
|
||||
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
|
33
scripts/show_changes
Executable file
33
scripts/show_changes
Executable file
@ -0,0 +1,33 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# show_changes - show a2server version differences
|
||||
#
|
||||
# To the extent possible under law, T. Joseph Carter and Ivan Drucker have
|
||||
# waived all copyright and related or neighboring rights to the a2server
|
||||
# scripts themselves. Software used or installed by these scripts is subject
|
||||
# to other licenses. This work is published from the United States.
|
||||
|
||||
# Find the path of our source directory
|
||||
top_src="$( dirname "${BASH_SOURCE[0]}" )/.."
|
||||
pushd $top_src >/dev/null
|
||||
top_src="$PWD"
|
||||
popd >/dev/null
|
||||
if [[ ! -f "$top_src/.a2server_source" ]]; then
|
||||
printf "\na2server: cannot find a2server source directory in $top_src.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
newVersion=$(grep '^a2serverVersion' "$top_src/install.sh" | cut -d '"' -f 2)
|
||||
|
||||
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
|
||||
read installedVersion </usr/local/etc/A2SERVER-version
|
||||
if [[ $installedVersion != *.*.* ]]; then
|
||||
# Deal with old three-digit version
|
||||
installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}"
|
||||
fi
|
||||
fi
|
||||
echo "a2server version available: $newVersion"
|
||||
echo "a2server version installed: ${installedVersion:-None}"
|
||||
|
||||
# FIXME: Do something useful with a changelog perhaps?
|
44
scripts/system_ident
Executable file
44
scripts/system_ident
Executable file
@ -0,0 +1,44 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# system_ident - identify your system for raspple2 if needed
|
||||
#
|
||||
# To the extent possible under law, T. Joseph Carter and Ivan Drucker have
|
||||
# waived all copyright and related or neighboring rights to the a2server
|
||||
# scripts themselves. Software used or installed by these scripts is subject
|
||||
# to other licenses. This work is published from the United States.
|
||||
|
||||
if [[ -z $ras2_os || -z $ras2_arch ]]; then
|
||||
ras2_os="unknown"
|
||||
if hash lsb_release 2>/dev/null; then
|
||||
if [[ -f /usr/bin/raspi-config ]]; then
|
||||
ras2_os="rpi-$(lsb_release -cs)"
|
||||
else
|
||||
case "$(lsb_release -is)" in
|
||||
Debian)
|
||||
ras2_os="debian-$(lsb_release -cs)"
|
||||
;;
|
||||
*)
|
||||
printf "\nUnknown OS with lsb_release\n"
|
||||
lsb_release -a
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
else
|
||||
uname_s="$(uname -s)"
|
||||
case "$uname_s" in
|
||||
Darwin)
|
||||
ras2_os="$uname_s"
|
||||
;;
|
||||
*)
|
||||
printf "\nUnknown OS with uname -s\n$uname_s\n"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ras2_arch="$(uname -m)"
|
||||
export ras2_os ras2_arch
|
||||
fi
|
||||
|
||||
if [[ $1 != -q ]]; then
|
||||
printf "ras2_os=\"%s\"\nras2_arch=\"%s\"\n" "$ras2_os" "$ras2_arch"
|
||||
fi
|
@ -1,19 +1,16 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
alias a2server-help="more /usr/local/etc/a2server-help.txt"
|
||||
alias a2server-setup='wget -q -O /tmp/a2server-setup ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}setup/index.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/a2server-setup'
|
||||
|
||||
|
||||
alias a2server-version="cat /usr/local/etc/A2SERVER-version"
|
||||
alias a2server-update='wget -q -O /tmp/a2server-update ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}update/index.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/a2server-update'
|
||||
|
||||
|
||||
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 raspbian-update='wget -qO /tmp/raspbian-update ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}scripts/raspbian-update.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/raspbian-update'
|
||||
alias rasppleii-update='raspbian-update a2cloud a2server'
|
||||
|
||||
alias welcome-message-edit='sudo nano /etc/motd'
|
||||
|
@ -10,10 +10,7 @@ a2server-update: check for update to A2SERVER
|
||||
system-shutdown: shut down the server
|
||||
system-restart: shut down and restart the server
|
||||
|
||||
Raspberry Pi commands, if you're using one:
|
||||
raspi-config: utilize all space on RPi SD card & other options
|
||||
raspbian-update : update Raspbian operating system
|
||||
rasppleii-update : update Raspbian OS, A2CLOUD, A2SERVER, Apple II Pi
|
||||
debupdate: update the Raspple II operating system
|
||||
|
||||
welcome-message-edit: change the welcome message
|
||||
|
||||
|
4
scripts/tools/a2serverrc
Executable file
4
scripts/tools/a2serverrc
Executable file
@ -0,0 +1,4 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
source /usr/local/etc/a2server-aliases
|
@ -1,6 +0,0 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
|
||||
export A2SERVER_SCRIPT_URL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}"
|
||||
export A2SERVER_BINARY_URL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files/}"
|
||||
source /usr/local/etc/a2server-aliases
|
116
scripts/tools/afpsync
Executable file
116
scripts/tools/afpsync
Executable file
@ -0,0 +1,116 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# afpsync: updates .AppleDouble components of files on shared volumes
|
||||
|
||||
# this must be used if any files are copied to the shared volume via
|
||||
# non-AFP methods (directly, via Samba, etc).
|
||||
|
||||
# usage:
|
||||
# afpsync [-v] [shared volume path]
|
||||
#
|
||||
# -v will silently create a .volinfo file if none exists.
|
||||
# If a path is specified, only that volume is synced; otherwise, all
|
||||
# all paths in /srv/A2SERVER which appear in
|
||||
# /usr/local/etc/netatalk/AppleVolumes.default are synced.
|
||||
|
||||
processPath () {
|
||||
if [[ ! -d $sharepath ]]; then
|
||||
echo "$sharepath does not exist."
|
||||
else
|
||||
volinfo="$sharepath/.AppleDesktop/.volinfo"
|
||||
if [[ ! -f $volinfo ]]; then
|
||||
if [[ ! $force ]]; then
|
||||
echo "Cannot update AppleDouble files for volume $sharepath,"
|
||||
echo "because its .volinfo file does not exist. To create it, log"
|
||||
echo "into the volume from an Apple II or Mac client computer,"
|
||||
echo "or use \"afpsync -v\"."
|
||||
else
|
||||
if (( $1 )); then
|
||||
mkvolinfo -f -c $sharepath
|
||||
else
|
||||
mkvolinfo -f $sharepath
|
||||
fi
|
||||
$0 $sharepath
|
||||
fi
|
||||
else
|
||||
IFS=''
|
||||
result=$(sudo dbd -r $sharepath | grep encoding)
|
||||
f=$(wc -l <<< $result)
|
||||
[[ $(wc -w <<< $result) == 0 ]] && f=0
|
||||
[[ $f -eq 1 && $(grep AppleDesktop <<< "$result") && $(grep MTOULOWER $sharepath/.AppleDesktop/.volinfo) ]] && (( f-- ))
|
||||
if (( f == 0 )); then
|
||||
echo "AppleDouble files have been updated for volume $sharepath."
|
||||
else
|
||||
[[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath."
|
||||
if [[ $showerrors ]]; then
|
||||
echo $result \
|
||||
| while read LINE; do
|
||||
[[ ! $(echo $LINE | grep APPLEDESKTOP) ]] && echo $LINE
|
||||
done
|
||||
elif [[ $renameLower ]]; then
|
||||
echo $result \
|
||||
| while read LINE; do
|
||||
if [[ ! $(echo $LINE | grep APPLEDESKTOP) ]]; then
|
||||
filepath=$(echo $LINE | sed "s/^Bad\ encoding\ for\ '//" | sed s/\'//)
|
||||
filename=${filepath##*/}
|
||||
filedir=${filepath%/*}
|
||||
mv $filepath $filedir/${filename^^}
|
||||
echo "Renamed $filedir/${filename^^}."
|
||||
fi
|
||||
done
|
||||
$0 $sharepath
|
||||
else
|
||||
echo "Use afpsync -e to see error details."
|
||||
fi
|
||||
fi
|
||||
unset IFS
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
while [[ $1 == "-r" || $1 == "-e" || $1 = "-v" ]]; do
|
||||
|
||||
if [[ $1 == "-v" ]]; then
|
||||
force=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $1 == "-e" ]]; then
|
||||
showerrors=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $1 == "-r" ]]; then
|
||||
renameLower=1
|
||||
shift
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if [[ ${1:0:1} == "-" ]]; then
|
||||
echo "Usage: afpsync [-e|-r] [-v] [shared volume path]"
|
||||
echo
|
||||
echo "-e: show error details"
|
||||
echo "-r: rename lowercase filenames to uppercase"
|
||||
echo "-v: create .volinfo file if none exists"
|
||||
echo "If no directory is specified, all found in"
|
||||
echo " /usr/local/etc/netatalk/AppleVolumes.default are processed."
|
||||
echo
|
||||
else
|
||||
sudo true
|
||||
if [[ $1 ]]; then
|
||||
sharepath=$(readlink -m $1)
|
||||
# behavior change in 1.3.0: now defaults to mixed case
|
||||
# on a volume when specifying a folder and -v
|
||||
# (as opposed to defaulting to casefold:toupper previously)
|
||||
processPath 1
|
||||
else
|
||||
grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \
|
||||
while read line; do
|
||||
[[ $(echo $line | grep toupper) ]]; nocasefold=$?
|
||||
sharepath=$(echo $line | cut -d" " -f1)
|
||||
processPath nocasefold
|
||||
done
|
||||
fi
|
||||
fi
|
@ -1,116 +0,0 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
|
||||
# afpsync: updates .AppleDouble components of files on shared volumes
|
||||
|
||||
# this must be used if any files are copied to the shared volume via
|
||||
# non-AFP methods (directly, via Samba, etc).
|
||||
|
||||
# usage:
|
||||
# afpsync [-v] [shared volume path]
|
||||
#
|
||||
# -v will silently create a .volinfo file if none exists.
|
||||
# If a path is specified, only that volume is synced; otherwise, all
|
||||
# all paths in /srv/A2SERVER which appear in
|
||||
# /usr/local/etc/netatalk/AppleVolumes.default are synced.
|
||||
|
||||
processPath () {
|
||||
if [[ ! -d $sharepath ]]; then
|
||||
echo "$sharepath does not exist."
|
||||
else
|
||||
volinfo="$sharepath/.AppleDesktop/.volinfo"
|
||||
if [[ ! -f $volinfo ]]; then
|
||||
if [[ ! $force ]]; then
|
||||
echo "Cannot update AppleDouble files for volume $sharepath,"
|
||||
echo "because its .volinfo file does not exist. To create it, log"
|
||||
echo "into the volume from an Apple II or Mac client computer,"
|
||||
echo "or use \"afpsync -v\"."
|
||||
else
|
||||
if (( $1 )); then
|
||||
mkvolinfo -f -c $sharepath
|
||||
else
|
||||
mkvolinfo -f $sharepath
|
||||
fi
|
||||
$0 $sharepath
|
||||
fi
|
||||
else
|
||||
IFS=''
|
||||
result=$(sudo dbd -r $sharepath | grep encoding)
|
||||
f=$(wc -l <<< $result)
|
||||
[[ $(wc -w <<< $result) == 0 ]] && f=0
|
||||
[[ $f -eq 1 && $(grep AppleDesktop <<< "$result") && $(grep MTOULOWER $sharepath/.AppleDesktop/.volinfo) ]] && (( f-- ))
|
||||
if (( f == 0 )); then
|
||||
echo "AppleDouble files have been updated for volume $sharepath."
|
||||
else
|
||||
[[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath."
|
||||
if [[ $showerrors ]]; then
|
||||
echo $result \
|
||||
| while read LINE; do
|
||||
[[ ! $(echo $LINE | grep APPLEDESKTOP) ]] && echo $LINE
|
||||
done
|
||||
elif [[ $renameLower ]]; then
|
||||
echo $result \
|
||||
| while read LINE; do
|
||||
if [[ ! $(echo $LINE | grep APPLEDESKTOP) ]]; then
|
||||
filepath=$(echo $LINE | sed "s/^Bad\ encoding\ for\ '//" | sed s/\'//)
|
||||
filename=${filepath##*/}
|
||||
filedir=${filepath%/*}
|
||||
mv $filepath $filedir/${filename^^}
|
||||
echo "Renamed $filedir/${filename^^}."
|
||||
fi
|
||||
done
|
||||
$0 $sharepath
|
||||
else
|
||||
echo "Use afpsync -e to see error details."
|
||||
fi
|
||||
fi
|
||||
unset IFS
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
while [[ $1 == "-r" || $1 == "-e" || $1 = "-v" ]]; do
|
||||
|
||||
if [[ $1 == "-v" ]]; then
|
||||
force=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $1 == "-e" ]]; then
|
||||
showerrors=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $1 == "-r" ]]; then
|
||||
renameLower=1
|
||||
shift
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if [[ ${1:0:1} == "-" ]]; then
|
||||
echo "Usage: afpsync [-e|-r] [-v] [shared volume path]"
|
||||
echo
|
||||
echo "-e: show error details"
|
||||
echo "-r: rename lowercase filenames to uppercase"
|
||||
echo "-v: create .volinfo file if none exists"
|
||||
echo "If no directory is specified, all found in"
|
||||
echo " /usr/local/etc/netatalk/AppleVolumes.default are processed."
|
||||
echo
|
||||
else
|
||||
sudo true
|
||||
if [[ $1 ]]; then
|
||||
sharepath=$(readlink -m $1)
|
||||
# behavior change in 1.3.0: now defaults to mixed case
|
||||
# on a volume when specifying a folder and -v
|
||||
# (as opposed to defaulting to casefold:toupper previously)
|
||||
processPath 1
|
||||
else
|
||||
grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \
|
||||
while read line; do
|
||||
[[ $(echo $line | grep toupper) ]]; nocasefold=$?
|
||||
sharepath=$(echo $line | cut -d" " -f1)
|
||||
processPath nocasefold
|
||||
done
|
||||
fi
|
||||
fi
|
498
scripts/tools/afptype
Executable file
498
scripts/tools/afptype
Executable file
@ -0,0 +1,498 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# 2-25-11: tested on 10.6.5 and Ubuntu 10.10. Final.
|
||||
|
||||
# to do: allow hex offsets
|
||||
|
||||
# These bash functions perform single-byte dec-hex-character conversions
|
||||
# and file read/write operations, and hopefully work identically across
|
||||
# different platforms. Each can operate by itself without the presence
|
||||
# of the others. They have been tested on Mac OS X 10.6 and
|
||||
# Ubuntu Linux 10.10. Your mileage may vary.
|
||||
|
||||
# You provide parameters to the functions as arguments, or alternatively
|
||||
# standard in (for the functions which accept characters). Examples:
|
||||
# Write hex byte with value "F0" to offset 23 in file "myFile":
|
||||
# writecharHex myFile 23 F0
|
||||
# Write "ABCDE" to the beginning of file "myFile"
|
||||
# echo "ABCDE" | writechars myFile
|
||||
|
||||
# For functions which output something (all but the write operations),
|
||||
# you can call the functions with command substitution if you want to
|
||||
# assign the output to a variable rather than display it. Examples:
|
||||
# Convert decimal value 65 to its hexadecimal equivalent:
|
||||
# val=$(decToHex 65)
|
||||
# Get decimal value of the character/byte at offset 215 in "myFile":
|
||||
# val=$(readcharDec "myFile" 215)
|
||||
|
||||
# For functions which convert to or from a character, 0-127 will be
|
||||
# ASCII/UTF-8, while 128-255 will be system/locale/codepage dependent.
|
||||
# In this context, a character is effectively the same as a byte.
|
||||
|
||||
# The functions return a non-zero exit status for invalid or missing
|
||||
# arguments. If you don't need these checks, remove the lines
|
||||
# above the comment "args are valid" (or as otherwise noted).
|
||||
# The exit statuses are, generally:
|
||||
# 0 = no error
|
||||
# 8 = extraneous argument
|
||||
# 9 = standard input is invalid
|
||||
# 1x = missing required argument (e.g. 11 for missing argument 1)
|
||||
# 2x = argument is invalid (e.g. 22 for invalid argument 2)
|
||||
# any other exit status will originate from the final command in the
|
||||
# function (e.g. dd, printf)
|
||||
|
||||
# For the functions which output chars (readchars, decToChar, and
|
||||
# hexToChar), be aware that NUL (0) and trailing LF (10/0x0A) chars will
|
||||
# be stripped when assigned to a variable, and cannot appear in an
|
||||
# argument. To preserve them, pipe the output elsewhere, such as into
|
||||
# charToDec, charToHex, writechars, or a command. (readcharDec and
|
||||
# readcharHex handle these characters correctly.)
|
||||
|
||||
# questions/comments to ivan@ivanx.com
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
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 | tr -d ' \0'
|
||||
}
|
||||
|
||||
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 | tr -d '\0'; 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 | tr -d '\0'; 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
|
||||
}
|
||||
|
||||
|
||||
# --- afptype is below this line
|
||||
|
||||
isHexByte () {
|
||||
[[ $(printf %02X "0x$1" 2> /dev/null) == \
|
||||
$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 1
|
||||
}
|
||||
|
||||
# support 00 and 0A as filetype chars?
|
||||
|
||||
debug=1
|
||||
ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS"
|
||||
|
||||
quit () {
|
||||
if [[ $2 && $debug ]]; then
|
||||
echo "$1" "$2"
|
||||
else
|
||||
echo -e "Error: $1"
|
||||
fi
|
||||
exit_usage
|
||||
}
|
||||
|
||||
exit_usage () {
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo "show types: afptype filename"
|
||||
echo "set Mac OS: afptype [-t 'type'] [-c 'creator'] [-q] filename"
|
||||
echo "set ProDOS: afptype [-p type] [-a auxtype] [-q] filename"
|
||||
echo "Mac OS type or creator must be four characters; use \x plus"
|
||||
echo " two hex digits for untypeables (note: use '\xZZ' for 00)."
|
||||
echo "ProDOS type should be two hex digits, and auxtype should be four;"
|
||||
echo " type can alternatively be BAS, BIN, INT, P16, S16, SHK, SYS, TXT."
|
||||
echo "-q skips recheck of file (show types) after setting"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
lookupPdosType () {
|
||||
# looks up ProDOS hex type from code in list 'ptypes'
|
||||
# arg: three-character code
|
||||
# out: two-digit hex value
|
||||
#exit: 0=type found, 1=error, 2=type not found
|
||||
ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS"
|
||||
[[ $1 ]] || quit "lookupPdosType:" "no argument supplied ($1)"
|
||||
[[ ${#1} -eq 3 ]] || return 1
|
||||
arg=$(echo -n "$1" | tr [a-z] [A-Z])
|
||||
for ptype in $ptypes; do
|
||||
if [[ ${ptype:3:3} == $arg ]]; then
|
||||
echo -n "${ptype:0:2}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "$1"
|
||||
return 1
|
||||
}
|
||||
|
||||
verifyTC () {
|
||||
[[ $1 ]] || return 1
|
||||
tcX="$(echo -e -n "$1"X)"
|
||||
[[ ${#tcX} -eq 5 ]] || return 1
|
||||
echo "$tcX"
|
||||
}
|
||||
|
||||
while [[ $1 && ( "${1:0:1}" == '-' ) ]]; do
|
||||
if [[ $1 == "-p" ]]; then
|
||||
[[ $p ]] && exit_usage
|
||||
shift
|
||||
p="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-a" ]]; then
|
||||
[[ $a ]] && exit_usage
|
||||
shift
|
||||
a="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-t" ]]; then
|
||||
[[ $t ]] && exit_usage
|
||||
shift
|
||||
t="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-c" ]]; then
|
||||
[[ $c ]] && exit_usage
|
||||
shift
|
||||
c="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-q" ]]; then
|
||||
[[ $q ]] && exit_usage
|
||||
q=1
|
||||
shift
|
||||
continue
|
||||
else
|
||||
exit_usage
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ( ( $p || $a ) && ( $t || $c ) ) || ( -z $1 ) ]]; then
|
||||
exit_usage
|
||||
fi
|
||||
|
||||
#filename="$1"
|
||||
#shift
|
||||
|
||||
for filename in $@; do
|
||||
|
||||
[[ ${#@} -gt 1 ]] && linestart="($filename) "
|
||||
|
||||
if [[ ! -f $filename ]]; then
|
||||
echo "${linestart}Not found."
|
||||
continue
|
||||
fi
|
||||
|
||||
adname="$(dirname "$filename")/.AppleDouble/$(basename "$filename")"
|
||||
[[ -f $adname ]] && filename=$adname
|
||||
ADversion=$(readcharDec "$filename" 5)
|
||||
if [[ ( ( $ADversion -ne 1 ) && ( $ADversion -ne 2 ) ) \
|
||||
|| ( "$(readchars "$filename" 1 3)" != "$(echo -e -n "\x05\x16\x07")" ) \
|
||||
|| ( $(readcharDec "$filename" 0) -ne 0 ) \
|
||||
|| ( $(readcharDec "$filename" 4) -ne 0 ) \
|
||||
|| ( $(readcharDec "$filename" 6) -ne 0 ) \
|
||||
|| ( $(readcharDec "$filename" 7) -ne 0 ) ]]; then
|
||||
echo "${linestart}Not an AppleDouble file."
|
||||
continue
|
||||
fi
|
||||
|
||||
entrycount=`readcharDec "$filename" 25`
|
||||
|
||||
entry=1
|
||||
offset=29
|
||||
|
||||
while [[ $(readcharDec "$filename" $offset) -ne 9 ]]; do
|
||||
(( entry = entry + 1 ))
|
||||
if (( entry > entrycount )); then
|
||||
echo "${linestart}Finder Info entry not found in AppleDouble file."
|
||||
break
|
||||
fi
|
||||
(( offset = (entry * 12 + 29) - 12 ))
|
||||
done
|
||||
(( entry > entrycount )) && continue
|
||||
|
||||
(( offset = offset + 3 ))
|
||||
(( tposHi = $(readcharDec "$filename" $offset) * 256 ))
|
||||
(( offset = offset + 1 ))
|
||||
(( tpos = $(readcharDec "$filename" $offset) + tposHi ))
|
||||
(( cpos = tpos + 4 ))
|
||||
(( ppos = tpos + 1 ))
|
||||
(( apos = tpos + 2 ))
|
||||
|
||||
if [[ $p || $a || $t || $c ]]; then # set
|
||||
if [[ $p || $a ]]; then
|
||||
if [[ $p ]]; then
|
||||
[[ ${#p} -eq 3 ]] && { p=$(lookupPdosType $p) || quit "Invalid ProDOS type name ($p)."; }
|
||||
isHexByte "$p" || quit "Invalid ProDOS file type ($p)."
|
||||
writecharHex "$filename" $ppos "$p"
|
||||
fi
|
||||
if [[ $a ]]; then
|
||||
isHexByte "${a:0:2}" && isHexByte "${a:2:2}" || quit "Invalid ProDOS aux type ($a)."
|
||||
writecharHex "$filename" $apos "${a:0:2}"
|
||||
(( apos=apos+1 ))
|
||||
writecharHex "$filename" $apos "${a:2:2}"
|
||||
fi
|
||||
writechars "$filename" $tpos "p"
|
||||
writechars "$filename" $cpos "pdos"
|
||||
elif [[ $t || $c ]]; then
|
||||
if [[ $t ]]; then
|
||||
type=$(verifyTC "$t") || quit "$(echo -n "Invalid Mac file type ($t)."; [[ $t == *x* ]] && echo -n " Try quotes."; echo)"
|
||||
writechars "$filename" $tpos "${type:0:4}"
|
||||
fi
|
||||
if [[ $c ]]; then
|
||||
creator=$(verifyTC "$c") || quit "$(echo -n "Invalid Mac file creator ($c)."; [[ $c == *x* ]] && echo -n " Try quotes."; echo)"
|
||||
writechars "$filename" $cpos "${creator:0:4}"
|
||||
fi
|
||||
fi
|
||||
[[ $q ]] || { echo -n "${linestart}File changed: "; "$0" "$filename"; }
|
||||
|
||||
else # show
|
||||
[[ $q ]] && quit "Can only use -q when changing type."
|
||||
|
||||
type="$(readchars "$filename" $tpos 4)"
|
||||
creator="$(readchars "$filename" $cpos 4)"
|
||||
|
||||
echo -n "$linestart"
|
||||
|
||||
if [[ $creator != "pdos" || ( ( $type != "TEXT" ) \
|
||||
&& ( $type != "PSYS" ) && ( ${type:0:1} != "p" ) ) ]]; then
|
||||
if [[ $creator || $type ]]; then
|
||||
echo "Mac file. Type:$type Creator:$creator"
|
||||
else
|
||||
echo "This file has no Mac or ProDOS file type information."
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ $type == "TEXT" ]]; then
|
||||
pdosType="\$04 [TXT]"
|
||||
pdosAuxType='$0000'
|
||||
elif [[ $type == "PSYS" ]]; then
|
||||
pdosType="\$FF [SYS]"
|
||||
pdosAuxType='$0000'
|
||||
else
|
||||
(( tpos=tpos+1 ))
|
||||
pdosType=$(readcharHex "$filename" $tpos)
|
||||
for ptype in $ptypes; do
|
||||
if [[ "${ptype:0:2}" == "$pdosType" ]]; then
|
||||
pdosType="$pdosType [${ptype:3:3}]"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
(( tpos=tpos+1 ))
|
||||
auxTypeHi=$(readcharHex "$filename" $tpos)
|
||||
(( tpos=tpos+1 ))
|
||||
auxTypeLo=$(readcharHex "$filename" $tpos)
|
||||
pdosAuxType=$auxTypeHi$auxTypeLo
|
||||
fi
|
||||
|
||||
echo "ProDOS file. Type:\$$pdosType AuxType:\$$pdosAuxType"
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# 7-19-11
|
||||
# quick ProDOS testing/fixing on Linux, needs more
|
||||
# Mac Type testing not done yet, nor testing on a Mac
|
||||
|
||||
# test on lunix
|
||||
# test inside and outside of AD directory, and from other dirs (both cases)
|
||||
# finish conversion writebyte/readchar library
|
||||
# consider return 2 for missing parameters for subroutines
|
@ -1,498 +0,0 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
|
||||
# 2-25-11: tested on 10.6.5 and Ubuntu 10.10. Final.
|
||||
|
||||
# to do: allow hex offsets
|
||||
|
||||
# These bash functions perform single-byte dec-hex-character conversions
|
||||
# and file read/write operations, and hopefully work identically across
|
||||
# different platforms. Each can operate by itself without the presence
|
||||
# of the others. They have been tested on Mac OS X 10.6 and
|
||||
# Ubuntu Linux 10.10. Your mileage may vary.
|
||||
|
||||
# You provide parameters to the functions as arguments, or alternatively
|
||||
# standard in (for the functions which accept characters). Examples:
|
||||
# Write hex byte with value "F0" to offset 23 in file "myFile":
|
||||
# writecharHex myFile 23 F0
|
||||
# Write "ABCDE" to the beginning of file "myFile"
|
||||
# echo "ABCDE" | writechars myFile
|
||||
|
||||
# For functions which output something (all but the write operations),
|
||||
# you can call the functions with command substitution if you want to
|
||||
# assign the output to a variable rather than display it. Examples:
|
||||
# Convert decimal value 65 to its hexadecimal equivalent:
|
||||
# val=$(decToHex 65)
|
||||
# Get decimal value of the character/byte at offset 215 in "myFile":
|
||||
# val=$(readcharDec "myFile" 215)
|
||||
|
||||
# For functions which convert to or from a character, 0-127 will be
|
||||
# ASCII/UTF-8, while 128-255 will be system/locale/codepage dependent.
|
||||
# In this context, a character is effectively the same as a byte.
|
||||
|
||||
# The functions return a non-zero exit status for invalid or missing
|
||||
# arguments. If you don't need these checks, remove the lines
|
||||
# above the comment "args are valid" (or as otherwise noted).
|
||||
# The exit statuses are, generally:
|
||||
# 0 = no error
|
||||
# 8 = extraneous argument
|
||||
# 9 = standard input is invalid
|
||||
# 1x = missing required argument (e.g. 11 for missing argument 1)
|
||||
# 2x = argument is invalid (e.g. 22 for invalid argument 2)
|
||||
# any other exit status will originate from the final command in the
|
||||
# function (e.g. dd, printf)
|
||||
|
||||
# For the functions which output chars (readchars, decToChar, and
|
||||
# hexToChar), be aware that NUL (0) and trailing LF (10/0x0A) chars will
|
||||
# be stripped when assigned to a variable, and cannot appear in an
|
||||
# argument. To preserve them, pipe the output elsewhere, such as into
|
||||
# charToDec, charToHex, writechars, or a command. (readcharDec and
|
||||
# readcharHex handle these characters correctly.)
|
||||
|
||||
# questions/comments to ivan@ivanx.com
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
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 | tr -d ' \0'
|
||||
}
|
||||
|
||||
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 | tr -d '\0'; 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 | tr -d '\0'; 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
|
||||
}
|
||||
|
||||
|
||||
# --- afptype is below this line
|
||||
|
||||
isHexByte () {
|
||||
[[ $(printf %02X "0x$1" 2> /dev/null) == \
|
||||
$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 1
|
||||
}
|
||||
|
||||
# support 00 and 0A as filetype chars?
|
||||
|
||||
debug=1
|
||||
ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS"
|
||||
|
||||
quit () {
|
||||
if [[ $2 && $debug ]]; then
|
||||
echo "$1" "$2"
|
||||
else
|
||||
echo -e "Error: $1"
|
||||
fi
|
||||
exit_usage
|
||||
}
|
||||
|
||||
exit_usage () {
|
||||
echo "Usage:"
|
||||
echo
|
||||
echo "show types: afptype filename"
|
||||
echo "set Mac OS: afptype [-t 'type'] [-c 'creator'] [-q] filename"
|
||||
echo "set ProDOS: afptype [-p type] [-a auxtype] [-q] filename"
|
||||
echo "Mac OS type or creator must be four characters; use \x plus"
|
||||
echo " two hex digits for untypeables (note: use '\xZZ' for 00)."
|
||||
echo "ProDOS type should be two hex digits, and auxtype should be four;"
|
||||
echo " type can alternatively be BAS, BIN, INT, P16, S16, SHK, SYS, TXT."
|
||||
echo "-q skips recheck of file (show types) after setting"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
lookupPdosType () {
|
||||
# looks up ProDOS hex type from code in list 'ptypes'
|
||||
# arg: three-character code
|
||||
# out: two-digit hex value
|
||||
#exit: 0=type found, 1=error, 2=type not found
|
||||
ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS"
|
||||
[[ $1 ]] || quit "lookupPdosType:" "no argument supplied ($1)"
|
||||
[[ ${#1} -eq 3 ]] || return 1
|
||||
arg=$(echo -n "$1" | tr [a-z] [A-Z])
|
||||
for ptype in $ptypes; do
|
||||
if [[ ${ptype:3:3} == $arg ]]; then
|
||||
echo -n "${ptype:0:2}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "$1"
|
||||
return 1
|
||||
}
|
||||
|
||||
verifyTC () {
|
||||
[[ $1 ]] || return 1
|
||||
tcX="$(echo -e -n "$1"X)"
|
||||
[[ ${#tcX} -eq 5 ]] || return 1
|
||||
echo "$tcX"
|
||||
}
|
||||
|
||||
while [[ $1 && ( "${1:0:1}" == '-' ) ]]; do
|
||||
if [[ $1 == "-p" ]]; then
|
||||
[[ $p ]] && exit_usage
|
||||
shift
|
||||
p="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-a" ]]; then
|
||||
[[ $a ]] && exit_usage
|
||||
shift
|
||||
a="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-t" ]]; then
|
||||
[[ $t ]] && exit_usage
|
||||
shift
|
||||
t="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-c" ]]; then
|
||||
[[ $c ]] && exit_usage
|
||||
shift
|
||||
c="$1"
|
||||
shift
|
||||
continue
|
||||
elif [[ $1 == "-q" ]]; then
|
||||
[[ $q ]] && exit_usage
|
||||
q=1
|
||||
shift
|
||||
continue
|
||||
else
|
||||
exit_usage
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ( ( $p || $a ) && ( $t || $c ) ) || ( -z $1 ) ]]; then
|
||||
exit_usage
|
||||
fi
|
||||
|
||||
#filename="$1"
|
||||
#shift
|
||||
|
||||
for filename in $@; do
|
||||
|
||||
[[ ${#@} -gt 1 ]] && linestart="($filename) "
|
||||
|
||||
if [[ ! -f $filename ]]; then
|
||||
echo "${linestart}Not found."
|
||||
continue
|
||||
fi
|
||||
|
||||
adname="$(dirname "$filename")/.AppleDouble/$(basename "$filename")"
|
||||
[[ -f $adname ]] && filename=$adname
|
||||
ADversion=$(readcharDec "$filename" 5)
|
||||
if [[ ( ( $ADversion -ne 1 ) && ( $ADversion -ne 2 ) ) \
|
||||
|| ( "$(readchars "$filename" 1 3)" != "$(echo -e -n "\x05\x16\x07")" ) \
|
||||
|| ( $(readcharDec "$filename" 0) -ne 0 ) \
|
||||
|| ( $(readcharDec "$filename" 4) -ne 0 ) \
|
||||
|| ( $(readcharDec "$filename" 6) -ne 0 ) \
|
||||
|| ( $(readcharDec "$filename" 7) -ne 0 ) ]]; then
|
||||
echo "${linestart}Not an AppleDouble file."
|
||||
continue
|
||||
fi
|
||||
|
||||
entrycount=`readcharDec "$filename" 25`
|
||||
|
||||
entry=1
|
||||
offset=29
|
||||
|
||||
while [[ $(readcharDec "$filename" $offset) -ne 9 ]]; do
|
||||
(( entry = entry + 1 ))
|
||||
if (( entry > entrycount )); then
|
||||
echo "${linestart}Finder Info entry not found in AppleDouble file."
|
||||
break
|
||||
fi
|
||||
(( offset = (entry * 12 + 29) - 12 ))
|
||||
done
|
||||
(( entry > entrycount )) && continue
|
||||
|
||||
(( offset = offset + 3 ))
|
||||
(( tposHi = $(readcharDec "$filename" $offset) * 256 ))
|
||||
(( offset = offset + 1 ))
|
||||
(( tpos = $(readcharDec "$filename" $offset) + tposHi ))
|
||||
(( cpos = tpos + 4 ))
|
||||
(( ppos = tpos + 1 ))
|
||||
(( apos = tpos + 2 ))
|
||||
|
||||
if [[ $p || $a || $t || $c ]]; then # set
|
||||
if [[ $p || $a ]]; then
|
||||
if [[ $p ]]; then
|
||||
[[ ${#p} -eq 3 ]] && { p=$(lookupPdosType $p) || quit "Invalid ProDOS type name ($p)."; }
|
||||
isHexByte "$p" || quit "Invalid ProDOS file type ($p)."
|
||||
writecharHex "$filename" $ppos "$p"
|
||||
fi
|
||||
if [[ $a ]]; then
|
||||
isHexByte "${a:0:2}" && isHexByte "${a:2:2}" || quit "Invalid ProDOS aux type ($a)."
|
||||
writecharHex "$filename" $apos "${a:0:2}"
|
||||
(( apos=apos+1 ))
|
||||
writecharHex "$filename" $apos "${a:2:2}"
|
||||
fi
|
||||
writechars "$filename" $tpos "p"
|
||||
writechars "$filename" $cpos "pdos"
|
||||
elif [[ $t || $c ]]; then
|
||||
if [[ $t ]]; then
|
||||
type=$(verifyTC "$t") || quit "$(echo -n "Invalid Mac file type ($t)."; [[ $t == *x* ]] && echo -n " Try quotes."; echo)"
|
||||
writechars "$filename" $tpos "${type:0:4}"
|
||||
fi
|
||||
if [[ $c ]]; then
|
||||
creator=$(verifyTC "$c") || quit "$(echo -n "Invalid Mac file creator ($c)."; [[ $c == *x* ]] && echo -n " Try quotes."; echo)"
|
||||
writechars "$filename" $cpos "${creator:0:4}"
|
||||
fi
|
||||
fi
|
||||
[[ $q ]] || { echo -n "${linestart}File changed: "; "$0" "$filename"; }
|
||||
|
||||
else # show
|
||||
[[ $q ]] && quit "Can only use -q when changing type."
|
||||
|
||||
type="$(readchars "$filename" $tpos 4)"
|
||||
creator="$(readchars "$filename" $cpos 4)"
|
||||
|
||||
echo -n "$linestart"
|
||||
|
||||
if [[ $creator != "pdos" || ( ( $type != "TEXT" ) \
|
||||
&& ( $type != "PSYS" ) && ( ${type:0:1} != "p" ) ) ]]; then
|
||||
if [[ $creator || $type ]]; then
|
||||
echo "Mac file. Type:$type Creator:$creator"
|
||||
else
|
||||
echo "This file has no Mac or ProDOS file type information."
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ $type == "TEXT" ]]; then
|
||||
pdosType="\$04 [TXT]"
|
||||
pdosAuxType='$0000'
|
||||
elif [[ $type == "PSYS" ]]; then
|
||||
pdosType="\$FF [SYS]"
|
||||
pdosAuxType='$0000'
|
||||
else
|
||||
(( tpos=tpos+1 ))
|
||||
pdosType=$(readcharHex "$filename" $tpos)
|
||||
for ptype in $ptypes; do
|
||||
if [[ "${ptype:0:2}" == "$pdosType" ]]; then
|
||||
pdosType="$pdosType [${ptype:3:3}]"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
(( tpos=tpos+1 ))
|
||||
auxTypeHi=$(readcharHex "$filename" $tpos)
|
||||
(( tpos=tpos+1 ))
|
||||
auxTypeLo=$(readcharHex "$filename" $tpos)
|
||||
pdosAuxType=$auxTypeHi$auxTypeLo
|
||||
fi
|
||||
|
||||
echo "ProDOS file. Type:\$$pdosType AuxType:\$$pdosAuxType"
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# 7-19-11
|
||||
# quick ProDOS testing/fixing on Linux, needs more
|
||||
# Mac Type testing not done yet, nor testing on a Mac
|
||||
|
||||
# test on lunix
|
||||
# test inside and outside of AD directory, and from other dirs (both cases)
|
||||
# finish conversion writebyte/readchar library
|
||||
# consider return 2 for missing parameters for subroutines
|
1417
scripts/tools/cppo
Executable file
1417
scripts/tools/cppo
Executable file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
165
scripts/tools/debupdate
Executable file
165
scripts/tools/debupdate
Executable file
@ -0,0 +1,165 @@
|
||||
#!/bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# debupdate - Upgrades packages on a Debian-based system
|
||||
# Written in 2016 by T. Joseph Carter <tjcarter@spiritsubstance.com>
|
||||
# Based on raspbian-update by Ivan Drucker <ivan@ivanx.com>
|
||||
#
|
||||
# To the extent possible under law, the author(s) have dedicated all copyright
|
||||
# and related and neighboring rights to this software to the public domain
|
||||
# worldwide. This software is distributed without any warranty.
|
||||
#
|
||||
# You should have received a copy of the CC0 Public Domain Dedication along
|
||||
# with this software. If not, you may find a copy here:
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
|
||||
PROGNAME="$0"
|
||||
PROGRAM="debupdate"
|
||||
VERSION="0.9.0"
|
||||
|
||||
useAptGet=
|
||||
useAutoClean=
|
||||
autoYes=
|
||||
|
||||
aptitudeUpgradeArgs="--allow-new-upgrades --allow-new-installs safe-upgrade"
|
||||
aptGetUpgradeArgs="--with-new-pkgs --auto-remove upgrade"
|
||||
|
||||
ShowLicense() {
|
||||
printf "%s version %s
|
||||
Upgrades packages on a Debian-based system
|
||||
|
||||
Written in 2016 by T. Joseph Carter <tjcarter@spiritsubstance.com>
|
||||
Based on raspbian-update by Ivan Drucker <ivan@ivanx.com>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with this software. If not, you may find a copy here:
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
" $PROGRAM $VERSION
|
||||
exit 0
|
||||
}
|
||||
|
||||
Run() {
|
||||
local cmd=( )
|
||||
for i in "${@}"; do
|
||||
# Replace argument's spaces with ''; if different, quote the string
|
||||
if [ "$i" != "${i/ /}" ]; then
|
||||
cmd=( ${cmd[@]} "'${i}'" )
|
||||
else
|
||||
cmd=( ${cmd[@]} $i )
|
||||
fi
|
||||
done
|
||||
printf ">>> %s\n" "${cmd[@]}"
|
||||
${@}
|
||||
}
|
||||
|
||||
|
||||
ShowHelp() {
|
||||
# FIXME
|
||||
printf "\nHelp\n"
|
||||
|
||||
exit ${1:-0}
|
||||
}
|
||||
|
||||
|
||||
# Process command line arguments
|
||||
while getopts ":hvyacy" opt; do
|
||||
case "$opt" in
|
||||
h) ShowHelp ;;
|
||||
v) ShowLicense ;;
|
||||
y) autoYes=1 ;;
|
||||
a) useAptGet=1 ;;
|
||||
c) useAutoClean=1 ;;
|
||||
\?)
|
||||
printf "Invalid argument: -%s\n" "$OPTARG"
|
||||
badArgument=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [[ "$badArgument" ]]; then
|
||||
ShowHelp 1
|
||||
fi
|
||||
|
||||
# Check for root access
|
||||
if [[ "$UID" != "0" ]]; then
|
||||
if hash sudo 2>/dev/null; then
|
||||
Run sudo $0 "$@"
|
||||
exit $?
|
||||
else
|
||||
printf "%s requires \"root\" administrator access to upgrade your system.\n" "$PROGRAM"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Determine if aptitude is installed (unless we're not using it)
|
||||
if [[ -z "$useAptGet" ]]; then
|
||||
if ! hash aptitude 2>/dev/null; then
|
||||
useAptGet=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean apt package cache
|
||||
printf "\nCleaning apt package cache...\n"
|
||||
if [[ $useAptGet ]]; then
|
||||
Run apt-get ${useAutoClean:+auto}clean
|
||||
else
|
||||
Run aptitude ${useAutoClean:+auto}clean
|
||||
fi
|
||||
|
||||
# Update package lists
|
||||
printf "\nUpdating list of available packages...\n"
|
||||
if [[ $useAptGet ]]; then
|
||||
Run apt-get update
|
||||
else
|
||||
Run aptitude update
|
||||
fi
|
||||
if [[ $? -ne 0 ]];
|
||||
printf "Package list update failed.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check to see if we even need to upgrade
|
||||
if [[ $useAptGet ]]; then
|
||||
apt-get --trivial-only $aptGetUpgradeArgs &>/dev/null
|
||||
else
|
||||
aptitude $aptitudeUpgradeArgs <<<"n" &>/dev/null
|
||||
fi
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "Your packages are already up to date.\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Do the upgrade itself
|
||||
if [[ $useAptGet ]]; then
|
||||
Run apt-get ${autoYes:+-y} $aptGetUpgradeArgs
|
||||
else
|
||||
Run aptitude ${autoYes:+-y} $aptitudeUpgradeArgs
|
||||
fi
|
||||
if [[ $? -ne 0 ]]; then
|
||||
# FIXME
|
||||
printf "System upgrade failed. Something about a log should be here.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# apt-get needs explicit autoremove (aptitude doesn't)
|
||||
if [[ $useAptGet ]]; then
|
||||
Run apt-get autoremove
|
||||
if [[ $? -ne 0 ]]; then
|
||||
printf "Failure attempting to auto-remove unneeded packages.\n"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean apt package cache (again)
|
||||
printf "Cleaning apt package cache...\n"
|
||||
if [[ $useAptGet ]]; then
|
||||
Run apt-get autoclean
|
||||
else
|
||||
Run aptitude autoclean
|
||||
fi
|
||||
|
||||
printf "\nIt is generally recommended that you reboot your system after upgrades. You
|
||||
can do this with the \"reboot\" command, which must be run as root.\n\n"
|
286
scripts/tools/mkatinit
Executable file
286
scripts/tools/mkatinit
Executable file
@ -0,0 +1,286 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab 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
|
@ -1,286 +0,0 @@
|
||||
#! /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
|
83
scripts/tools/mkvolinfo
Executable file
83
scripts/tools/mkvolinfo
Executable file
@ -0,0 +1,83 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# mkvolinfo -- creates a (share)/.AppleDesktop/.volinfo file
|
||||
|
||||
makeVolInfoFile () {
|
||||
[[ -d $sharepath/.AppleDesktop ]] || mkdir $sharepath/.AppleDesktop
|
||||
touch $volinfo
|
||||
echo 'MAC_CHARSET:MAC_ROMAN' >> $volinfo
|
||||
echo 'VOL_CHARSET:UTF8' >> $volinfo
|
||||
echo 'ADOUBLE_VER:v2' >> $volinfo
|
||||
echo 'CNIDBACKEND:dbd' >> $volinfo
|
||||
echo 'CNIDDBDHOST:localhost' >> $volinfo
|
||||
echo 'CNIDDBDPORT:4700' >> $volinfo
|
||||
echo "CNID_DBPATH:$sharepath" >> $volinfo
|
||||
echo 'VOLUME_OPTS:PRODOS CACHEID' >> $volinfo
|
||||
if (( $mixedcase )); then
|
||||
echo 'VOLCASEFOLD:' >> $volinfo
|
||||
else
|
||||
echo 'VOLCASEFOLD:MTOULOWER UTOMUPPER' >> $volinfo
|
||||
fi
|
||||
echo 'EXTATTRTYPE:AFPVOL_EA_AD' >> $volinfo
|
||||
echo ".volinfo for $sharepath has been created."
|
||||
}
|
||||
|
||||
while [[ $1 == "-f" || $1 == "-c" ]]; do
|
||||
if [[ $1 == "-f" ]]; then
|
||||
force=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $1 == "-c" ]]; then
|
||||
mixedcase=1
|
||||
shift
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${1:0:1} == "-" ]]; then
|
||||
|
||||
echo "usage: mkvolinfo [-f] [-c] [shared volume path]"
|
||||
echo
|
||||
echo "-c will create the .volinfo file to specify no uppercase filename conversion"
|
||||
echo "-f will create the .volinfo file without prompting, if none exists"
|
||||
echo "If a path is specified, that is what is used, otherwise the last entry"
|
||||
echo "in /usr/local/etc/netatalk/AppleVolumes.default is used."
|
||||
|
||||
else
|
||||
sudo true
|
||||
if [[ $1 ]]; then
|
||||
sharepath=$(readlink -m $1)
|
||||
else
|
||||
sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1)
|
||||
fi
|
||||
|
||||
volinfo=$sharepath/.AppleDesktop/.volinfo
|
||||
|
||||
if [[ ! -d $sharepath ]]; then
|
||||
echo "$sharepath does not exist."
|
||||
else
|
||||
if [[ -f $volinfo ]]; then
|
||||
echo "$volinfo already exists."
|
||||
else
|
||||
if [[ $force ]]; then
|
||||
makeVolInfoFile
|
||||
else
|
||||
echo "The .volinfo file is automatically generated when you first"
|
||||
echo "log in from an AFP (Apple II or Mac) client machine."
|
||||
echo "If you can't do this, you can create a .volinfo file now"
|
||||
echo "based on assumed defaults; proceed with caution if you have"
|
||||
echo "customized your AppleVolumes files."
|
||||
echo
|
||||
echo "If the path shown below is incorrect, you can specify"
|
||||
echo "the path to your shared volume as an argument to mkvolinfo."
|
||||
echo
|
||||
echo -n "Make .volinfo for shared volume $sharepath now? "
|
||||
read
|
||||
if [[ ${REPLY:0:1} == "y" ]] || [[ ${REPLY:0:1} == "Y" ]]; then
|
||||
makeVolInfoFile
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
@ -1,83 +0,0 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
|
||||
# mkvolinfo -- creates a (share)/.AppleDesktop/.volinfo file
|
||||
|
||||
makeVolInfoFile () {
|
||||
[[ -d $sharepath/.AppleDesktop ]] || mkdir $sharepath/.AppleDesktop
|
||||
touch $volinfo
|
||||
echo 'MAC_CHARSET:MAC_ROMAN' >> $volinfo
|
||||
echo 'VOL_CHARSET:UTF8' >> $volinfo
|
||||
echo 'ADOUBLE_VER:v2' >> $volinfo
|
||||
echo 'CNIDBACKEND:dbd' >> $volinfo
|
||||
echo 'CNIDDBDHOST:localhost' >> $volinfo
|
||||
echo 'CNIDDBDPORT:4700' >> $volinfo
|
||||
echo "CNID_DBPATH:$sharepath" >> $volinfo
|
||||
echo 'VOLUME_OPTS:PRODOS CACHEID' >> $volinfo
|
||||
if (( $mixedcase )); then
|
||||
echo 'VOLCASEFOLD:' >> $volinfo
|
||||
else
|
||||
echo 'VOLCASEFOLD:MTOULOWER UTOMUPPER' >> $volinfo
|
||||
fi
|
||||
echo 'EXTATTRTYPE:AFPVOL_EA_AD' >> $volinfo
|
||||
echo ".volinfo for $sharepath has been created."
|
||||
}
|
||||
|
||||
while [[ $1 == "-f" || $1 == "-c" ]]; do
|
||||
if [[ $1 == "-f" ]]; then
|
||||
force=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $1 == "-c" ]]; then
|
||||
mixedcase=1
|
||||
shift
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${1:0:1} == "-" ]]; then
|
||||
|
||||
echo "usage: mkvolinfo [-f] [-c] [shared volume path]"
|
||||
echo
|
||||
echo "-c will create the .volinfo file to specify no uppercase filename conversion"
|
||||
echo "-f will create the .volinfo file without prompting, if none exists"
|
||||
echo "If a path is specified, that is what is used, otherwise the last entry"
|
||||
echo "in /usr/local/etc/netatalk/AppleVolumes.default is used."
|
||||
|
||||
else
|
||||
sudo true
|
||||
if [[ $1 ]]; then
|
||||
sharepath=$(readlink -m $1)
|
||||
else
|
||||
sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1)
|
||||
fi
|
||||
|
||||
volinfo=$sharepath/.AppleDesktop/.volinfo
|
||||
|
||||
if [[ ! -d $sharepath ]]; then
|
||||
echo "$sharepath does not exist."
|
||||
else
|
||||
if [[ -f $volinfo ]]; then
|
||||
echo "$volinfo already exists."
|
||||
else
|
||||
if [[ $force ]]; then
|
||||
makeVolInfoFile
|
||||
else
|
||||
echo "The .volinfo file is automatically generated when you first"
|
||||
echo "log in from an AFP (Apple II or Mac) client machine."
|
||||
echo "If you can't do this, you can create a .volinfo file now"
|
||||
echo "based on assumed defaults; proceed with caution if you have"
|
||||
echo "customized your AppleVolumes files."
|
||||
echo
|
||||
echo "If the path shown below is incorrect, you can specify"
|
||||
echo "the path to your shared volume as an argument to mkvolinfo."
|
||||
echo
|
||||
echo -n "Make .volinfo for shared volume $sharepath now? "
|
||||
read
|
||||
if [[ ${REPLY:0:1} == "y" ]] || [[ ${REPLY:0:1} == "Y" ]]; then
|
||||
makeVolInfoFile
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
415
setup/index.txt
415
setup/index.txt
@ -1,358 +1,93 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# A2SERVER master setup script, last update 17-Nov-15
|
||||
# it downloads and executes several scripts related to the setup of
|
||||
# netatalk configured for Apple II use on Debian or Raspbian.
|
||||
# more info is at http://ivanx.com/a2server
|
||||
# setup/index.txt - upgrade path from Ivan's a2server tree
|
||||
#
|
||||
# Ivan's a2server installed with a single copy-paste of a command line that
|
||||
# downloaded a script and ran it sight-unseen. People are going to continue
|
||||
# to run that command (they shouldn't, but they will), and we can support
|
||||
# them doing it for now.
|
||||
|
||||
# to download and execute, type:
|
||||
# wget ivanx.com/a2server/setup; source setup
|
||||
a2sBranch="master"
|
||||
a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/${a2sBranch}"
|
||||
a2sTarball="https://github.com/RasppleII/a2server/archive/${a2sBranch}.tar.gz"
|
||||
|
||||
a2serverVersion="152"
|
||||
# Set top_src to the location of the source tree if we're running in one
|
||||
top_src="$( dirname "${BASH_SOURCE[0]}" )/.."
|
||||
if [[ -f "$top_src/.a2server_source" ]]; then
|
||||
pushd $top_src >/dev/null
|
||||
top_src="$PWD"
|
||||
popd >/dev/null
|
||||
|
||||
# Ensure URL we'll use ends in a /
|
||||
case "$A2SERVER_SCRIPT_URL" in
|
||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||
esac
|
||||
case "$A2SERVER_BINARY_URL" in
|
||||
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
||||
*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;;
|
||||
esac
|
||||
useExternalURL=1
|
||||
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
|
||||
cat <<-EOT
|
||||
This script exists solely for backward-compatibility with IvanX's a2server
|
||||
website and aliases installed by older versions. You appear to have an
|
||||
a2server source directory here:
|
||||
$top_src
|
||||
|
||||
isRpi=
|
||||
[[ -f /usr/bin/raspi-config ]] && isRpi=1
|
||||
Please run ./install.sh in that directory. Thanks!
|
||||
|
||||
isDebian=
|
||||
lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -d . -f 1 < /etc/debian_version) -ge "7" ) ]] && isDebian=1
|
||||
|
||||
installedVersion=
|
||||
if [ -f /usr/local/etc/A2SERVER-version ]; then
|
||||
installedVersion="$(cat /usr/local/etc/A2SERVER-version)"
|
||||
EOT
|
||||
exit 1
|
||||
fi
|
||||
echo "A2SERVER version available: $a2serverVersion"
|
||||
echo "A2SERVER version installed: ${installedVersion:=None}"
|
||||
|
||||
echo
|
||||
[[ $scriptURL != *"ivanx.com"* && $scriptURL != *"raw.githubusercontent.com/RasppleII/a2server"* ]] && echo "Using script URL: $scriptURL"
|
||||
[[ $binaryURL != *"ivanx.com"* ]] && echo "Using binary URL: $binaryURL"
|
||||
[[ ! $useExternalURL ]] && echo -e "Not using external URLs. Downloads must be available from:\n ${binaryURL}external/appleii/\n ${binaryURL}external/source/\n (See the A2SERVER developer page for more information.)"
|
||||
# Find the version in the install script
|
||||
newVersion=$(wget -qO- "${a2sScriptURL}/install.sh" | grep '^a2serverVersion' | cut -d '"' -f 2)
|
||||
|
||||
skipRepoUpdate=
|
||||
# It almost never is, but this script could be run with command line arguments,
|
||||
# of which -y we can use, so we should check for it. We'll pass them all to
|
||||
# the install script later
|
||||
autoAnswerYes=
|
||||
installAll=
|
||||
setupNetBoot=
|
||||
setupWindowsSharing=
|
||||
compileAlways=
|
||||
rm /tmp/a2server-* 2> /dev/null
|
||||
while [[ $1 ]]; do
|
||||
if [[ $1 == "-r" ]]; then
|
||||
shift
|
||||
skipRepoUpdate="-r"
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
elif [[ $1 == "-i" ]]; then
|
||||
shift
|
||||
installAll="-i"
|
||||
elif [[ $1 == "-y" ]]; then
|
||||
shift
|
||||
autoAnswerYes="-y"
|
||||
touch /tmp/a2server-autoAnswerYes
|
||||
elif [[ $1 == "-b" ]]; then
|
||||
shift
|
||||
setupNetBoot="-b"
|
||||
touch /tmp/a2server-setupNetBoot
|
||||
elif [[ $1 == "-w" ]]; then
|
||||
shift
|
||||
setupWindowsSharing="-w"
|
||||
touch /tmp/a2server-setupWindowsSharing
|
||||
elif [[ $1 == "-c" ]]; then
|
||||
shift
|
||||
compileAlways="-c"
|
||||
touch /tmp/a2server-compileAlways
|
||||
elif [[ $1 == "-v" ]]; then
|
||||
shift
|
||||
# Version was already printed
|
||||
[[ $0 == "-bash" ]] && return 1 || exit 1
|
||||
elif [[ $1 ]]; then
|
||||
echo "options:"
|
||||
echo "-v: display installed and available versions, then exit"
|
||||
echo "-i: reinstall A2SERVER software (but not Apple II software)"
|
||||
echo "-y: auto-answer yes to all prompts"
|
||||
echo "-r: don't update package repositories"
|
||||
echo "-b: auto-setup network boot (use with -y)"
|
||||
echo "-w: auto-setup Windows file sharing (use with -y)"
|
||||
echo "-c: compile non-package items, rather than downloading binaries"
|
||||
[[ $0 == "-bash" ]] && return 1 || exit 1
|
||||
fi
|
||||
for arg in $@; do
|
||||
if [[ $arg == "-y" ]]; then
|
||||
autoAnswerYes=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 110 )); }; then
|
||||
echo
|
||||
echo "WARNING: The current A2SERVER installer scripts haven't been tested for"
|
||||
echo "updating the earlier version of A2SERVER that you have. A fresh install"
|
||||
echo "is suggested. Continuing is not recommended and could make A2SERVER"
|
||||
echo "no longer work properly, or cause data to be lost."
|
||||
cat <<EOT
|
||||
|
||||
Hello, you've reached the single wget command version of the a2server install
|
||||
script. This script is being phased out for a number of reasons. The most
|
||||
important is that it is not repeatable. This script will download things
|
||||
behind the scenes, run them without much verification, and then delete what it
|
||||
ran, no matter if the installation finished successfully or not. The next
|
||||
time you run the same command, you may get a different (hopefully better)
|
||||
version.
|
||||
|
||||
Right now, a2server ${newVersion} is available.
|
||||
|
||||
If you are seeing this text, iKarith (Joseph Carter) hasn't bothered to write
|
||||
publicly-facing end-user documentation for downloading and installing a2server
|
||||
a more preferred way. He's filed an issue about this, please do follow the
|
||||
instructions there:
|
||||
https://github.com/RasppleII/a2server/issues/60
|
||||
|
||||
For now, this script does what the old installer used to.
|
||||
|
||||
EOT
|
||||
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
printf "Do you want to install a2server with this script? "
|
||||
read
|
||||
if [[ ${REPLY:0:1} != "y" && ${REPLY:0:1} != "Y" ]]; then
|
||||
printf "\nOkay, not installing anything now!\n\n"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
a2server_update=0
|
||||
doSetup=1
|
||||
top_src=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX)
|
||||
|
||||
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 152 )); }; then
|
||||
a2server_update=1
|
||||
fi
|
||||
# Normally tarballs unpack in a subdirectory, but we want it to unpack into
|
||||
# $top_src directly (even though the directory has the tarball in it.)
|
||||
printf "\na2server: Downloading installer to $top_src.\n"
|
||||
wget -O "$top_src/a2server-$a2sBranch.tar.gz" "$a2sTarball"
|
||||
tar -C $top_src --strip-components=1 -zxf "$top_src/a2server-${a2sBranch}.tar.gz"
|
||||
|
||||
unsupportedOS=1
|
||||
if [[ $isRpi ]]; then #supported Raspbian? (16-Feb-15, 20-Jun-14, 09-Jan-14, etc)
|
||||
fwhash=$(zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 'as of' | awk '{print $NF}')
|
||||
fwsupported="-8aca5762- -462f3e3f476f7b6- -c32bc633039cd9- -9d34d0475f9-
|
||||
-d4f5315cfac4e- -6f4a90c8cb8817f- -5dd9b4962e- -17c8799375-
|
||||
-960832a6c2590635216c296b6ee0bebf67b21d50-
|
||||
-2a329e0c7d8ea19c085bac5633aa4fccee0f21be-
|
||||
-b2420fc150ae4616f5d9ec24bdaedc630586a529-"
|
||||
[[ "$fwsupported" == *-$fwhash-* ]] && unsupportedOS=
|
||||
# [[ ($fwhash == "8aca5762") || ($fwhash == "462f3e3f476f7b6") || ($fwhash == "c32bc633039cd9") || ($fwhash == "9d34d0475f9") || ($fwhash == "d4f5315cfac4e") || ($fwhash == "6f4a90c8cb8817f") || ($fwhash == "5dd9b4962e") || ($fwhash == "17c8799375") ]] && unsupportedOS=
|
||||
elif [[ $isDebian ]]; then # supported Debian?
|
||||
debianVersion=$(cat /etc/debian_version)
|
||||
debianSupported="-9.2- -8.2- -7.9- -7.8- -7.6- -7.3-"
|
||||
[[ $debianSupported == *-$debianVersion-* ]] && unsupportedOS=
|
||||
fi
|
||||
# Now we actually run the installer as if we were installing it by hand
|
||||
printf "\na2server: Running the installer now.\n"
|
||||
"${top_src}/install.sh" "$@"
|
||||
|
||||
if [[ $unsupportedOS && $isRpi ]]; then
|
||||
echo
|
||||
echo "A2SERVER and its installer scripts have been tested on Raspbian Stretch,"
|
||||
echo "Jessie, and Wheezy, though not this specific firmware version"
|
||||
echo "(${fwhash:0:7}). Just FYI."
|
||||
unsupportedOS=
|
||||
elif [[ $unsupportedOS && $isDebian ]]; then
|
||||
echo
|
||||
echo "A2SERVER and its installer scripts have been tested on Debian 7/8/9,"
|
||||
echo "though not this specific point release ($debianVersion). Just FYI."
|
||||
unsupportedOS=
|
||||
fi
|
||||
|
||||
if [[ $unsupportedOS ]]; then
|
||||
echo
|
||||
echo "WARNING: A2SERVER and its installer scripts have only been tested on"
|
||||
echo "Debian and Raspbian. Continuing is probably fine, but might not be."
|
||||
echo "Theoretical worst case would be your operating system no longer works"
|
||||
echo "properly or data is lost, so consider backing up first."
|
||||
fi
|
||||
|
||||
doSetup=1
|
||||
if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then
|
||||
echo
|
||||
echo "Setting up A2SERVER will take up to 60 minutes, during which"
|
||||
echo "you'll see a bunch of stuff spit out across the screen."
|
||||
echo
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo -n "Ready to set up A2SERVER? "
|
||||
read
|
||||
[[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? ))
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( $doSetup )); then
|
||||
|
||||
echo
|
||||
echo "a2server-setup modifies files and performs actions as the root user."
|
||||
echo "For details, visit http://ivanx.com/a2server."
|
||||
echo
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo -n "Continue? "
|
||||
read
|
||||
[[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? ))
|
||||
fi
|
||||
|
||||
if (( $doSetup )); then
|
||||
|
||||
checkPw=1
|
||||
while [[ $checkPw ]] ; do
|
||||
userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':')
|
||||
[[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw=
|
||||
[[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw=
|
||||
|
||||
password="your password"
|
||||
[[ $isApple2Pw ]] && password="apple2"
|
||||
[[ $isRaspberryPw ]] && password="raspberry"
|
||||
checkPw=
|
||||
|
||||
[[ $isRpi ]] && a2server="your Raspberry Pi" || a2server="A2SERVER"
|
||||
if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2SERVER-version ]]; then
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo "To ensure that all client computers are able to connect to"
|
||||
echo "${a2server} using the same password, you probably want"
|
||||
echo "to change your user password to 'apple2'."
|
||||
echo
|
||||
echo -n "Do you want to change the password for user '$USER' to 'apple2' now? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
echo "A2SERVER: changing password for user '$USER' to 'apple2'..."
|
||||
echo "$USER:apple2" | sudo chpasswd
|
||||
checkPw=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "During this installation, enter '${password}' if prompted for passwords."
|
||||
echo
|
||||
|
||||
sudo true
|
||||
|
||||
echo
|
||||
echo "A2SERVER: Downloading scripts..."
|
||||
|
||||
wget -q -O /tmp/1.storage "${scriptURL}scripts/a2server-1-storage.txt"
|
||||
chmod ugo+x /tmp/1.storage
|
||||
|
||||
wget -q -O /tmp/2.tools "${scriptURL}scripts/a2server-2-tools.txt"
|
||||
chmod ugo+x /tmp/2.tools
|
||||
|
||||
wget -q -O /tmp/3.sharing "${scriptURL}scripts/a2server-3-sharing.txt"
|
||||
chmod ugo+x /tmp/3.sharing
|
||||
|
||||
wget -q -O /tmp/5.netboot "${scriptURL}scripts/a2server-5-netboot.txt"
|
||||
chmod ugo+x /tmp/5.netboot
|
||||
|
||||
wget -q -O /tmp/6.samba "${scriptURL}scripts/a2server-6-samba.txt"
|
||||
chmod ugo+x /tmp/6.samba
|
||||
|
||||
wget -q -O /tmp/7.console "${scriptURL}scripts/a2server-7-console.txt"
|
||||
chmod ugo+x /tmp/7.console
|
||||
|
||||
echo "A2SERVER: Scripts have been downloaded. Installing..."
|
||||
|
||||
if [[ $installAll ]]; then
|
||||
sudo rm /usr/local/etc/A2SERVER-version 2> /dev/null
|
||||
sudo rm /usr/local/bin/nulib2 2> /dev/null
|
||||
sudo rm /usr/local/bin/unar 2> /dev/null
|
||||
sudo rm /usr/local/sbin/macipgw 2> /dev/null
|
||||
sudo rm /usr/local/bin/ciopfs 2> /dev/null
|
||||
sudo rm /usr/local/etc/netatalk/afppasswd 2> /dev/null
|
||||
sudo rm /usr/local/etc/netatalk/a2boot/p8 /usr/local/etc/netatalk/a2boot/ProDOS16\ Image 2> /dev/null
|
||||
fi
|
||||
|
||||
/tmp/1.storage
|
||||
rm /tmp/1.storage
|
||||
/tmp/2.tools
|
||||
rm /tmp/2.tools
|
||||
/tmp/3.sharing
|
||||
rm /tmp/3.sharing
|
||||
/tmp/5.netboot
|
||||
rm /tmp/5.netboot
|
||||
/tmp/6.samba
|
||||
rm /tmp/6.samba
|
||||
/tmp/7.console
|
||||
rm /tmp/7.console
|
||||
rm /tmp/a2server-packageReposUpdated &> /dev/null
|
||||
|
||||
if [[ ! -f /usr/local/etc/A2SERVER-version ]] \
|
||||
|| (( $(head -c 3 /usr/local/etc/A2SERVER-version) < ${a2serverVersion:0:3} )); then
|
||||
echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null
|
||||
fi
|
||||
|
||||
source /usr/local/etc/a2serverrc
|
||||
|
||||
# get Kernel release (e.g. 3.6.11+) and version (e.g. #557)
|
||||
kernelRelease=$(uname -r)
|
||||
kernelMajorRelease=$(cut -d '.' -f 1 <<< $kernelRelease)
|
||||
kernelMinorRelease=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
|
||||
|
||||
echo
|
||||
# all done, see if AppleTalk is available and notify either way
|
||||
if [[ $(ps aux | grep [a]talkd) ]]; then
|
||||
echo "You now have a fully functional file server for Apple II clients."
|
||||
echo "On an Apple IIe, it should be accessible via \"Log In\" on the"
|
||||
echo "Workstation Card software. For IIgs users, it should be accessible"
|
||||
echo "via the AppleShare control panel."
|
||||
if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then
|
||||
echo
|
||||
echo "You can network boot GS/OS."
|
||||
echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)"
|
||||
echo "to Your Card, and slot 7 to AppleTalk, and Startup Slot to 7 or Scan."
|
||||
echo "On a ROM 3 IIgs, set slot 1 or 2, and Startup Slot, to AppleTalk."
|
||||
fi
|
||||
if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then
|
||||
echo
|
||||
echo "You can network boot ProDOS 8. On an Apple IIe, put your Workstation Card"
|
||||
echo "in a slot above your disk controller card, or type PR#X with open-apple"
|
||||
echo "held down, with X being the slot of your Workstation Card."
|
||||
echo 'On a IIgs, press "8" during the initial procession of periods.'
|
||||
fi
|
||||
echo
|
||||
echo "A2SERVER setup is complete! Go connect from your Apple II!"
|
||||
echo
|
||||
elif [[ -f /tmp/rpiUpdate ]]; then
|
||||
echo "A2SERVER is now configured, but Apple II clients will not be able"
|
||||
echo "to connect until you restart your Raspberry Pi."
|
||||
echo
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo -n "Restart now? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
sudo shutdown -r now
|
||||
echo
|
||||
echo "A2SERVER: Preparing to restart..."
|
||||
while :; do sleep 60; done
|
||||
fi
|
||||
rm /tmp/rpiUpdate
|
||||
echo
|
||||
elif [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRelease -le 15 ]]; then
|
||||
echo "A2SERVER is now configured, but Apple II clients cannot connect"
|
||||
echo "because of a kernel-crashing bug in Linux kernel 3.12 through 3.15."
|
||||
echo "You have kernel version $kernelMajorRelease.$kernelMinorRelease."
|
||||
echo "A2SERVER has disabled AppleTalk networking to prevent crashes."
|
||||
echo "Please use kernel 3.11 or earlier, or kernel 3.16 or later."
|
||||
echo
|
||||
else
|
||||
echo "A2SERVER is now configured, but Apple II clients cannot connect because"
|
||||
echo "AppleTalk networking is unavailable. Please make sure that"
|
||||
echo "your Linux distribution has a loadable AppleTalk kernel module or"
|
||||
echo "has AppleTalk built into the kernel, and restart your server."
|
||||
echo "Or, if you previously disabled AppleTalk in A2SERVER, re-enable it"
|
||||
echo "by typing 'appletalk-on'."
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/noMacIP ]]; then
|
||||
echo
|
||||
echo "MacIP connections may be unavailable. If you know how, try"
|
||||
echo "recompiling the AppleTalk kernel module with IPDDP options disabled."
|
||||
echo
|
||||
rm /tmp/noMacIP
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/singleUser ]]; then
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo "Your Raspberry Pi was started in single-user mode in order to"
|
||||
echo -n "fix a problem. You should restart to operate normally. Restart now? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
sudo shutdown -r now
|
||||
echo
|
||||
echo "A2SERVER: Preparing to restart..."
|
||||
while :; do sleep 60; done
|
||||
fi
|
||||
rm /tmp/singleUser
|
||||
echo
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Type 'system-shutdown' to turn off A2SERVER."
|
||||
echo "Type 'a2server-setup' to configure network boot."
|
||||
echo "Type 'a2server-help' for a list of other commands."
|
||||
fi
|
||||
fi
|
||||
|
||||
unset a2server_update 2> /dev/null
|
||||
unset doSetup 2> /dev/null
|
||||
rm /tmp/a2server-* 2> /dev/null
|
||||
rm setup &> /dev/null
|
||||
# Clean up and delete the installer we downloaded
|
||||
printf "\na2server: Finished with installer, now deleting ${top_src}.\n"
|
||||
rm -rf "$top_src"
|
||||
|
293
setup/ivan.sh
Executable file
293
setup/ivan.sh
Executable file
@ -0,0 +1,293 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# A2SERVER master setup script, last update 17-Nov-15
|
||||
# it downloads and executes several scripts related to the setup of
|
||||
# netatalk configured for Apple II use on Debian or Raspbian.
|
||||
# more info is at http://ivanx.com/a2server
|
||||
|
||||
# Find the path of our source directory
|
||||
top_src="$( dirname "${BASH_SOURCE[0]}" )/.."
|
||||
pushd $top_src >/dev/null
|
||||
top_src="$PWD"
|
||||
popd >/dev/null
|
||||
if [[ ! -f "$top_src/.a2server_source" ]]; then
|
||||
printf "\na2server: cannot find a2server source directory in $top_src.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make sure ras2_{os,arch} get set
|
||||
. "$top_src/scripts/system_ident" -q
|
||||
|
||||
# This is now in install.sh, get it from there
|
||||
a2serverVersion=$(grep '^a2serverVersion' "$top_src/install.sh" | cut -d '"' -f 2)
|
||||
|
||||
compare_version="$top_src/scripts/compare_version"
|
||||
|
||||
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
|
||||
read installedVersion </usr/local/etc/A2SERVER-version
|
||||
if [[ $installedVersion != *.*.* ]]; then
|
||||
# Deal with old three-digit version
|
||||
installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}"
|
||||
fi
|
||||
fi
|
||||
if [[ $installedVersion != *.*.* ]]; then
|
||||
installedVersion=0
|
||||
fi
|
||||
|
||||
skipRepoUpdate=
|
||||
autoAnswerYes=
|
||||
installAll=
|
||||
setupNetBoot=
|
||||
setupWindowsSharing=
|
||||
compileAlways=
|
||||
rm -rf /tmp/a2server-install
|
||||
rm /tmp/a2server-* 2> /dev/null
|
||||
while [[ $1 ]]; do
|
||||
if [[ $1 == "-r" ]]; then
|
||||
shift
|
||||
skipRepoUpdate="-r"
|
||||
touch /tmp/a2server-packageReposUpdated
|
||||
elif [[ $1 == "-i" ]]; then
|
||||
shift
|
||||
installAll="-i"
|
||||
elif [[ $1 == "-y" ]]; then
|
||||
shift
|
||||
autoAnswerYes="-y"
|
||||
touch /tmp/a2server-autoAnswerYes
|
||||
elif [[ $1 == "-b" ]]; then
|
||||
shift
|
||||
setupNetBoot="-b"
|
||||
touch /tmp/a2server-setupNetBoot
|
||||
elif [[ $1 == "-w" ]]; then
|
||||
shift
|
||||
setupWindowsSharing="-w"
|
||||
touch /tmp/a2server-setupWindowsSharing
|
||||
elif [[ $1 == "-c" ]]; then
|
||||
shift
|
||||
compileAlways="-c"
|
||||
touch /tmp/a2server-compileAlways
|
||||
elif [[ $1 == "-v" ]]; then
|
||||
shift
|
||||
# Version was already printed
|
||||
if [[ $0 == "-bash" ]]; then
|
||||
return 1
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
elif [[ $1 ]]; then
|
||||
echo "options:"
|
||||
echo "-v: display installed and available versions, then exit"
|
||||
echo "-i: reinstall A2SERVER software (but not Apple II software)"
|
||||
echo "-y: auto-answer yes to all prompts"
|
||||
echo "-r: don't update package repositories"
|
||||
echo "-b: auto-setup network boot (use with -y)"
|
||||
echo "-w: auto-setup Windows file sharing (use with -y)"
|
||||
echo "-c: compile non-package items, rather than downloading binaries"
|
||||
if [[ $0 == "-bash" ]]; then
|
||||
return 1
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if "$compare_version" $installedVersion lt 1.1.0; then
|
||||
echo
|
||||
echo "WARNING: The current A2SERVER installer scripts haven't been tested for"
|
||||
echo "updating the earlier version of A2SERVER that you have. A fresh install"
|
||||
echo "is suggested. Continuing is not recommended and could make A2SERVER"
|
||||
echo "no longer work properly, or cause data to be lost."
|
||||
fi
|
||||
|
||||
a2server_update=0
|
||||
doSetup=1
|
||||
|
||||
if [[ "$installedVersion" != "0" ]] && "$compare_version" $installedVersion lt 1.5.2; then
|
||||
a2server_update=1
|
||||
fi
|
||||
|
||||
unsupportedOS=1
|
||||
if [[ $ras2_os == debian-* || $ras2_os == rpi-* ]]; then
|
||||
read debianVersion < /etc/debian_version
|
||||
if [[ $debianVersion == *.* ]]; then
|
||||
if (( ${debianVersion%.*} >= 8 && ${debianVersion%.*} < 10 )); then
|
||||
unsupportedOS=
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $unsupportedOS ]]; then
|
||||
cat <<-EOF
|
||||
|
||||
WARNING: A2SERVER and its installer scripts have only been tested on
|
||||
Debian and Raspbian wheezy, jessie, and stretch. It may work with later
|
||||
versions, but it might not. The theoretical worst case would be an OS
|
||||
image that no longer works correctly or lost data, so you might want to
|
||||
press ctrl-c here. Otherwise press Return.
|
||||
|
||||
Detected system: $ras2_os ($ras2_arch)
|
||||
EOF
|
||||
read
|
||||
fi
|
||||
|
||||
doSetup=1
|
||||
if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then
|
||||
echo
|
||||
echo "Setting up A2SERVER will take up to 60 minutes, during which"
|
||||
echo "you'll see a bunch of stuff spit out across the screen."
|
||||
echo
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo -n "Ready to set up A2SERVER? "
|
||||
read
|
||||
[[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? ))
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( $doSetup )); then
|
||||
|
||||
echo
|
||||
echo "a2server-setup modifies files and performs actions as the root user."
|
||||
echo "For details, visit http://ivanx.com/a2server."
|
||||
echo
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo -n "Continue? "
|
||||
read
|
||||
[[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? ))
|
||||
fi
|
||||
|
||||
if (( $doSetup )); then
|
||||
|
||||
origDir="$PWD"
|
||||
rm -rf /tmp/a2server-install &>/dev/null
|
||||
mkdir -p /tmp/a2server-install
|
||||
|
||||
read -d '' a2sSubScripts <<-EOF
|
||||
a2server-1-storage.txt
|
||||
a2server-2-tools.txt
|
||||
a2server-3-sharing.txt
|
||||
a2server-5-netboot.txt
|
||||
a2server-6-samba.txt
|
||||
a2server-7-console.txt
|
||||
EOF
|
||||
|
||||
if [[ $installAll ]]; then
|
||||
sudo rm -f /usr/local/etc/A2SERVER-version
|
||||
sudo rm -f /usr/local/bin/nulib2
|
||||
sudo rm -f /usr/local/bin/unar
|
||||
sudo rm -f /usr/local/sbin/macipgw
|
||||
sudo rm -f /usr/local/bin/ciopfs
|
||||
sudo rm -f /usr/local/etc/netatalk/afppasswd
|
||||
sudo rm -f /usr/local/etc/netatalk/a2boot/p8
|
||||
sudo rm -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Image
|
||||
fi
|
||||
|
||||
for _script in $a2sSubScripts; do
|
||||
"$top_src/scripts/$_script"
|
||||
done
|
||||
|
||||
rm -f /tmp/a2server-packageReposUpdated
|
||||
|
||||
echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null
|
||||
|
||||
source /usr/local/etc/a2serverrc
|
||||
|
||||
# get Kernel release (e.g. 3.6.11+) and version (e.g. #557)
|
||||
kernelRelease=$(uname -r)
|
||||
kernelMajorRelease=$(cut -d '.' -f 1 <<< $kernelRelease)
|
||||
kernelMinorRelease=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
|
||||
|
||||
echo
|
||||
# all done, see if AppleTalk is available and notify either way
|
||||
if [[ $(ps aux | grep [a]talkd) ]]; then
|
||||
echo "You now have a fully functional file server for Apple II clients."
|
||||
echo "On an Apple IIe, it should be accessible via \"Log In\" on the"
|
||||
echo "Workstation Card software. For IIgs users, it should be accessible"
|
||||
echo "via the AppleShare control panel."
|
||||
if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then
|
||||
echo
|
||||
echo "You can network boot GS/OS."
|
||||
echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)"
|
||||
echo "to Your Card, and slot 7 to AppleTalk, and Startup Slot to 7 or Scan."
|
||||
echo "On a ROM 3 IIgs, set slot 1 or 2, and Startup Slot, to AppleTalk."
|
||||
fi
|
||||
if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then
|
||||
echo
|
||||
echo "You can network boot ProDOS 8. On an Apple IIe, put your Workstation Card"
|
||||
echo "in a slot above your disk controller card, or type PR#X with open-apple"
|
||||
echo "held down, with X being the slot of your Workstation Card."
|
||||
echo 'On a IIgs, press "8" during the initial procession of periods.'
|
||||
fi
|
||||
echo
|
||||
echo "A2SERVER setup is complete! Go connect from your Apple II!"
|
||||
echo
|
||||
elif [[ -f /tmp/rpiUpdate ]]; then
|
||||
echo "A2SERVER is now configured, but Apple II clients will not be able"
|
||||
echo "to connect until you restart your Raspberry Pi."
|
||||
echo
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo -n "Restart now? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
sudo shutdown -r now
|
||||
echo
|
||||
echo "A2SERVER: Preparing to restart..."
|
||||
while :; do sleep 60; done
|
||||
fi
|
||||
rm /tmp/rpiUpdate
|
||||
echo
|
||||
elif [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRelease -le 15 ]]; then
|
||||
echo "A2SERVER is now configured, but Apple II clients cannot connect"
|
||||
echo "because of a kernel-crashing bug in Linux kernel 3.12 through 3.15."
|
||||
echo "You have kernel version $kernelMajorRelease.$kernelMinorRelease."
|
||||
echo "A2SERVER has disabled AppleTalk networking to prevent crashes."
|
||||
echo "Please use kernel 3.11 or earlier, or kernel 3.16 or later."
|
||||
echo
|
||||
else
|
||||
echo "A2SERVER is now configured, but Apple II clients cannot connect because"
|
||||
echo "AppleTalk networking is unavailable. Please make sure that"
|
||||
echo "your Linux distribution has a loadable AppleTalk kernel module or"
|
||||
echo "has AppleTalk built into the kernel, and restart your server."
|
||||
echo "Or, if you previously disabled AppleTalk in A2SERVER, re-enable it"
|
||||
echo "by typing 'appletalk-on'."
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/noMacIP ]]; then
|
||||
echo
|
||||
echo "MacIP connections may be unavailable. If you know how, try"
|
||||
echo "recompiling the AppleTalk kernel module with IPDDP options disabled."
|
||||
echo
|
||||
rm /tmp/noMacIP
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/singleUser ]]; then
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
echo
|
||||
echo "Your Raspberry Pi was started in single-user mode in order to"
|
||||
echo -n "fix a problem. You should restart to operate normally. Restart now? "
|
||||
read
|
||||
fi
|
||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||
sudo shutdown -r now
|
||||
echo
|
||||
echo "A2SERVER: Preparing to restart..."
|
||||
while :; do sleep 60; done
|
||||
fi
|
||||
rm /tmp/singleUser
|
||||
echo
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Type 'system-shutdown' to turn off A2SERVER."
|
||||
echo "Type 'a2server-setup' to configure network boot."
|
||||
echo "Type 'a2server-help' for a list of other commands."
|
||||
fi
|
||||
fi
|
||||
|
||||
unset a2server_update 2> /dev/null
|
||||
unset doSetup 2> /dev/null
|
||||
rm -rf /tmp/a2server-install &>/dev/null
|
||||
rm -f /tmp/a2server-* 2> /dev/null
|
||||
rm -f setup &> /dev/null
|
@ -68,7 +68,7 @@
|
||||
|
||||
1.2.6: Nov 2015: full, ready to use install of Spectrum; install unzip
|
||||
[unannounced]
|
||||
|
||||
|
||||
1.2.6+:Nov 2015: merged Ivan's 1.2.6 (into github master branch)
|
||||
[unannounced]
|
||||
|
||||
@ -80,11 +80,11 @@
|
||||
1.2.8: Dec 2015: can specify alternate host for binaries and external files;
|
||||
[unannounced] 64-bit Debian precompiled binaries; move /media/A2SHARED/*
|
||||
to /srv/A2SERVER; internet access (MacIP support);
|
||||
|
||||
|
||||
1.2.9: Jan 2016: cppo supports ShrinkIt, DOS 3.3, DSK, 2MG; MountIt fully
|
||||
[unannounced] installed; nulib2 fixes handling empty forks (thanks Andy);
|
||||
-c installer option compiles all software (no binaries)
|
||||
|
||||
|
||||
1.3.0: Jan 2016: Marinetti 3.0b8 installed, with preconfigured MacIP
|
||||
[unannounced]
|
||||
|
||||
@ -93,7 +93,7 @@
|
||||
|
||||
1.3.2: Jan 2016: install SAFE2, SAM2, and SNAP, configured for Apple II sites;
|
||||
[unannounced] -i installer option reinstalls A2SERVER
|
||||
|
||||
|
||||
1.5.0: Jan 2016: defaults to GitHub for location of installer scripts
|
||||
[unannounced]
|
||||
|
||||
|
131
update/index.txt
131
update/index.txt
@ -1,45 +1,114 @@
|
||||
#! /bin/bash
|
||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||
# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh:
|
||||
|
||||
# Ensure URL we'll use ends in a /
|
||||
case "$A2SERVER_SCRIPT_URL" in
|
||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||
esac
|
||||
# update/index.txt - upgrade path from Ivan's a2server tree
|
||||
#
|
||||
# Ivan's a2server installed with a single copy-paste of a command line that
|
||||
# downloaded a script and ran it sight-unseen. It also installed an alias
|
||||
# command that would perform a similar one-liner to upgrade a2server to the
|
||||
# latest version. This script provides that interface for upgrades.
|
||||
|
||||
currentVersion=$(wget -qO- "${scriptURL}setup/index.txt" | grep '^a2serverVersion' | cut -d '"' -f 2)
|
||||
a2sBranch="master"
|
||||
a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/${a2sBranch}"
|
||||
a2sTarball="https://github.com/RasppleII/a2server/archive/${a2sBranch}.tar.gz"
|
||||
|
||||
# Set top_src to the location of the source tree if we're running in one
|
||||
top_src="$( dirname "${BASH_SOURCE[0]}" )/.."
|
||||
pushd $top_src >/dev/null
|
||||
top_src="$PWD"
|
||||
popd >/dev/null
|
||||
if [[ ! -f "$top_src/.a2server_source" ]]; then
|
||||
a2sWebUpdate=1
|
||||
top_src=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX)
|
||||
fi
|
||||
|
||||
installedVersion=
|
||||
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
|
||||
installedVersion=$(cat /usr/local/etc/A2SERVER-version)
|
||||
else
|
||||
installedVersion=100
|
||||
read installedVersion < /usr/local/etc/A2SERVER-version
|
||||
# Convert old three-digit version if needed
|
||||
if [[ $installedVersion != *.*.* ]]; then
|
||||
installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}"
|
||||
fi
|
||||
fi
|
||||
|
||||
autoAnswerYes=
|
||||
for arg in $@; do
|
||||
if [[ $arg == "-y" ]]; then
|
||||
autoAnswerYes=1
|
||||
break
|
||||
fi
|
||||
if [[ $arg == "-y" ]]; then
|
||||
autoAnswerYes=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Update history:"
|
||||
wget -qO- "${scriptURL}update/versionhistory.txt"
|
||||
echo
|
||||
echo "installed version: ${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2:1}"
|
||||
echo "current version: ${currentVersion:0:1}.${currentVersion:1:1}.${currentVersion:2:1}"
|
||||
echo
|
||||
if [[ $autoAnswerYes ]]; then
|
||||
REPLY="y"
|
||||
printf "\na2server web update\n\n"
|
||||
|
||||
if (( $a2sWebUpdate )); then
|
||||
newVersion=$(wget -qO- "${a2sScriptURL}/install.sh" | grep '^a2serverVersion' | cut -d '"' -f 2)
|
||||
cat <<-EOT
|
||||
You've started the single command a2server update script. This script will
|
||||
download things behind the scenes, run them without much verification, and
|
||||
then it will delete what it ran whether the upgrade finished successfully or
|
||||
not. For this reason, we are going to be phasing this script out in the
|
||||
future.
|
||||
EOT
|
||||
else
|
||||
echo -n "Do you want to update (or reinstall) A2SERVER? "
|
||||
read
|
||||
fi
|
||||
if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then
|
||||
# sudo rm /usr/local/etc/netatalk/a2boot/* &> /dev/null
|
||||
wget -q -O /tmp/setup "${scriptURL}setup/index.txt"; source /tmp/setup -i "$@"
|
||||
newVersion=$(grep '^a2serverVersion' "$top_src/install.sh" | cut -d '"' -f 2)
|
||||
cat <<-EOT
|
||||
You've started the single command a2server update script from inside the
|
||||
a2server source directory for version $newVersion. This script will only
|
||||
upgrade to or reinstall that version.
|
||||
EOT
|
||||
fi
|
||||
|
||||
unset currentVersion 2> /dev/null
|
||||
unset installedVersion 2> /dev/null
|
||||
if [[ $installedVersion ]]; then
|
||||
printf "\nRight now you have a2server %s installed\n" "$installedVersion"
|
||||
else
|
||||
printf "\nRight now you don't appear to have a2server installed\n"
|
||||
fi
|
||||
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
printf "\nPress Enter to continue "
|
||||
read
|
||||
fi
|
||||
|
||||
# If running from local source tree, that's what you'll be upgrading to
|
||||
printf "\nProject history:\n"
|
||||
if (( $a2sWebUpdate )); then
|
||||
wget -qO- "${a2sScriptURL}/update/versionhistory.txt"
|
||||
else
|
||||
cat "$top_src/update/versionhistory.txt"
|
||||
fi
|
||||
|
||||
cat <<EOT
|
||||
|
||||
installed version: ${installedVersion}
|
||||
available version: ${newVersion}
|
||||
|
||||
EOT
|
||||
|
||||
if [[ ! $autoAnswerYes ]]; then
|
||||
printf "Do you want to update (or reinstall) a2server? "
|
||||
read
|
||||
if [[ ${REPLY:0:1} != "y" && ${REPLY:0:1} != "Y" ]]; then
|
||||
printf "\nOkay, not updating anything now!\n\n"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( $a2sWebUpdate )); then
|
||||
top_src=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX)
|
||||
|
||||
# Normally tarballs unpack in a subdirectory, but we want it to unpack into
|
||||
# $top_src directly (even though the directory has the tarball in it.)
|
||||
printf "\na2server: Downloading installer to $top_src.\n"
|
||||
wget -O "$top_src/a2server-$a2sBranch.tar.gz" "$a2sTarball"
|
||||
tar -C $top_src --strip-components=1 -zxf "$top_src/a2server-${a2sBranch}.tar.gz"
|
||||
fi
|
||||
|
||||
# Now we actually run the installer as if we were installing it by hand
|
||||
printf "\na2server: Running the update installer now.\n"
|
||||
"${top_src}/install.sh" -i "$@"
|
||||
|
||||
if (( $a2sWebUpdate )); then
|
||||
printf "\na2server: Finished with installer, now deleting ${top_src}.\n"
|
||||
rm -rf "$top_src"
|
||||
fi
|
||||
|
@ -56,7 +56,7 @@
|
||||
1.2.6: Nov 2015: full, ready to use install of Spectrum
|
||||
[unannounced; released briefly, then withdrawn]
|
||||
|
||||
1.5.0: Jan 2016: mixed case filenames for A2FILES; remove GSFILES if empty;
|
||||
1.5.0: Jan 2016: mixed case filenames for A2FILES; remove GSFILES if empty;
|
||||
install Marinetti 3.0b8 with internet access via MacIP;
|
||||
fully install Spectrum, SAFE2, SAM2, SNAP, MountIt; install
|
||||
DOS3.3 and TEACH; remove Ubuntu support; move/media/A2SHARED/*
|
||||
@ -67,12 +67,15 @@
|
||||
for current date; install from any host URL for development;
|
||||
source code at GitHub (thanks Joseph)
|
||||
|
||||
1.5.0r2: Jan 16: fixed GitHub URLs to prevent https errors during installation
|
||||
(thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html)
|
||||
|
||||
1.5.1: Jan 2016: fixed GitHub URLs to prevent https errors during installation
|
||||
(thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html);
|
||||
bug fixes and minor text changes
|
||||
|
||||
|
||||
1.5.1r2: Oct 2017: corrected version number
|
||||
|
||||
|
||||
1.5.2: Nov 2017: support for Debian/Raspbian Stretch; fixes minor bugs during
|
||||
install; enable SSH server if disabled on Raspberry Pi; fixes
|
||||
changed download links for GS/OS communication software
|
||||
|
Loading…
x
Reference in New Issue
Block a user