mirror of
https://github.com/RasppleII/a2server.git
synced 2025-09-11 22:24:38 +00:00
Compare commits
78 Commits
1.2.8
...
current-te
Author | SHA1 | Date | |
---|---|---|---|
|
4fb47b06ed | ||
|
a615ed1808 | ||
|
5e0feab69c | ||
|
a3a7a9479d | ||
|
34836dcbb4 | ||
|
7b7917d417 | ||
|
938db3c46b | ||
|
4d1b5db5e3 | ||
|
7d1a06a916 | ||
|
f9b120002a | ||
|
49d50e49ac | ||
|
dfa1e26c80 | ||
|
d86e3bfa88 | ||
|
cd20570999 | ||
|
cd8271cd56 | ||
|
750b9998df | ||
|
9ba5258fe0 | ||
|
50875f5c3f | ||
|
ca4e3b76e6 | ||
|
3a82176d0a | ||
|
061c3c1897 | ||
|
dea2ea2ce2 | ||
|
bb5f42462e | ||
|
59d293ec84 | ||
|
9dfbe0e9f3 | ||
|
ca12a4a9e9 | ||
|
94b6dcaa26 | ||
|
da204bd05b | ||
|
fbc1ce5ba2 | ||
|
b7528026de | ||
|
60f88e4e8a | ||
|
13343a5c2a | ||
|
95fb701098 | ||
|
3a0e123c0a | ||
|
5c47545772 | ||
|
c5460eb292 | ||
|
653218535f | ||
|
a0ded5a7cf | ||
|
3cc2beabcf | ||
|
4ca810bd26 | ||
|
f8d7a916e2 | ||
|
80c4818d47 | ||
|
b846df61da | ||
|
ec0bf3b9d5 | ||
|
631ad8a2e2 | ||
|
4ad9e10c77 | ||
|
9760380115 | ||
|
5660347bc8 | ||
|
6f835905af | ||
|
9bd8b0d3f0 | ||
|
9b87db8eb4 | ||
|
71274cb18f | ||
|
502e638964 | ||
|
85cbf4d741 | ||
|
c5c14759d1 | ||
|
6e9ddb5e47 | ||
|
180dcc5634 | ||
|
7163390b19 | ||
|
e0a78c5756 | ||
|
8327a5eb8d | ||
|
4a0d574f8a | ||
|
e58fd1bbb1 | ||
|
02442b16e5 | ||
|
00adf2673d | ||
|
fc7aaf4d53 | ||
|
0ca7ef94b8 | ||
|
1403fde73d | ||
|
7e12bbd696 | ||
|
1af347ae8f | ||
|
22020603f6 | ||
|
5fab6a21af | ||
|
6b45259759 | ||
|
4692537443 | ||
|
4e4bd8dbbd | ||
|
d2775f4d27 | ||
|
8f6fae4bb4 | ||
|
53404e7784 | ||
|
01d3ce1775 |
98
README.md
98
README.md
@@ -1,5 +1,6 @@
|
|||||||
# A2SERVER
|
# A2SERVER
|
||||||
AppleTalk server for Apple // computers developed by Ivan Drucker
|
AppleTalk server for Apple // computers developed by Ivan Drucker, with
|
||||||
|
substantial rework and by T. Joseph Carter
|
||||||
|
|
||||||
Documentation here is sparse for the moment; see [Ivan's site]() for
|
Documentation here is sparse for the moment; see [Ivan's site]() for
|
||||||
information about A2SERVER and how it all works. There's a lot there and it's
|
information about A2SERVER and how it all works. There's a lot there and it's
|
||||||
@@ -13,22 +14,91 @@ relatively modern piece of it. As such they should be preserved as they are.
|
|||||||
|
|
||||||
## Developer note
|
## Developer note
|
||||||
|
|
||||||
To use the scripts on a server other than Ivan's, you'll want to export
|
To use the scripts with a specific GitHub tag:
|
||||||
the shell variable A2SERVER_SCRIPT_URL to the base URL of this repository
|
|
||||||
on your server. The base-URL should be slash-terminated. You can then run
|
|
||||||
the following snippet:
|
|
||||||
|
|
||||||
~~~ bash
|
~~~ bash
|
||||||
wget -O a2server-setup ${A2SERVER_SCRIPT_URL}setup/index.txt; source a2server-setup
|
export A2SERVER_SCRIPT_URL=https://raw.githubusercontent.com/RasppleII/a2server/TAG_GOES_HERE/
|
||||||
|
export A2SERVER_BINARY_URL=${A2SERVER_SCRIPT_URL}files
|
||||||
|
wget -O setup ${A2SERVER_SCRIPT_URL}setup/index.txt; source setup
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
A simple method for installing from a local subdirectory is to `cd` to it and
|
Or, to use the scripts on your own server, including your local machine:
|
||||||
then type `python -m SimpleHTTPServer`. Then
|
|
||||||
`export A2SERVER_SCRIPT_URL="http://localhost:8000/"`
|
~~~ bash
|
||||||
or use the IP address of the host machine on your LAN instead of localhost.
|
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
|
||||||
|
~~~
|
||||||
|
|
||||||
You should probably export A2SERVER_SCRIPT_URL in your .bashrc or whatever
|
|
||||||
file configures your development environment. Also be advised that as of
|
|
||||||
version 1.24 of A2SERVER, you must use the snippet above.
|
|
||||||
|
|
||||||
[Ivan's site]: http://appleii.ivanx.com/a2server/
|
[Ivan's site]: http://appleii.ivanx.com/a2server/
|
||||||
|
@@ -1,19 +0,0 @@
|
|||||||
# Ivan Drucker's A2SERVER documentation
|
|
||||||
|
|
||||||
A2SERVER was not so much planned as it was evolved. It began as a project to
|
|
||||||
boot an Apple //e card in a Macintosh over AppleTalk using a small embedded
|
|
||||||
Linux-based computer and evolved over time into what it is today.
|
|
||||||
|
|
||||||
So too has its documentation. And while one of the goals of this project is
|
|
||||||
to produce a full manual for A2SERVER, the pages on Ivan's website effectively
|
|
||||||
are a manual if you dig through them a bit.
|
|
||||||
|
|
||||||
More than that, Ivan's pages are a piece of recent Apple // history. Future
|
|
||||||
endeavors may improve upon what is contained within those pages, but it will
|
|
||||||
not and indeed cannot replace them.
|
|
||||||
|
|
||||||
Thus the content of those pages as of mid-October 2015 (version 1.2.4) is
|
|
||||||
reproduced here in Markdown format in order to be most widely readable. Where
|
|
||||||
unconvertable HTML with no direct non-HTML equivalent exists, this archive
|
|
||||||
will prefer readability to source accuracy. Examples of this include things
|
|
||||||
such as replacing formatting using non-breaking spaces with an unordered list.
|
|
@@ -1,43 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
You probably want to be able to get stuff on and off of A2SERVER, so that
|
|
||||||
means connecting to it from other computers.
|
|
||||||
|
|
||||||
You can browse your network and you should see either "raspberrypi" or
|
|
||||||
"a2server" as a server you can connect to. You can log in as Guest if asked.
|
|
||||||
|
|
||||||
On Mac OS X, it should appear under Shared in the sidebar of a Finder window,
|
|
||||||
or under "Network" from the "Go" menu of the Finder.
|
|
||||||
|
|
||||||
On Windows, it should appear under Network.
|
|
||||||
|
|
||||||
On Mac OS 7 through 9, open Chooser from the Apple menu and click on
|
|
||||||
AppleShare.
|
|
||||||
|
|
||||||
(If you can't browse to the server on your network, you may need to [log in
|
|
||||||
to A2SERVER](a2server_commands.md) to update, and if that doesn't work, to
|
|
||||||
find its IP address. On Mac OS X, enter the IP address under "Connect To
|
|
||||||
Server..." from the Go menu of the Finder; on Windows, type the IP address
|
|
||||||
following two backslash characters (\\) in an Explorer window.)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Content edit: Make sure both Markdown source and HTML target renderings of how
|
|
||||||
to specify a backslash-delimited UNC path are understandable. -Joseph
|
|
||||||
-->
|
|
||||||
|
|
||||||
You will see two or three shared volumes: A2FILES, GSFILES, and, if you have
|
|
||||||
A2CLOUD installed, ADTDISKS. Avoid the A2FILES volume except for copying
|
|
||||||
things off of it. If you do want to put stuff on it, be careful to only use
|
|
||||||
ProDOS-compliant filenames (all caps, 15 characters max, starts with a letter,
|
|
||||||
and only contains letters/numbers/periods). Otherwise, you'll get unexpected
|
|
||||||
behavior like invisible files.
|
|
||||||
|
|
||||||
Unix-type computers can also use `scp` to copy files to and from A2SERVER;
|
|
||||||
Windows computers can also do so in the command window by using `pscp` in
|
|
||||||
[PuTTY][1]. The shared volumes are within /srv/A2SERVER.
|
|
||||||
|
|
||||||
If you need to set the ProDOS file type of a file you have copied to A2SERVER,
|
|
||||||
[log in to A2SERVER](a2server_commands.md) and use `afptype`.
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://www.chiark.greenend.org.uk/~sgtatham/putty/
|
|
@@ -1,128 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
Sometimes you need to access the A2SERVER command line to set up network boot
|
|
||||||
or do other stuff. A list of commands is below.
|
|
||||||
|
|
||||||
If you are running A2SERVER on a Raspberry Pi without a screen and keyboard
|
|
||||||
attached, see how to
|
|
||||||
[log in to a Raspberry Pi](a2server_raspberrypi_login.md).
|
|
||||||
|
|
||||||
Otherwise, log in on your local console or virtual machine window, or via SSH
|
|
||||||
on another computer. On Mac OS X, or Windows with [Bonjour Print Services][1]
|
|
||||||
installed, you can use "raspberrypi.local" for your SSH address, or
|
|
||||||
"a2server.local" if not on a Pi. If that doesn't work, try updating
|
|
||||||
A2SERVER by typing `a2server-setup`.
|
|
||||||
|
|
||||||
If it still doesn't work, or you don't want to install Bonjour Print
|
|
||||||
services for Windows, you will need to use A2SERVER's IP address instead,
|
|
||||||
which you can see by typing `showip`. You can create a DHCP reservation in
|
|
||||||
your router to give A2SERVER the same IP address every time. To do this,
|
|
||||||
you'll need the MAC (Ethernet) address of the machine (or virtual machine)
|
|
||||||
running A2SERVER, which you can see by typing `showmac`. If you are using the
|
|
||||||
premade virtual machine, the MAC is 08:00:03:F2:FF:59 .
|
|
||||||
|
|
||||||
The default username is either "pi" for Raspberry Pi, and otherwise
|
|
||||||
"user1". The password is "apple2". (The password is "raspberry" for an
|
|
||||||
standard installation of Raspbian; you can use the
|
|
||||||
[installer script](a2server_installer.md) to install A2SERVER.)
|
|
||||||
|
|
||||||
Shared volumes can be found at /srv/A2SERVER. Netatalk configuration files
|
|
||||||
are in /usr/local/etc/netatalk.
|
|
||||||
|
|
||||||
Once logged in, you can enter the following commands.
|
|
||||||
|
|
||||||
(If any of these yield "command not found", refresh the command list by
|
|
||||||
typing `a2server-setup`, answering "no" to all prompts if you like.)
|
|
||||||
|
|
||||||
|
|
||||||
~~~
|
|
||||||
A2SERVER commands:
|
|
||||||
(note: new commands may be added; use a2server-setup to refresh)
|
|
||||||
|
|
||||||
a2server-help: show this list of commands
|
|
||||||
a2server-setup: set up network boot, Windows access, Farallon fix,
|
|
||||||
refresh command list
|
|
||||||
a2server-version: see installed version of A2SERVER
|
|
||||||
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
|
|
||||||
|
|
||||||
welcome-message-edit: change the welcome message
|
|
||||||
|
|
||||||
showip: show the current ethernet IP address of the server
|
|
||||||
showmac: show the MAC (Ethernet hardware) address of the server
|
|
||||||
showip-wifi: show the current wifi IP address of the server
|
|
||||||
showmac-wifi: show the MAC (wifi hardware) address of the server
|
|
||||||
ifreset: reset all network interfaces (requires restart)
|
|
||||||
|
|
||||||
netatalk-stop: stop the netatalk service until reboot
|
|
||||||
netatalk-start: start the netatalk service
|
|
||||||
netatalk-restart: restart the netatalk service
|
|
||||||
netatalk-off: disable the netatalk service (even after reboot)
|
|
||||||
netatalk-on: enable the netatalk service
|
|
||||||
|
|
||||||
bonjour-off: disable advertisement of shared folders to OS X
|
|
||||||
bonjour-on : enable advertisement of shared folders to OS X
|
|
||||||
(these are automatically set by the netatalk commands above)
|
|
||||||
|
|
||||||
netatalk-router-on: use netatalk in router mode (default)
|
|
||||||
netatalk-router-off: use netatalk in node mode
|
|
||||||
(use if there is an AppleTalk router such as a GatorBox present)
|
|
||||||
|
|
||||||
netatalk-eth: use wired ethernet interface for netatalk (default)
|
|
||||||
netatalk-wifi: use wifi interface for netatalk
|
|
||||||
note: if an interface isn't available, netatalk will be reset with
|
|
||||||
router mode off; use "netatalk-router-on" to correct this if needed
|
|
||||||
|
|
||||||
appletalk-off: disable AppleTalk networking (even after reboot)
|
|
||||||
appletalk-on : enable AppleTalk networking
|
|
||||||
|
|
||||||
environment variables:
|
|
||||||
$NETATALK: directory containing netatalk configuration files
|
|
||||||
$A2FILES : directory containing A2FILES shared volume
|
|
||||||
$GSFILES : directory containing GSFILES shared volume
|
|
||||||
|
|
||||||
netboot-gsos: set the current user to netboot into GS/OS (default)
|
|
||||||
netboot-gsos-guest: set guests to netboot into GS/OS
|
|
||||||
netboot-p8: set the current user to netboot into ProDOS 8
|
|
||||||
netboot-p8-guest: set guests to netboot into ProDOS 8 (default)
|
|
||||||
note: when a IIgs is set to network boot into GS/OS, using the Network
|
|
||||||
control panel or the NETBOOT.GSOS utility, guests will behave like
|
|
||||||
registered users, and ignore the netboot setting of the guest user
|
|
||||||
|
|
||||||
guest-off: disallow guest access to A2SERVER
|
|
||||||
guest-on: allow guest access to A2SERVER (default)
|
|
||||||
note: by default, Guest access is the only way to network boot into
|
|
||||||
ProDOS 8. For registered user boot into ProDOS 8, type "netboot-p8"
|
|
||||||
|
|
||||||
samba-off: disable Windows file sharing (even after reboot)
|
|
||||||
samba-on: enable Windows file Sharing
|
|
||||||
samba-stop: stop Windows file sharing until reboot
|
|
||||||
samba-start: start Windows file sharing
|
|
||||||
samba-restart: stop and restart Windows file sharing
|
|
||||||
|
|
||||||
gsfiles-share: disable the GSFILES shared volume
|
|
||||||
gsfiles-unshare: enable the GSFILES shared volume
|
|
||||||
a2files-share: disable the A2FILES shared volume
|
|
||||||
a2files-unshare: enable the A2FILES shared volume
|
|
||||||
|
|
||||||
nulib2: create, extract, and work with NuFX (ShrinkIt) archive files
|
|
||||||
unar: extract other archive files (multiformat)
|
|
||||||
lsar: list contents of other archive files (multiformat)
|
|
||||||
|
|
||||||
afptype: set the ProDOS type/auxtype or Mac OS type/creator of a file
|
|
||||||
afpsync: register files introduced outside of AFP with netatalk
|
|
||||||
mkatinit: set up network boot configuration files
|
|
||||||
cppo: catalog and copy files from ProDOS image file (slow, but works)
|
|
||||||
(add -h to show help for the above four commands, e.g. "afptype -h")
|
|
||||||
|
|
||||||
~~~
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://support.apple.com/kb/dl999
|
|
@@ -1,84 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
A2SERVER's central capability, sharing files to an Apple II, is provided by
|
|
||||||
[Netatalk][1] 2.2.4.
|
|
||||||
|
|
||||||
Here's the extra sauce that A2SERVER provides:
|
|
||||||
|
|
||||||
* available as a ready-to-use [Raspberry Pi][2] operating system installer
|
|
||||||
|
|
||||||
(plus new [Pi Filler][3] and [Pi Copier][3] utilities for easy SD card
|
|
||||||
creation and backup)
|
|
||||||
|
|
||||||
* available as a ready-to-use [VirtualBox][4] appliance for Mac OS X, Windows,
|
|
||||||
Linux, and Solari
|
|
||||||
|
|
||||||
* simple downloadable installation script for Ubuntu Linux or Raspbian takes
|
|
||||||
care of setting up and configuring *everything*
|
|
||||||
|
|
||||||
* enables reliable operation by Asante, Farallon and Dayna bridges on both IIe
|
|
||||||
*and* IIgs \[fixes contributed by Steven Hirsch and Geoff Body\]
|
|
||||||
|
|
||||||
* easy to configure for network boot, including ProDOS 8 and GS/OS download
|
|
||||||
and installation
|
|
||||||
|
|
||||||
* can network boot both IIe and IIgs computers on the same network
|
|
||||||
|
|
||||||
* new ProDOS 8 tools (NETBOOT.P8 and NETBOOT.GSOS) for setting the IIg network
|
|
||||||
boot default
|
|
||||||
|
|
||||||
* temporary ProDOS 8 network boot without changing GS/OS default \[contributed
|
|
||||||
by Geoff Body\]
|
|
||||||
|
|
||||||
* GS/OS installer that can be run from folders rather than disk
|
|
||||||
|
|
||||||
* installs ProDOS 8 and GS/OS utilities for working with archive (ShrinkIt and
|
|
||||||
GSHK), disk images ([DSK2FILE][5] / [Asimov][6] / [MountIt][7]), and file
|
|
||||||
(Apple ProDOS System Utilities)
|
|
||||||
|
|
||||||
* supports Wi-Fi when used with Apple AirPort or Time Capsul
|
|
||||||
|
|
||||||
* maintains correct dates during GS/OS folder copy \[fix contributed by Steven
|
|
||||||
Hirsch\]
|
|
||||||
|
|
||||||
* uses randnum authentication for registered user sign-in (which alway works,
|
|
||||||
unlike cleartext)
|
|
||||||
|
|
||||||
* supports login to shared volumes from latest versions of OS X and Window
|
|
||||||
|
|
||||||
* new Linux tool ([afptype](scripts/tools/afptype.txt)) for setting ProDOS or
|
|
||||||
classic Mac file types on shared volume
|
|
||||||
|
|
||||||
* new Linux tool ([cppo](scripts/tools/cppo.txt)) for cataloging and copying
|
|
||||||
files (with optional resource forks) out of ProDOS disk image
|
|
||||||
|
|
||||||
* [Linux commands](a2server_commands.md) to ease server maintenanc
|
|
||||||
|
|
||||||
* installs Linux tools for working with ShrinkIt and other old and new archive
|
|
||||||
formats ([nulib2][8] and [unar/lsar][9])
|
|
||||||
|
|
||||||
<!--
|
|
||||||
* sets up Raspberry Pi for shell login from Apple II via USB-serial cable or
|
|
||||||
Raspberry Pi console cable
|
|
||||||
-->
|
|
||||||
|
|
||||||
* blinks Raspberry Pi OK/ACT LED for ten seconds when netatalk has just
|
|
||||||
started
|
|
||||||
|
|
||||||
* good documentation (or so I hope)
|
|
||||||
|
|
||||||
|
|
||||||
Any content unique to A2SERVER and not covered under a specific license is
|
|
||||||
licensed under the [WTFPL][10].
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://netatalk.sourceforge.net
|
|
||||||
[2]: http://www.raspberrypi.org
|
|
||||||
[3]: http://ivanx.com/raspberrypi/
|
|
||||||
[4]: http://www.virtualbox.org
|
|
||||||
[5]: http://www.dwheeler.com/6502/oneelkruns/dsk2file.html
|
|
||||||
[6]: http://www.ninjaforce.com/html/products.html
|
|
||||||
[7]: http://www.brutaldeluxe.fr/products/apple2gs/mountit.html
|
|
||||||
[8]: http://www.nulib.com
|
|
||||||
[9]: http://unarchiver.c3.cx
|
|
||||||
[10]: http://www.wtfpl.net
|
|
@@ -1,63 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
To connect to A2SERVER from your Apple II:
|
|
||||||
|
|
||||||
(An alternative to the below is to [boot your Apple II over the
|
|
||||||
network](a2server_netboot.md) -- check that out too.)
|
|
||||||
|
|
||||||
Start up A2SERVER and wait (potentially up to a minute) until you get to the
|
|
||||||
login prompt. You do not need to log in. On a Raspberry Pi, you can see that
|
|
||||||
it's ready when the the normally irregular ACT or OK LED blinks steadily and
|
|
||||||
rapidly for ten seconds.
|
|
||||||
|
|
||||||
If you are on a IIe, boot from the [Workstation Card disk](#wsdisks), and
|
|
||||||
choose "Log On".
|
|
||||||
|
|
||||||
If you are on a IIgs, open the AppleShare control panel. If you don't have
|
|
||||||
it, use the GS/OS installer disks to custom install the script called
|
|
||||||
"Network: AppleShare" to your startup disk. If you are on a floppy-only
|
|
||||||
system, you can instead use the script "Network: AppleShare, 3.5" disk" to
|
|
||||||
make a bootable disk, or consider setting up
|
|
||||||
[network boot](a2server_netboot.md).
|
|
||||||
|
|
||||||
(There is also an obsolete [IIgs Workstation Disk](#wsdisks) that boots into
|
|
||||||
ProDOS 16 rather than GS/OS, and has the same ProDOS 8 applications for server
|
|
||||||
access as the IIe disk. You probably don't want to use it.)
|
|
||||||
|
|
||||||
"a2server" or "raspberrypi" should appear in the list of server names. Log
|
|
||||||
in as Guest and select the A2FILES volume, for ProDOS 8 storage, and/or the
|
|
||||||
GSFILES volume, for GS/OS storage. (You can also log in as a registered user,
|
|
||||||
but it's exactly the same.)
|
|
||||||
|
|
||||||
On the A2FILES volume, filenames need to be all caps and are subject to the
|
|
||||||
usual ProDOS restrictions (letters/numbers/periods only, first character must
|
|
||||||
be a letter, 15 characters max). IIgs users can store files on GSFILES with
|
|
||||||
mixed case, punctuated names of up to 31 characters (same as a classic Mac).
|
|
||||||
|
|
||||||
The network volumes hosted by A2SERVER will appear on the Finder desktop in
|
|
||||||
GS/OS; in ProDOS 8, you can type `PREFIX /A2FILES`.
|
|
||||||
|
|
||||||
### Workstation Software: {#wsdisk}
|
|
||||||
|
|
||||||
<!--
|
|
||||||
FIXME: These disk images are not (at present) contained within this archive.
|
|
||||||
Moreover, they cannot be directly included in properly "Open Source" packages
|
|
||||||
of A2SERVER which ought to include this archive. They'll have to be external
|
|
||||||
links, but I'm not fixing that right now. -tjcarter,2015-10-22
|
|
||||||
-->
|
|
||||||
|
|
||||||
* IIe Workstation Card, 800K:
|
|
||||||
[raw image](files/a2ws/A2E.WS.FULL.HDV)
|
|
||||||
[ShrinkIt image](files/a2ws/A2E.WS.FULL.BXY)
|
|
||||||
|
|
||||||
* IIe Workstation Card, Logon/Logoff/BASIC only, 140K:
|
|
||||||
[raw image](files/a2ws/A2E.WS.LITE.DSK)
|
|
||||||
[ShrinkIt image](files/a2ws/A2E.WS.LITE.BXY)
|
|
||||||
|
|
||||||
* IIe Workstation Card, System Utilities/BASIC only, 140K:
|
|
||||||
[raw image](files/a2ws/A2E.WS.UTIL.DSK)
|
|
||||||
[ShrinkIt image](files/a2ws/A2E.WS.UTIL.BXY)
|
|
||||||
|
|
||||||
* IIgs Workstation, 800K \[superseded by GS/OS AppleShare software\]:
|
|
||||||
[raw image](files/a2ws/A2GS.WS.HDV)
|
|
||||||
[ShrinkIt image](files/a2ws/A2E.WS.BXY)
|
|
@@ -1,53 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
You can easily install A2SERVER on Debian, Ubuntu, or Raspbian Linux by using
|
|
||||||
the A2SERVER install scripts.
|
|
||||||
|
|
||||||
While these are the only Linux distributions the scripts have been tested on,
|
|
||||||
other Debian-derived distributions may work as well, provided they're not
|
|
||||||
based on Debian 8, don't use kernel 3.12 through 3.15, have AppleTalk
|
|
||||||
networking support available as a kernel module or compiled into the kernel
|
|
||||||
itself, and their repositories contain the packages the scripts require. The
|
|
||||||
user running the scripts needs a bash shell, sudo privileges, and a search
|
|
||||||
path containing all the "bin" and "sbin" directories.
|
|
||||||
|
|
||||||
|
|
||||||
### Debian or Ubuntu Linux
|
|
||||||
|
|
||||||
(Tested on Debian 7.8.0 and Ubuntu Server 12.04 LTS. Note that Ubuntu 14.04
|
|
||||||
LTS includes kernel 3.13, which is *not* compatible with A2SERVER; you will
|
|
||||||
need to upgrade it to 3.16 or later. Debian 8 and Ubuntu 15 *cannot* be used
|
|
||||||
at this time.)
|
|
||||||
|
|
||||||
1. [Create a new virtual machine](a2server_prepvm.md) (skip if installing on a
|
|
||||||
real machine)
|
|
||||||
2. [Install Debian](a2server_installubuntu.md) (or Ubuntu) on the virtual or
|
|
||||||
real machine
|
|
||||||
|
|
||||||
|
|
||||||
### Raspberry Pi
|
|
||||||
|
|
||||||
1. [Download Raspbian][1]
|
|
||||||
2. [Perform Raspberry Pi setup](a2server_raspberrypi.md)
|
|
||||||
|
|
||||||
|
|
||||||
Once you are up and running in Linux, you can execute the automated setup
|
|
||||||
scripts to download, install, and configure the A2SERVER software. To use
|
|
||||||
these, [log in to Linux](a2server_commands.md), and type:
|
|
||||||
|
|
||||||
~~~ bash
|
|
||||||
wget appleii.ivanx.com/a2server/setup; source setup
|
|
||||||
~~~
|
|
||||||
|
|
||||||
Confirm that you want to proceed, enter the password again, and go get a
|
|
||||||
sandwich, but come back so you can answer questions when prompted.
|
|
||||||
|
|
||||||
Once it's done, check out the links on the [A2SERVER home page](index.md) for
|
|
||||||
next steps.
|
|
||||||
|
|
||||||
If you'd like to set things up manually, or are curious as to what's
|
|
||||||
happening, you can
|
|
||||||
[view the contents of the setup scripts](a2server_scriptdetails.md).
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://www.raspberrypi.org/downloads
|
|
@@ -1,58 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
These steps cover how to install Ubuntu Server Linux into your empty virtual or real machine. (The instructions are similar, but may vary somewhat, for Debian Linux.)
|
|
||||||
|
|
||||||
* Download [Ubuntu Server 12.04 LTS][1], and burn it to a CD if
|
|
||||||
installing on a real machine; otherwise, attach the download to your
|
|
||||||
virtual machine's CD/DVD drive.
|
|
||||||
|
|
||||||
* Click Start.
|
|
||||||
|
|
||||||
* Answer all the region related questions and choose to Install Ubuntu
|
|
||||||
Server.
|
|
||||||
|
|
||||||
* For hostname, enter *a2server*
|
|
||||||
|
|
||||||
* Under Partition Disks, choose "Guided - use entire disk" (no LVM).
|
|
||||||
|
|
||||||
* Choose SCSI1 (or whatever other disk appears), and (two screens later)
|
|
||||||
confirm "Write the changes to disks."
|
|
||||||
|
|
||||||
* If you are installing Debian, and are prompted for a domain name or
|
|
||||||
the root user password, leave them blank.
|
|
||||||
|
|
||||||
* Enter *user1* as the full name for the new user, and as the username
|
|
||||||
for your account
|
|
||||||
|
|
||||||
* Choose *apple2* as the password, verify by retyping, and then confirm
|
|
||||||
weak password
|
|
||||||
|
|
||||||
* Choose not to encrypt your home directory
|
|
||||||
|
|
||||||
* If you require an HTTP proxy, enter it, or leave it blank if not.
|
|
||||||
|
|
||||||
* Choose yes to Install the GRUB boot loader to the master boot record
|
|
||||||
|
|
||||||
* Choose no automatic updates
|
|
||||||
|
|
||||||
* Choose OpenSSH under Software Selection (and, for Debian, Standard
|
|
||||||
System Utilities)
|
|
||||||
|
|
||||||
* Click Continue to reboot
|
|
||||||
|
|
||||||
* When prompted, log in with username *user1* and password *apple2*.
|
|
||||||
|
|
||||||
* If you installed Debian rather than Ubuntu, type:
|
|
||||||
|
|
||||||
~~~ bash
|
|
||||||
sudo sed -i '0,/-eq 0/s/-eq 0/-ge 0/' /etc/profile
|
|
||||||
~~~
|
|
||||||
|
|
||||||
* When you're back at the prompt, type `sudo shutdown -h now` which
|
|
||||||
will turn off the (virtual) machine.
|
|
||||||
|
|
||||||
* Recommended: If you are using a virtual machine, take a snapshot you
|
|
||||||
can return to this point if necessary.
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://www.ubuntu.com/download/server/download
|
|
@@ -1,122 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
In order to connect your Apple II to the network, you need a LocalTalk to
|
|
||||||
Ethernet bridge. (Unfortunately, the [Uthernet card][1] will not work, as
|
|
||||||
Apple's network drivers don't know what it is.)
|
|
||||||
|
|
||||||
If you have an enhanced Apple IIe, you will also need an [Apple II Workstation
|
|
||||||
Card][2], and, if you're not booting over the network, the [Workstation Card
|
|
||||||
software](a2server_howtouse.html#wsdisks). Make sure you buy one with the
|
|
||||||
dongle. \[ <!-- [Blujay][3] --> [eBay][4] \]
|
|
||||||
|
|
||||||
These are the commonly available bridges; be sure you read below about their
|
|
||||||
idiosyncracies before you buy one.
|
|
||||||
|
|
||||||
* Asante [AsanteTalk][5] and AsantePrint \[ [Asante][6] [eBay][7] \]
|
|
||||||
|
|
||||||
* Dayna EtherPrint and Mini EtherPrint (any model with an Ethernet port)
|
|
||||||
\[ [eBay][8] \]
|
|
||||||
|
|
||||||
* Farallon EtherWave/EtherMac/iPrint LT with LocalTalk (PN842, PN848 or
|
|
||||||
PN559) \[ [eBay][9] \]
|
|
||||||
|
|
||||||
* A pre-USB Mac with any kind of Ethernet, and the [LocalTalk Bridge][10]
|
|
||||||
control panel installed \[ [eBay][11] \]
|
|
||||||
|
|
||||||
You'll also need an ImageWriter II printer cable (or any other 8-pin mini-DIN
|
|
||||||
null-modem serial cable), or two LocalTalk transceivers joined by either a
|
|
||||||
LocalTalk cable or four-wire phone cord, depending on whether you have Apple
|
|
||||||
or PhoneNet transceivers. (PhoneNet transceivers also require a terminator at
|
|
||||||
both ends; it looks like a phone plug with a resistor sticking out of it.)
|
|
||||||
Connect each end to your Apple II and the bridge, and an Ethernet cable
|
|
||||||
between the bridge and your router.
|
|
||||||
|
|
||||||
For an Apple IIgs, go to the Slots control panel by pressing ctrl-Apple-ESC,
|
|
||||||
and set slot 1 or 2, depending on whether you are using the printer or modem
|
|
||||||
port for networking, to "Your Card" (ROM 01 machines) or "AppleTalk" (ROM
|
|
||||||
3 machines), and set slot 7 to "AppleTalk" (ROM 01 machines only). For an
|
|
||||||
Apple IIe, install the Workstation Card in any slot, and be sure to connect
|
|
||||||
your LocalTalk cable to the port with the double-arrow icon.
|
|
||||||
|
|
||||||
If you have multiple Apple II's you'd like to network, you can use a bridge
|
|
||||||
for each, or a single bridge attached to daisy-chained LocalTalk transceivers.
|
|
||||||
|
|
||||||
Wired ethernet is recommended, but if you have an Apple AirPort or Time
|
|
||||||
Capsule, you can use Wi-Fi by attaching your LocalTalk-to-Ethernet bridge to a
|
|
||||||
another AirPort, and setting up an [extended network][12] (if all AirPorts are
|
|
||||||
802.11n models), or a [WDS][13] (if any AirPort is an 802.11g model). (Most
|
|
||||||
non-Apple routers and access points will not work because they are not
|
|
||||||
designed to handle AppleTalk networking.)
|
|
||||||
|
|
||||||
|
|
||||||
Caveat emptor:
|
|
||||||
|
|
||||||
* The AsanteTalk must be powered on while A2SERVER is up and running, or it
|
|
||||||
will enter a mode where it won't operate correctly. (On the AsanteTalk, you
|
|
||||||
will know it entered the right mode if the TX light blinks a lot during
|
|
||||||
power-up. If it instead pulses only two or three times, then goes dark for a
|
|
||||||
little while, and then pulses very rapidly for about three seconds, you'll
|
|
||||||
need to remove power, make sure A2SERVER is running, and try again.)
|
|
||||||
|
|
||||||
* At least some of the Dayna bridges must be attached to a 10Base-T Ethernet
|
|
||||||
port; they won't work if attached to an autosensing 10/100 or Gigabit
|
|
||||||
Ethernet port such as those found on modern routers and switches. You can
|
|
||||||
[buy a 10Base-T hub on eBay][14] for around $10 to go between your router
|
|
||||||
and the bridge.
|
|
||||||
|
|
||||||
* Farallon bridges work fine with an Apple IIe. To prevent them from freezing
|
|
||||||
a IIgs after a couple of minutes, you can download a fix for GS/OS ([disk
|
|
||||||
image][15] or [ShrinkIt][16] format) and put it into SYSTEM/SYSTEM.SETUP, or
|
|
||||||
you can [log in to the A2SERVER console](a2server_commands.html) and type
|
|
||||||
`a2server-setup` and you will be asked if you want to install it. Because
|
|
||||||
the fix is for GS/OS only, Farallon bridges will *not* work with a IIgs
|
|
||||||
booted directly into ProDOS 8. (Also note: the PN842 has a built-in 8-pin
|
|
||||||
cable, and the PN848 and PN559 have a built-in PhoneNet terminated
|
|
||||||
transceiver, so you might not need all the cabling described above.)
|
|
||||||
|
|
||||||
* Using a classic Mac as a bridge works perfectly in all cases. Set AppleTalk
|
|
||||||
to use the Ethernet port, attach the LocalTalk tranceiver or serial cable to
|
|
||||||
the printer port (or printer/modem port), and install [LocalTalk
|
|
||||||
Bridge][10]. (Recommended models: PowerBook 3400 with Ethernet, PowerBook G3
|
|
||||||
with black keyboard. Any model with both a round serial port and any kind of
|
|
||||||
Ethernet, including via expansion card, AAUI adapter, or SCSI adapter,
|
|
||||||
should work.)
|
|
||||||
|
|
||||||
And finally:
|
|
||||||
|
|
||||||
* The Cayman GatorBox CS and the Shiva FastPath IV and V have been reported to
|
|
||||||
work, but it's hard to find these, so I have been unable to test. If you
|
|
||||||
have one of these and it doesn't work, [log in](a2server_commands.html) to
|
|
||||||
A2SERVER and type `netatalk-router-off` (if you get "command not found",
|
|
||||||
type `a2server-setup` to refresh the command list).
|
|
||||||
|
|
||||||
* Other LocalTalk-to-Ethernet routers and bridges may work too, but haven't
|
|
||||||
been tested by me.
|
|
||||||
|
|
||||||
|
|
||||||
Thank you:
|
|
||||||
|
|
||||||
Many thanks to Steven Hirsch, who fixed the Netatalk code in A2SERVER to make
|
|
||||||
the Asante bridges start up reliably, and prevent the Dayna bridges from
|
|
||||||
crashing the computer in GS/OS; and many thanks to Geoff Body, who contributed
|
|
||||||
the patch to GS/OS to make Farallon bridges work reliably without freezing a
|
|
||||||
IIgs after a few minutes. Also, thanks to all who have tested and sent reports
|
|
||||||
on using A2SERVER with their bridges.
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://a2retrosystems.com/
|
|
||||||
[2]: http://www.apple2info.net/hardware/a2ews/a2ews.htm
|
|
||||||
[3]: http://www.blujay.com/?keywords=workstation+card&Search.x=0&Search.y=0&Search=Search&page=search
|
|
||||||
[4]: http://www.ebay.com/sch/i.html?_nkw=apple+workstation+card+-portrait
|
|
||||||
[5]: http://www.asante.com/products/Asantetalk/Asantetalk.asp
|
|
||||||
[6]: http://www.asante.com/shop/shopdisplayproducts.asp?id=16&cat=+AsanteTalk
|
|
||||||
[7]: http://www.ebay.com/sch/i.html?_nkw=%28asantetalk%2C+asanteprint%29
|
|
||||||
[8]: http://www.ebay.com/sch/i.html?_nkw=etherprint
|
|
||||||
[9]: http://www.ebay.com/sch/i.html?_nkw=farallon+%28etherwave%2Cethermac%2Ciprint%29+-sl+-aui+-aaui+-pci+-nubus+-pds+-card
|
|
||||||
[10]: http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FMacintosh%2FNetworking-Communications%2FOther_N-C%2FLocalTalk_Bridge_2.1.smi.bin
|
|
||||||
[11]: http://www.ebay.com/sch/i.html?_nkw=powerbook%20(3400c%2Cg3)%20-adapter%20-pismo%20-lombard%20-bronze%20-ibook%20-g4%20-333%20-333mhz%20-400%20-400mhz%20-500%20-500mhz
|
|
||||||
[12]: http://support.apple.com/kb/HT4259
|
|
||||||
[13]: http://support.apple.com/kb/HT4262
|
|
||||||
[14]: http://www.ebay.com/sch/i.html?_odkw=10base-t+%28hub%2Cswitch%29+-fast+-100+-1000+-gigabit
|
|
||||||
[15]: http://appleii.ivanx.com/a2server/files/FARALLON.B1.PO
|
|
||||||
[16]: http://appleii.ivanx.com/a2server/files/FARALLON.B1.BXY
|
|
@@ -1,48 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
You can set up A2SERVER to let your Apple IIgs or IIe boot into GS/OS or
|
|
||||||
ProDOS 8 over the network, rather than from a local drive. It can even
|
|
||||||
download and install ProDOS 8 and GS/OS for you, meaning you can get up and
|
|
||||||
running from "bare metal" if you wanted to.
|
|
||||||
|
|
||||||
To do this, [log into the a2server console](a2server_commands.md), and type:
|
|
||||||
|
|
||||||
~~~ bash
|
|
||||||
a2server-setup
|
|
||||||
~~~
|
|
||||||
|
|
||||||
After confirming that you want to proceed, you will be asked if you want to
|
|
||||||
set up A2SERVER for network boot. Just follow the prompts. If you elect to
|
|
||||||
install GS/OS, be prepared to wait for a while. You will also be given the
|
|
||||||
option to install various utilities (GSHK, Asimov, and MountIt for GS/OS;
|
|
||||||
ShrinkIt, DSK2FILE, and Apple System Utilities for ProDOS 8.)
|
|
||||||
|
|
||||||
For an Apple IIgs, set the startup slot to Slot 7 (ROM 01) or AppleTalk (ROM
|
|
||||||
3). For an Apple IIe, put the Workstation Card in a slot higher than any other
|
|
||||||
drive interface card, or type PR#x where x is the slot number; you must hold
|
|
||||||
down the Open-Apple key when you press return.
|
|
||||||
|
|
||||||
When your Apple II boots up, it will try to boot from the network. If it's
|
|
||||||
working, you'll see a flashing asterisk on a IIe, or a progression of periods
|
|
||||||
at the upper left of the screen on a IIgs. You may or may not be asked to
|
|
||||||
choose "a2server" or "raspberrypi" as your server.
|
|
||||||
|
|
||||||
Log in as Guest and select the A2FILES volume, and also the GSFILES volume if
|
|
||||||
you're using a IIgs. (If you are booting into GS/OS, you can also log in as a
|
|
||||||
registered user, but it's exactly the same.)
|
|
||||||
|
|
||||||
ProDOS 8 and GS/OS are stored on the volume /A2FILES; filenames are all caps
|
|
||||||
and subject to the usual ProDOS restrictions. IIgs users can store files on
|
|
||||||
the volume /GSFILES with mixed case, punctuated names of up to 31 characters.
|
|
||||||
|
|
||||||
If you installed GS/OS, you'll see a folder called GSOS.INSTALLER. In there,
|
|
||||||
IMAGES contains all the GS/OS floppies, which can be turned back into disks by
|
|
||||||
using Asimov in the IMAGE.TOOLS folder. You can also use run the GS/OS
|
|
||||||
installer from the NET.INSTALL folder instead of using disks.
|
|
||||||
|
|
||||||
A IIgs can network boot into either GS/OS or ProDOS 8 by default, which you
|
|
||||||
specify in the Network control panel of GS/OS, or within ProDOS 8 by running
|
|
||||||
NETBOOT.GSOS or NETBOOT.P8, which you'll find in A2FILES (both reboot the
|
|
||||||
computer immediately). You can temporarily network boot into ProDOS 8, without
|
|
||||||
changing the GS/OS default, by pressing "8" while the dots are filling in
|
|
||||||
during the first phase of the network boot (thanks to Geoff Body for this).
|
|
@@ -1,68 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
The following steps explain how to prep the A2SERVER virtual machine,
|
|
||||||
specifically [VirtualBox][1], which has the notable virtue of being free.
|
|
||||||
However, you can also use other virtual machine products, such as those from
|
|
||||||
[Parallels][2] and [VMware][3], and the process should be similar.
|
|
||||||
|
|
||||||
If you're comfortable doing so, you may also customize the steps below as you
|
|
||||||
wish, or install Ubuntu Linux natively rather than in a VM.
|
|
||||||
|
|
||||||
* Download [VirtualBox 4.2.10][4].
|
|
||||||
|
|
||||||
* Download [Ubuntu Server 12.04 LTS][5] (A2SERVER has been tested with the
|
|
||||||
32-bit version only).
|
|
||||||
|
|
||||||
* Start VirtualBox, and go to Preferences.
|
|
||||||
|
|
||||||
* Click Input. Set the host key to right-alt, and uncheck Auto Capture
|
|
||||||
Keyboard.
|
|
||||||
|
|
||||||
* Click OK.
|
|
||||||
|
|
||||||
* Click New to create a new virtual machine.
|
|
||||||
|
|
||||||
* Enter *A2SERVER* as the VM name, and select Linux/Ubuntu as the operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
* Enter 256 MB for memory.
|
|
||||||
|
|
||||||
* Under Virtual Hard Disk, leave the defaults (Start-up Disk, and Create new
|
|
||||||
hard disk).
|
|
||||||
|
|
||||||
* Choose VMDK for hard disk file type.
|
|
||||||
|
|
||||||
* Leave the virtual disk file as Dynamically allocated.
|
|
||||||
|
|
||||||
* Leave the virtual disk file location as A2SERVER, and set the disk size to
|
|
||||||
32 GB.
|
|
||||||
|
|
||||||
* Click Create, and then again in the next window.
|
|
||||||
|
|
||||||
* Click Settings.
|
|
||||||
|
|
||||||
* Click Storage. Click on \"Empty\" under \"IDE Controller\".
|
|
||||||
|
|
||||||
* Click on the small CD icon on the far right of the window, select \"Choose a
|
|
||||||
virtual CD/DVD disk file...\", and choose the Ubuntu Server file you
|
|
||||||
downloaded.
|
|
||||||
|
|
||||||
* Click Network.
|
|
||||||
|
|
||||||
* Change \"Attached To:\" to \"Bridged Adapter\".
|
|
||||||
|
|
||||||
* Change \"Name:\" to a **wired** network interface on your computer. If you
|
|
||||||
don't have one, use a USB-to-Ethernet adapter. (A2SERVER won't work over
|
|
||||||
Wi-Fi when running in a VM.)
|
|
||||||
|
|
||||||
* Optional but recommended: Under Advanced, change the MAC Address to
|
|
||||||
080003F2FF59.
|
|
||||||
|
|
||||||
* Click OK.
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://www.virtualbox.org/
|
|
||||||
[2]: http://www.parallels.com/
|
|
||||||
[3]: http://www.vmware.com/
|
|
||||||
[4]: https://www.virtualbox.org/wiki/Downloads/
|
|
||||||
[5]: http://www.ubuntu.com/download/server/
|
|
@@ -1,68 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
So you got a [Raspberry Pi][1]. Congratulations!
|
|
||||||
Are you ready to turn it into a file server for your Apple II? Here's how.
|
|
||||||
|
|
||||||
<!--
|
|
||||||
*Important: As of 11-Aug-14, A2SERVER 1.2.0 is now compatible with the latest
|
|
||||||
version of Raspbian (NOOBS 1.3.9/2014-Jun-20), and the Raspberry Pi Model B+.
|
|
||||||
Type `a2server-setup` to update. If you are already running A2SERVER, and it
|
|
||||||
stopped working after a Raspbian update, see the
|
|
||||||
[recovery page](a2server_recovery.md).*
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Starting fresh:
|
|
||||||
|
|
||||||
If you haven't already started working with a Raspberry Pi, then [download
|
|
||||||
Raspple II][2], a distribution of the Raspbian operating system which includes
|
|
||||||
A2SERVER, [A2CLOUD][3], and David Schmenk's [Apple II Pi][4].
|
|
||||||
|
|
||||||
Expand the RasppleII.zip file, and copy all of its files to a 4 GB or larger
|
|
||||||
SD card. Then put the SD card in your Pi, and attach power. The operating
|
|
||||||
system will automatically install, which will take about 20 minutes.
|
|
||||||
|
|
||||||
When it's done, your Pi will reboot into Raspbian. If you don't have a
|
|
||||||
screen attached, you'll know when it's done when the ACT/OK lamp on the
|
|
||||||
Raspberry Pi board stops flickering.
|
|
||||||
|
|
||||||
(If you are starting over with the same SD card, or want to ensure the card is
|
|
||||||
formatted correctly, you can use the official [SD Formatter][5] utility --
|
|
||||||
carefully! -- before copying the files.)
|
|
||||||
|
|
||||||
If you wish to log in (you don't need to to use A2SERVER), the username is
|
|
||||||
"pi" and password "apple2". (If you do not have a screen and keyboard
|
|
||||||
attached to your Raspberry Pi, read about [logging into a Raspberry Pi from
|
|
||||||
another computer](a2server_raspberrypi_login.md), including an Apple II.) If
|
|
||||||
you wish to change any configuration options, type `raspi-config`.
|
|
||||||
|
|
||||||
For next steps, check out the links on the [A2SERVER home page](index.md).
|
|
||||||
|
|
||||||
|
|
||||||
### Already using a Raspberry Pi?
|
|
||||||
|
|
||||||
If you're already using Raspbian, you can install A2SERVER by typing at a
|
|
||||||
Linux prompt:
|
|
||||||
|
|
||||||
~~~ bash
|
|
||||||
wget appleii.ivanx.com/a2server/setup; source setup
|
|
||||||
~~~
|
|
||||||
|
|
||||||
The process is straightforward -- just respond to the prompts.
|
|
||||||
|
|
||||||
For next steps, check out the links on the [A2SERVER home page](index.md).
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
(If you wish, you can read detailed technical information about the [AppleTalk
|
|
||||||
networking support on the Raspberry Pi](a2server_raspberrypi_kernel.md) that
|
|
||||||
A2SERVER installs.)
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://www.raspberrypi.org
|
|
||||||
[2]: http://appleii.ivanx.com/rasppleii/
|
|
||||||
[3]: http://appleii.ivanx.com/a2cloud
|
|
||||||
[4]: http://schmenk.is-a-geek.com/wordpress
|
|
||||||
[5]: https://www.sdcard.org/downloads/formatter_4/
|
|
@@ -1,56 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
You need to access the Raspberry Pi's command prompt in order set up A2SERVER
|
|
||||||
for network boot, and [do other stuff](a2server_commands.md).
|
|
||||||
|
|
||||||
The default username is "pi" and default password is "apple2". If you
|
|
||||||
don't have a screen and keyboard attached, you can:
|
|
||||||
|
|
||||||
|
|
||||||
### Log in via SSH from another computer
|
|
||||||
|
|
||||||
On a Mac, open Terminal (in the Utilities folder of the Applications folder),
|
|
||||||
and type `ssh pi@raspberrypi.local` to connect. If you have Windows, you can
|
|
||||||
install [Bonjour Print Services][1], and then use [PuTTY][2] to connect to the
|
|
||||||
address "raspberrypi.local".
|
|
||||||
|
|
||||||
If that doesn't work, or you don't want to install Bonjour Print Services
|
|
||||||
for Windows, you will need to find your Pi's IP address and use that instead.
|
|
||||||
If you have a Mac, you can use [Pi Finder][3] to help with this; if you have
|
|
||||||
Windows, you can use [Advanced IP Scanner][4]. Once logged in, you can type
|
|
||||||
`showmac` to see your Pi's MAC (Ethernet) address, and you can use this to
|
|
||||||
reserve an IP address in your router so the Pi gets the same IP address every
|
|
||||||
time.
|
|
||||||
|
|
||||||
|
|
||||||
### Log in from an Apple II
|
|
||||||
|
|
||||||
There are a few different options for logging in from an Apple II. They are:
|
|
||||||
|
|
||||||
* Apple II serial: With the appropriate cables, you can use a terminal
|
|
||||||
communications program such as [ProTERM][5], [Spectrum][6], or Z-Link
|
|
||||||
to log into and control your Raspberry Pi. All this is set up
|
|
||||||
automatically with [A2CLOUD][7], so head over there to read about how
|
|
||||||
to install it and find out what cables you need to get.
|
|
||||||
|
|
||||||
|
|
||||||
* Apple II Ethernet: If you have an [Uthernet Card][8] in an Apple IIgs, you
|
|
||||||
can log into your Raspberry Pi with [Spectrum][6] using VT100 emulation
|
|
||||||
(once logged in, type `TERM=vt100`). To make this work you will need to
|
|
||||||
first log into your Pi by one of the above methods, and type `sudo apt-get
|
|
||||||
-y install telnetd` (you may not wish to do this if your Pi is on a network
|
|
||||||
with any untrusted users, as Telnet is unencrypted). Also, note your Pi's
|
|
||||||
IP address (you can type `showip` once logged in) so you can provide it to
|
|
||||||
Spectrum Internet Suite; you might want to put a DHCP reservation into your
|
|
||||||
router (type `showmac` to get your Pi's MAC address) so you don't have to
|
|
||||||
figure it out again.
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://support.apple.com/kb/dl999
|
|
||||||
[2]: http://www.chiark.greenend.org.uk/~sgtatham/putty/
|
|
||||||
[3]: http://ivanx.com/raspberrypi/files/PiFinder.zip
|
|
||||||
[4]: http://www.advanced-ip-scanner.com
|
|
||||||
[5]: http://lostclassics.apple2.info/downloads/?dl_cat=11
|
|
||||||
[6]: http://www.wannop.info/speccie/Site/Speccies_Home_Pages.html
|
|
||||||
[7]: http://appleii.ivanx.com/a2cloud/
|
|
||||||
[8]: http://a2retrosystems.com
|
|
@@ -1,109 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
If you had A2SERVER running, and you typed either `apt-get update` or
|
|
||||||
`rpi-update`, you may have received Linux kernel version 3.12 through 3.15.
|
|
||||||
These, unfortunately, include a defective AppleTalk kernel module which will
|
|
||||||
kernel panic (crash) your system on startup when A2SERVER tries to activate
|
|
||||||
AppleTalk networking.
|
|
||||||
|
|
||||||
If you have a screen or console cable attached, you will see some debugging
|
|
||||||
information that concludes with "Kernel panic." If you don't have a screen
|
|
||||||
attached, there will be no visible signs other than that you simply can't
|
|
||||||
connect from another computer on your network.
|
|
||||||
|
|
||||||
To prevent this from happening, type `a2server-setup` *before* updating the
|
|
||||||
software on your computer. If it's too late, and you need to recover from
|
|
||||||
this situation, you could [start over][1]. Or, if you want to keep your
|
|
||||||
current installation, you have a few options, depending on your setup:
|
|
||||||
|
|
||||||
|
|
||||||
### A2SERVER virtual machine, or on other non-Raspberry Pi Linux computer
|
|
||||||
|
|
||||||
* Start up the virtual or real machine.
|
|
||||||
|
|
||||||
* On the GRUB startup screen, choose the Recovery kernel.
|
|
||||||
|
|
||||||
* At the Linux prompt, type `a2server-setup`
|
|
||||||
|
|
||||||
|
|
||||||
### A2SERVER on Raspberry Pi with screen/keyboard/mouse attached
|
|
||||||
|
|
||||||
* Press the shift key rapidly and repeatedly while your Pi starts up. If you
|
|
||||||
have an HDMI monitor, you can stop when you see the installer screen. If you
|
|
||||||
have a composite monitor, stop after about a minute, and then press 3 (PAL,
|
|
||||||
e.g. Europe) or 4 (NTSC, e.g. North America and Japan), and you should see
|
|
||||||
the installer screen.
|
|
||||||
|
|
||||||
* Press E for Edit, then click the *cmdline.txt* tab.
|
|
||||||
|
|
||||||
* At the end of the line, append `single` (preceded by a space).
|
|
||||||
|
|
||||||
* Press OK to save, then ESC to reboot.
|
|
||||||
|
|
||||||
* Log in with username "pi" and password "apple2".
|
|
||||||
|
|
||||||
* At the Linux prompt, type `a2server-setup`
|
|
||||||
|
|
||||||
|
|
||||||
### A2SERVER on Raspberry Pi without screen/keyboard mouse, and a Mac
|
|
||||||
|
|
||||||
* Remove the SD card from your Pi and insert it in your Mac.
|
|
||||||
|
|
||||||
* Look for a volume named BOOT to appear.
|
|
||||||
|
|
||||||
* Within it, open *cmdline.txt* in a text editor (the default is TextEdit).
|
|
||||||
|
|
||||||
* At the end of the line, append `single` (preceded by a space), then save it.
|
|
||||||
|
|
||||||
* Eject the SD card and put it back in your Pi, then start up your Pi.
|
|
||||||
|
|
||||||
* [Log in to your Pi](a2server_raspberrypi_login.md) and type `a2server-setup`
|
|
||||||
|
|
||||||
|
|
||||||
### A2SERVER on Raspberry Pi without screen/keyboard mouse, and a Linux computer
|
|
||||||
|
|
||||||
* Remove the SD card from your Pi.
|
|
||||||
|
|
||||||
* On your Linux computer, type:
|
|
||||||
|
|
||||||
~~~ bash
|
|
||||||
wget ivanx.com/a2server/fix; source fix
|
|
||||||
~~~
|
|
||||||
|
|
||||||
* Follow the on-screen instructions.
|
|
||||||
|
|
||||||
* If after using the fix tool, you still can't connect from your Apple II,
|
|
||||||
[log in to your Pi][2], and type `a2server-setup`
|
|
||||||
|
|
||||||
* (Alternative approach: Follow the Mac method above, though the volume may
|
|
||||||
not appear as BOOT.)
|
|
||||||
|
|
||||||
|
|
||||||
### A2SERVER on Raspberry Pi without screen/keyboard/mouse, and a Windows computer
|
|
||||||
|
|
||||||
* Remove the SD card from your Pi.
|
|
||||||
|
|
||||||
* Install the [A2SERVER virtual machine](a2server_virtualbox.md) on your
|
|
||||||
Windows computer.
|
|
||||||
|
|
||||||
* Start the virtual machine, and log in with user name "user1" and
|
|
||||||
password "apple2".
|
|
||||||
|
|
||||||
* In the virtual machine window, type:
|
|
||||||
|
|
||||||
~~~ bash
|
|
||||||
wget ivanx.com/a2server/fix;source fix
|
|
||||||
~~~
|
|
||||||
|
|
||||||
* Follow the on-screen instructions.
|
|
||||||
|
|
||||||
* Type `system-shutdown` in the virtual machine window.
|
|
||||||
|
|
||||||
* Quit VirtualBox.
|
|
||||||
|
|
||||||
* If after using the fix tool, you still can't connect from your Apple
|
|
||||||
II, [Log in to your Pi](a2server_raspberrypi_login.md) and type
|
|
||||||
`a2server-setup`
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://ivanx.com/a2server/
|
|
@@ -1,123 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
When you type A2SERVER-setup, a series of scripts are downloaded from
|
|
||||||
appleii.ivanx.com and executed, some with root privileges. They are run from
|
|
||||||
the /tmp folder, and deleted upon completion.
|
|
||||||
|
|
||||||
Here is what they do, in the order shown (click the links to view the scripts
|
|
||||||
themselves):
|
|
||||||
|
|
||||||
[Master setup script](setup/index.txt)
|
|
||||||
|
|
||||||
* checks for supported OS and warns if it isn't
|
|
||||||
|
|
||||||
* offers to change user password (Raspberry Pi only)
|
|
||||||
|
|
||||||
* runs all of the scripts below
|
|
||||||
|
|
||||||
* offers to download a replacement kernel with AppleTalk support (Raspberry Pi
|
|
||||||
only)
|
|
||||||
|
|
||||||
|
|
||||||
[Storage setup](scripts/a2server-1-storage.txt) (runs during initial setup, skipped on subsequent runs)
|
|
||||||
|
|
||||||
* Make the /srv/A2SERVER directory
|
|
||||||
|
|
||||||
|
|
||||||
[A2SERVER tools install](scripts/a2server-2-tools.txt) (always runs)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
* update package list and upgrade packages (apt-get update/upgrade)
|
|
||||||
-->
|
|
||||||
|
|
||||||
* download, compile, and install nulib2 (ShrinkIt archive utility), into
|
|
||||||
/usr/local/bin
|
|
||||||
|
|
||||||
* install libraries required for compiling [The Unarchiver][1]
|
|
||||||
|
|
||||||
* download, compile, and install unar/lsar (The Unarchiver), into
|
|
||||||
/usr/local/bin
|
|
||||||
|
|
||||||
* install A2SERVER tools into /usr/local/bin and /usr/local/etc:
|
|
||||||
[afpsync](scripts/tools/afpsync.txt),
|
|
||||||
[afptype](scripts/tools/afptype.txt),
|
|
||||||
[cppo](scripts/tools/cppo.txt),
|
|
||||||
[mkatinit](scripts/tools/mkatinit.txt),
|
|
||||||
[volnifo](scripts/tools/mkvolinfo.txt),
|
|
||||||
[aliases](scripts/tools/a2server-aliases.txt) (described at the bottom of
|
|
||||||
[this page](a2server_commands.html))
|
|
||||||
|
|
||||||
* set up aliases file to be read at each login (/etc/profile)
|
|
||||||
|
|
||||||
* customize pre-login message on Ubuntu (/etc/issue), or post-login message on
|
|
||||||
non-Ubuntu (/etc/motd)
|
|
||||||
|
|
||||||
|
|
||||||
[Netatalk install and configure](scripts/a2server-3-sharing.txt) (runs during
|
|
||||||
initial setup and if upgrade to Netatalk is required; otherwise skipped)
|
|
||||||
|
|
||||||
* stop Netatalk service if it is running
|
|
||||||
|
|
||||||
* update package list and upgrade packages
|
|
||||||
|
|
||||||
* download and install libraries required for compiling Netatalk
|
|
||||||
|
|
||||||
* download Netatalk source code
|
|
||||||
|
|
||||||
* modify source code to make dates work correctly
|
|
||||||
|
|
||||||
* compile and install Netatalk
|
|
||||||
|
|
||||||
* set up Netatalk configuration files for Apple II use
|
|
||||||
|
|
||||||
* start Netatalk service
|
|
||||||
|
|
||||||
|
|
||||||
[Network boot setup](scripts/a2server-5-netboot.txt) (always runs)
|
|
||||||
|
|
||||||
* ask whether user wants network boot (skips to the last step in this section
|
|
||||||
if not)
|
|
||||||
|
|
||||||
* download boot blocks disk from Apple and convert it to raw block dump file
|
|
||||||
|
|
||||||
* copy boot blocks files and BASIC.SYSTEM
|
|
||||||
|
|
||||||
* use mkatinit to enable Apple II network boot
|
|
||||||
|
|
||||||
* patch boot block files to support cleartext passwords, and typing "8"
|
|
||||||
during IIGS network startup to force ProDOS 8 boot
|
|
||||||
|
|
||||||
* ask user whether to download and install GS/OS
|
|
||||||
|
|
||||||
* ask whether user wants to download disk image and file utilities
|
|
||||||
|
|
||||||
* ask whether user wants to install Farallon bridge patch
|
|
||||||
|
|
||||||
|
|
||||||
[Windows file sharing](scripts/a2server-6-samba.txt) (always runs)
|
|
||||||
|
|
||||||
* ask whether user wants Windows file sharing, and if so:
|
|
||||||
|
|
||||||
* download and install samba, and start the service
|
|
||||||
|
|
||||||
* set up samba configuration files
|
|
||||||
|
|
||||||
* if user doesn't want Windows file sharing, stop the samba service
|
|
||||||
|
|
||||||
|
|
||||||
[Console optimizing](scripts/a2server-7-console.txt) (runs during initial
|
|
||||||
setup, skipped on subsequent runs)
|
|
||||||
|
|
||||||
* disable default Ubuntu Server login message
|
|
||||||
|
|
||||||
* make console clear boot messages before initial login prompt
|
|
||||||
|
|
||||||
* eliminate piix4\_smbus error message before initial login prompt
|
|
||||||
|
|
||||||
* prevent console from going blank after ten minutes of inactivity (after
|
|
||||||
login)
|
|
||||||
|
|
||||||
* resolve a slow-scrolling problem in Ubuntu Server 10.04 (only)
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://wakaba.c3.cx/s/apps/unarchiver.html
|
|
@@ -1,234 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
|
|
||||||
The A2SERVER Odyssey
|
|
||||||
|
|
||||||
A2SERVER has been a multi-year labor of love.
|
|
||||||
|
|
||||||
Way back in 2010, my primary Apple II was a Mac Color Classic with an Apple
|
|
||||||
IIe compatibility card.
|
|
||||||
|
|
||||||
One of the things this card could do was emulate something called a
|
|
||||||
Workstation Card, which appeared to let Apple II computers access files on a
|
|
||||||
Mac file server. This was intriguing; I hadn't imagined it was possible.
|
|
||||||
|
|
||||||
And it was also potentially valuable as a way of providing mass storage for an
|
|
||||||
Apple II, with the bonus that other computers could easily access it as a
|
|
||||||
means of getting stuff to and from an otherwise isolated machine.
|
|
||||||
|
|
||||||
After some experimenting, I discovered that was exactly what it did, and I
|
|
||||||
bought an actual Workstation Card for my IIe, because that would be much, much
|
|
||||||
cooler. And it appeared that you could even *boot* the Apple II into ProDOS
|
|
||||||
from the network, which blew my mind. Using AppleShare 3.0 on another Mac as a
|
|
||||||
host, I made this happen, and there was much rejoicing.
|
|
||||||
|
|
||||||
Then, I got an idea into my head: this is great and everything, but you still
|
|
||||||
need an old Mac around. How great would it be if you could just have an
|
|
||||||
always-on network drive for an Apple II, with all the storage you might ever
|
|
||||||
need, and accessible from other computers on the LAN?
|
|
||||||
|
|
||||||
(It's true that there were Compact Flash storage cards at the time, and I
|
|
||||||
actually bought CFFA #16, but these didn't appeal to me quite as much because
|
|
||||||
of their relative lack of accessibility on other platforms. I'd need some
|
|
||||||
sort of CF extender to get the card outside the machine, then run CiderPress
|
|
||||||
in a Windows emulator...)
|
|
||||||
|
|
||||||
It so happens that I had purchased a Western Digital My Book World Edition,
|
|
||||||
which was one of the first popular NAS products available. It was basically a
|
|
||||||
small Linux computer in a drive enclosure, and it was widely hacked to make it
|
|
||||||
do all kinds of tricks, one of which was providing native file sharing for
|
|
||||||
Macs.
|
|
||||||
|
|
||||||
This was possible by installing Netatalk, an open-source implentation of AFP
|
|
||||||
(AppleShare). I immediately wondered if it would be possible to somehow get my
|
|
||||||
IIe to talk to it. So I looked into it, and it appeared that Netatalk running
|
|
||||||
on Linux still supported the older AppleTalk networking protocol required by
|
|
||||||
an Apple II, and it even supported network boot into ProDOS.
|
|
||||||
|
|
||||||
There was the issue of how to actually interface my Apple II to the network;
|
|
||||||
this turned out to be relatively easy, by using an Apple-provide control panel
|
|
||||||
for classic Macs called LocalTalk Bridge, which indeed bridged AppleTalk from
|
|
||||||
its LocalTalk port (connected to an Apple II) to its Ethernet port (connected
|
|
||||||
to my network, which was connected to the NAS). But this was clumsy, so I
|
|
||||||
invested in an AsanteTalk, which is a dedicated (if finicky)
|
|
||||||
LocalTalk-to-Ethernet bridge.
|
|
||||||
|
|
||||||
What I discovered, after some time, was that a) the version of Linux that
|
|
||||||
shipped on that NAS did not include support for AppleTalk networking, and b)
|
|
||||||
the easily-installed Netatalk package didn't include the components required
|
|
||||||
for network boot, which I absolutely wanted.
|
|
||||||
|
|
||||||
I wasn't terribly Linux-savvy at the time, but I eventually figured out that
|
|
||||||
to get network boot support, I would need to download Netatalk and compile it
|
|
||||||
myself, from source. Ok. But once I learned that adding AppleTalk support
|
|
||||||
overall would require recompiling a kernel for the drive, I kind of put the
|
|
||||||
idea aside, figuring I'd bring it to KFest and hack on it with someone there
|
|
||||||
who knows what they're doing.
|
|
||||||
|
|
||||||
In the meantime, I decided to see if I could make things work exactly as I
|
|
||||||
wanted with a "proper" Linux installation. Ubuntu Linux was well-known for
|
|
||||||
its relative ease of use, so I installed that into VMWare Fusion running on my
|
|
||||||
(modern) Mac. I installed the Netatalk package, and that worked -- though it
|
|
||||||
was still missing the network boot component, and there were other issues like
|
|
||||||
password login not working correctly.
|
|
||||||
|
|
||||||
So I had to figure out how to recompile Netatalk to make it do what I needed.
|
|
||||||
I managed to figure this out after much effort and studying of posts and
|
|
||||||
contributions to comp.sys.apple2, but wasn't able to get it to actually
|
|
||||||
netboot to ProDOS.
|
|
||||||
|
|
||||||
So this led me to comp.sys.apple2, and there met two people who turned out to
|
|
||||||
be two enormous contributors to A2SERVER: Steven Hirsch, who wrote much of the
|
|
||||||
actual network boot support in Netatalk, and Geoff Body, who knows everything
|
|
||||||
about the "boot blocks" that get transferred to the Apple IIe or IIgs during
|
|
||||||
network startup. Both Steven and Geoff have also helped figure out and work
|
|
||||||
around the idiosyncracies of many of the dedicated LocalTalk-to-Ethernet
|
|
||||||
bridges, and have been essential contributors to the execution of A2SERVER.
|
|
||||||
|
|
||||||
The initial conversation is chronicled in perpetuity here:
|
|
||||||
https://groups.google.com/forum/#!topic/comp.sys.apple2/b\_TzESci6Kg
|
|
||||||
|
|
||||||
With their help, I finally succeeded in network booting my Apple IIe from my
|
|
||||||
Linux virtual machine. The first proto-version of A2SERVER was a step-by-step
|
|
||||||
guide to manually set it up, as posted here:
|
|
||||||
https://groups.google.com/forum/#!topic/comp.sys.apple2/lkh4hXqmJbE
|
|
||||||
|
|
||||||
I could have left it at that, but I didn't like it. It wasn't all THAT easy
|
|
||||||
for a non-Linux person, network boot relied on Apple software from a "secret
|
|
||||||
archive" and hand-hacked binary code from within the guide itself, and the
|
|
||||||
final setup was hard-coded to a specific user name. I wanted a version that
|
|
||||||
was general-purpose, easy for anyone to install, and which obtained any
|
|
||||||
copyrighted software from 100% public, authorized sources.
|
|
||||||
|
|
||||||
And which, in a perfect world, could be configured to netboot from "bare
|
|
||||||
metal" -- that is, a bare computer with nothing but Linux would be able to
|
|
||||||
boot an Apple IIe or IIgs with no operating system, software, or even any
|
|
||||||
drives at all.
|
|
||||||
|
|
||||||
I hadn't forgotten about wanting it to run on a NAS, either, but I figured
|
|
||||||
I'd circle back to that, since it was so much easier working in a VM. For the
|
|
||||||
time being, what I'd ship would be both a premade VM, and a complete
|
|
||||||
installer script for actual Linux installations. And that would be A2SERVER.
|
|
||||||
|
|
||||||
Then it was a matter of locating what I could, from anyone I could, to make it
|
|
||||||
work. I discovered that the boot blocks and BASIC.SYSTEM -- the essential
|
|
||||||
pieces for netbooting ProDOS 8 -- were ensconced with the GSOS "Disk 7"
|
|
||||||
image available from Apple's Older Software downloads page. But that disk
|
|
||||||
image was a DiskDoubler self-extracting archive. Fortunately, The Unarchiver
|
|
||||||
could uncompress it, and is open-source, and builds on Linux. The disk image
|
|
||||||
was actually an HFS disk, which Linux has support for, so I was able to mount
|
|
||||||
it and copy the files out.
|
|
||||||
|
|
||||||
Steven contributed a huge fix to the Netatalk source code so ProDOS dates get
|
|
||||||
handled correctly. Geoff gave me patches to the Boot Blocks to fix a cleartext
|
|
||||||
login bug and allow an on-demand startup option to boot into ProDOS 8 on a
|
|
||||||
IIgs.
|
|
||||||
|
|
||||||
Then I had to hack a bunch of stuff together. I wrote mkatinit to create the
|
|
||||||
very specific user login files required for netboot; afpsync to simplify
|
|
||||||
Netatalk's handling of new shared files introduced from Linux; afptype to
|
|
||||||
allow setting the ProDOS (or classic Mac) file type of a file shared by
|
|
||||||
Netatalk.
|
|
||||||
|
|
||||||
These tools, plus a properly-compiled-and-configured Netatalk, made it
|
|
||||||
possible for a Linux server to entirely download ProDOS 8 and set it up for
|
|
||||||
network boot by an Apple II. Nothing had to be done on the Apple II side. Bare
|
|
||||||
metal!
|
|
||||||
|
|
||||||
I then shaped my guide into an actual executable script which could be
|
|
||||||
downloaded from my web site and executed on any Ubuntu installation. I
|
|
||||||
expanded the script to download and install the necessary tools, apply the
|
|
||||||
necessary patches, and everything else I felt was needed for click-and-go
|
|
||||||
server Apple II server setup, such as optional Windows file sharing (since one
|
|
||||||
of the goals was easy file interchange with modern computers).
|
|
||||||
|
|
||||||
And that was kinda that -- almost. I'd conquered the IIe, but the real Mt.
|
|
||||||
Everest was bare metal GS/OS netboot. This was much more challenging: it meant
|
|
||||||
I'd have to get the files out of the ProDOS-formatted GSOS installer disk
|
|
||||||
images, with resource forks intact and made usable by Netatalk. This is what I
|
|
||||||
wanted to show off when I introduced A2SERVER at KansasFest 2011.
|
|
||||||
|
|
||||||
There was no off-the-shelf solution for this, so I spent pretty much every
|
|
||||||
waking hour in Kansas City furiously creating cppo, which would copy files out
|
|
||||||
of a ProDOS disk image. And...I failed. I just ran out of time before my
|
|
||||||
presentation.
|
|
||||||
|
|
||||||
So I installed a Network Startup instalation of GS/OS the conventional way --
|
|
||||||
using the IIgs installer disks running on a IIgs, with the Netatalk shared
|
|
||||||
volume as the target. (The CFFA3000, which was also introduced that same
|
|
||||||
KansasFest, was absolutely invaluable for this.)
|
|
||||||
|
|
||||||
And it worked. In my presentation, I was able to network boot Peter
|
|
||||||
Neubauer's Apple IIe with nothing but the Workstation Card; and my IIgs with
|
|
||||||
nothing but a RAM card.
|
|
||||||
|
|
||||||
Then I came back home. I completed cppo, and it worked, mostly; with that
|
|
||||||
done, I then set about writing something to interpret the GS/OS installer
|
|
||||||
scripts and cppo the right pieces to the right places. And...it worked too.
|
|
||||||
Except that it didn't. It all started up, but the Finder had random
|
|
||||||
filenames, the Trash was full when there was nothing in it. It was corrupt.
|
|
||||||
Who knows why. I gave up.
|
|
||||||
|
|
||||||
I wasn't satisfied with not being able to start up a IIgs at all if you
|
|
||||||
didn't have the installer disks; so I made it netboot into ProDOS 8, from
|
|
||||||
where you could use DSK2FILE (which the A2SERVER installer script offers to
|
|
||||||
download) to convert the disk images to actual disks, which you could then use
|
|
||||||
to make an AppleShare startup floppy, which you could THEN use to mount the
|
|
||||||
shared volume and use it as a target for a full Network Startup install. Icky,
|
|
||||||
and of possible benefit to no one (really, who doesn't have GS/OS install
|
|
||||||
disks and a drive?), but it was some kind of solution. I packaged up the VM,
|
|
||||||
put up these web pages, and decided it was Done.
|
|
||||||
|
|
||||||
But the NAS thing itched at me. I wanted to be able to suggest an easily
|
|
||||||
obtained product. By now, WD had replaced my NAS with the My Book Live, which
|
|
||||||
featured a much faster processor, and was based on Debian Linux, which is what
|
|
||||||
Ubuntu is derived from. This was a promising starting point. I figured out how
|
|
||||||
to compile an AppleTalk kernel module for it. And then I already had these
|
|
||||||
turnkey scripts ready to go, so I hacked, and hacked, and...I couldn't get it
|
|
||||||
to work. I'd sometimes get gibberish for volume names, and network boot would
|
|
||||||
load the boot blocks, and then never stop loading, filling the Apple II's
|
|
||||||
memory with zeroes until it crashed. (My suspicion is that the big-endianness
|
|
||||||
of the PowerPC CPU in the newer NAS may have been a factor.) Fixing that would
|
|
||||||
have taken me deep into the packetized heart of Netatalk, which is beyond my
|
|
||||||
pay grade. I gave up, and decided A2SERVER was Done. Again.
|
|
||||||
|
|
||||||
Until I went to KansasFest 2012, and Eric Rucker showed me something I had
|
|
||||||
never heard of: a Raspberry Pi. Somewhere, the gears started turning, and
|
|
||||||
months later I checked it out, and saw that its primary operating system
|
|
||||||
was...a Debian derivative. Could this be my long-sought-after NAS?
|
|
||||||
|
|
||||||
It was. The install scripts ran with only a little tweaking. I did have to
|
|
||||||
compile AppleTalk in the kernel, but eventually I had what I wanted. And it
|
|
||||||
was only $35!
|
|
||||||
|
|
||||||
I revisited the corrupted GS/OS installation. I couldn't put my finger on
|
|
||||||
what was wrong. But I noticed that the Finder showed a different length on its
|
|
||||||
source disk and after copying. So I followed its index blocks, and discovered
|
|
||||||
that contained in those were 0000's. ProDOS knew to fill blocks with zeros,
|
|
||||||
but cppo was dutifully copying Block 0, the ProDOS boot block, thereby
|
|
||||||
corrupting the Finder. I fixed this, and then I HAD IT: Bare metal install
|
|
||||||
GS/OS from Linux. Yeah, man.
|
|
||||||
|
|
||||||
And, so, then it was just tweaking and refining and tweaking and refining. The
|
|
||||||
big bummer as far as general use goes was that all the common
|
|
||||||
LocalTalk-to-Ethernet bridges (Dayna, AsanteTalk, and Farallon) were partially
|
|
||||||
or completely inoperable with a IIgs, and the Workstation Card required for a
|
|
||||||
IIe is hardly in great abundance. But Geoff Body came up with a fix for the
|
|
||||||
Farallon, I came up with a workaround for the AsanteTalk, and Steven Hirsch
|
|
||||||
came up with an actual fix for both the AsanteTalk and the Dayna, meaning
|
|
||||||
*all* of those bridges are now options for a IIgs owner!
|
|
||||||
|
|
||||||
So this was it: bare IIgs (even without memory card, if you're OK with ProDOS
|
|
||||||
8) + Raspberry Pi + readily available bridge = Apple II file server. Yeah!
|
|
||||||
|
|
||||||
And I discovered that with a USB cable or RPi console cable, you could
|
|
||||||
actually log in and control it with ProTERM. With Hugh Hood's clever ProTERM
|
|
||||||
patch for 115,200 bps on a IIgs, I could actually see my Raspberry Pi start
|
|
||||||
up...on my Apple II. I can't explain how joyous this made me.
|
|
||||||
|
|
||||||
And, I wrote ProDOS 8 utilities to switch the IIgs boot mode, which is
|
|
||||||
normally only possible under GS/OS.
|
|
||||||
|
|
||||||
I could go on and on, but basically the ideas kept coming, and I think I was
|
|
||||||
able I was able to polish most of A2SERVER's rough edges so that it could be
|
|
||||||
fun and/or useful for a few people. I hope you enjoy it!
|
|
@@ -1,44 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
|
|
||||||
To set up A2SERVER, follow these steps:
|
|
||||||
|
|
||||||
* Download and install [VirtualBox][1]. It's free. (If you prefer different
|
|
||||||
virtual machine software, [you can instead use the A2SERVER installer
|
|
||||||
script](a2server_installer.md).)
|
|
||||||
|
|
||||||
* Download the [A2SERVER virtual machine](files/A2SERVER.ova) (~750 MB), or
|
|
||||||
the [A2SERVER+A2CLOUD virtual machine](files/A2SERVER_A2CLOUD.ova) (~1.7
|
|
||||||
GB).
|
|
||||||
|
|
||||||
* Open VirtualBox, and choose "Import Appliance..." from the File menu.
|
|
||||||
Select the file you downloaded (A2SERVER.ova).
|
|
||||||
|
|
||||||
* Leave the "Reinitialize the MAC address of all network cards" box
|
|
||||||
unchecked. Click Import.
|
|
||||||
|
|
||||||
* When it's done importing, click A2SERVER, then click Settings, then click
|
|
||||||
Network.
|
|
||||||
|
|
||||||
* Ensure that "Attached To:" is set to "Bridged Adapter".
|
|
||||||
|
|
||||||
* Set "Name:" to a _wired_ network interface on your computer. If you don't
|
|
||||||
have one, use a USB-to-Ethernet adapter. (A2SERVER won't work over Wi-Fi in
|
|
||||||
a virtual machine.)
|
|
||||||
|
|
||||||
* Click OK.
|
|
||||||
|
|
||||||
|
|
||||||
You're all set up. For next steps, check out the links on the [A2SERVER home
|
|
||||||
page](index.md).
|
|
||||||
|
|
||||||
|
|
||||||
SHA-1 for A2SERVER VM: d6c60b0ab14f14ddd49b7e5cdac39503db96a903
|
|
||||||
SHA-1 for A2SERVER+A2CLOUD VM: 69df7c28fa21e4e4cc01b106398936f23559a64b
|
|
||||||
<!--
|
|
||||||
v1.1.3: a8927d6fba9dfa9c2015918cdc61122bb2c95ea5
|
|
||||||
v1.1.0: 63eebfcfe9fbbeb17aa4ab3226e849289072d396
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
[1]: https://www.virtualbox.org/wiki/Downloads
|
|
@@ -1,78 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
While wired Ethernet is recommended, it's possible to use A2SERVER with Wi-Fi
|
|
||||||
if you have an Apple AirPort or Time Capsule. (A2SERVER won't work with most
|
|
||||||
non-Apple router and access point models, as they are not designed to handle
|
|
||||||
AppleTalk networking.)
|
|
||||||
|
|
||||||
To connect your Apple II via Wi-Fi, read how to [attach your Apple II to your
|
|
||||||
local network](a2server_lan.md).
|
|
||||||
|
|
||||||
If you want your A2SERVER machine (whether virtual, real, or Raspberry Pi) to
|
|
||||||
connect to your network via Wi-Fi, you first need to configure a Wi-Fi network
|
|
||||||
adapter via the instructions below. Once you've got that up and running, [log
|
|
||||||
in](a2server_commands.md) to A2SERVER and type `netatalk-wifi` to tell
|
|
||||||
A2SERVER to use the Wi-Fi interface (if you get "command not found", type
|
|
||||||
`a2server-setup` to refresh the command list).
|
|
||||||
|
|
||||||
|
|
||||||
Setting up Wi-Fi on your A2SERVER machine:
|
|
||||||
|
|
||||||
### Multiple AirPorts
|
|
||||||
|
|
||||||
As an alternative to using a Wi-Fi network adapter, any of the machine types
|
|
||||||
below can work with Wi-Fi simply by connecting the wired Ethernet interface to
|
|
||||||
another AirPort and setting up an [extended network][1] (if all AirPorts are
|
|
||||||
802.11n models), or a [WDS][2] (if any AirPort is an 802.11g model).
|
|
||||||
|
|
||||||
|
|
||||||
### Raspberry Pi
|
|
||||||
|
|
||||||
[We got a whole page about that.][3]
|
|
||||||
|
|
||||||
|
|
||||||
### Virtual machine
|
|
||||||
|
|
||||||
On a virtual machine, A2SERVER won't work over Wi-Fi with the virtual network
|
|
||||||
interface, but you may, or may not, be able to use a USB Wi-Fi adapter
|
|
||||||
attached your VM's emulated USB port, and then follow the instructions below
|
|
||||||
for a real machine. Some adapters may have issues with specific virtual
|
|
||||||
machine software; for example, Atheros 9K based adapters [do not work with
|
|
||||||
VirtualBox][4] or VMWare Fusion, though they do work with Parallels Desktop;
|
|
||||||
Realtek 81xx based adapters seem to work with VirtualBox (at minimum).
|
|
||||||
|
|
||||||
|
|
||||||
### Real machine (Intel or compatible)
|
|
||||||
|
|
||||||
On a standard computer with a native Linux installation, if you can get a
|
|
||||||
Wi-Fi adapter working, it will probably work with A2SERVER. Instructions will
|
|
||||||
vary by distribution, but should be similar to [the guide for Raspberry
|
|
||||||
Pi][3], with a much wider range of usable adapters.
|
|
||||||
|
|
||||||
If those steps don't work, type `sudo nano /etc/network/interfaces`, and edit
|
|
||||||
the file so it contains a sequence of lines that look like this:
|
|
||||||
`allow-hotplug wlan0 iface wlan0 inet dhcp wpa-ssid MyNetworkName` (substitute
|
|
||||||
your Wi-Fi network name) `wpa-psk abcdefgh` (substitute your WPA password, or
|
|
||||||
its 64-character hex equivalent)
|
|
||||||
|
|
||||||
If you are using WEP encryption instead of WPA, replace the last two lines
|
|
||||||
with:
|
|
||||||
`wireless-essid MyNetworkName` (substitute your Wi-Fi network name)
|
|
||||||
`wireless-key abcde` (substitute your 5 or 13 character, or 10 or 26 hex byte,
|
|
||||||
WEP password)
|
|
||||||
|
|
||||||
Spaces in the Wi-Fi network name or password may not work.
|
|
||||||
|
|
||||||
Remove any other chunks which mention wlan0, and save the file (press
|
|
||||||
control-w). Then type: `sudo ifdown wlan0; sudo ifup wlan0`
|
|
||||||
|
|
||||||
Finally, type `ip addr`. If you see an IP address for wlan0 (next to
|
|
||||||
"inet"), your Wi-Fi adapter is on your network, and you can disconnect your
|
|
||||||
Ethernet or serial cable. (If you don't seem to have internet access, type
|
|
||||||
`sudo shutdown -r now` to restart.)
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://support.apple.com/kb/HT4259
|
|
||||||
[2]: http://support.apple.com/kb/HT4262
|
|
||||||
[3]: http://ivanx.com/raspberrypi/raspberrypi_wifi.html
|
|
||||||
[4]: https://www.virtualbox.org/ticket/9511
|
|
@@ -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 appleii.ivanx.com/a2server/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
|
|
@@ -1,91 +0,0 @@
|
|||||||
## A2SERVER
|
|
||||||
|
|
||||||
A2SERVER lets you use a [Raspberry Pi][1], or almost any other computer, to
|
|
||||||
serve files to Apple IIgs and enhanced IIe computers on your network. You'll
|
|
||||||
also be able to boot into GS/OS or ProDOS 8 directly from tne network (no
|
|
||||||
drives needed). A2SERVER has been designed to be as easy to set up and use as
|
|
||||||
possible, and it's free.
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A2SERVER is available as a Raspberry Pi installer, or a virtual machine which
|
|
||||||
runs on Mac OS X, Windows, Linux, or Solaris computers, or as an easy-to-use
|
|
||||||
installer for Ubuntu or Debian Linux.
|
|
||||||
-->
|
|
||||||
|
|
||||||
A2SERVER is based on open-source software, primarily [Netatalk][2] 2.2.4,
|
|
||||||
with [many utilities and enhancements](a2server_features.md) to make
|
|
||||||
everything as easy as possible. (If you like A2SERVER, you might also want to
|
|
||||||
check out [A2CLOUD][3].)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If you haven't checked out A2SERVER in a while: it now runs on something
|
|
||||||
small, cheap, and silent, and every common LocalTalk-to-Ethernet bridge now
|
|
||||||
works easily with a IIgs (as opposed to none previously). And A2SERVER
|
|
||||||
supports Wi-Fi, and can download and install GS/OS on your network drive for
|
|
||||||
you. Cool stuff!
|
|
||||||
-->
|
|
||||||
|
|
||||||
*Update 19-Mar-15: A2SERVER 1.2.2 is available. It has support for Raspberry
|
|
||||||
Pi 2 Model B and every other Raspberry Pi, and new command line options for
|
|
||||||
the installer script. To update, type `a2server-setup`.*
|
|
||||||
|
|
||||||
Choose how you'd like to use A2SERVER, and you'll be up and running shortly.
|
|
||||||
|
|
||||||
* [Raspberry Pi](a2server_raspberrypi.md)
|
|
||||||
* [Virtual Machine](a2server_virtualbox.md) (for Mac OS X, Windows, Linux,
|
|
||||||
Solaris)
|
|
||||||
* [Installer for Ubuntu or Debian Linux](a2server_installer.md)
|
|
||||||
|
|
||||||
|
|
||||||
Once you've got it set up, here are next steps:
|
|
||||||
|
|
||||||
[Attach your Apple II to your local network](a2server_lan.md)
|
|
||||||
|
|
||||||
[Connect to A2SERVER from your Apple II](a2server_howtouse.md)
|
|
||||||
|
|
||||||
[Boot into ProDOS 8 or GS/OS over the network](a2server_netboot.md)
|
|
||||||
|
|
||||||
[Log into, shut down, and do stuff in the A2SERVER
|
|
||||||
console](a2server_commands.md)
|
|
||||||
|
|
||||||
[Access A2SERVER files from a Mac or Windows computer](a2server_access.md)
|
|
||||||
|
|
||||||
[Use A2SERVER with Wi-Fi](a2server_wifi.md)
|
|
||||||
|
|
||||||
|
|
||||||
And some other stuff that might (or might not) be helpful or interesting:
|
|
||||||
|
|
||||||
[A2SERVER feature list](a2server_features.md)
|
|
||||||
|
|
||||||
[A2SERVER version history](update/versionhistory.txt)
|
|
||||||
|
|
||||||
[Recover from a crashed A2SERVER](a2server_recovery.md)
|
|
||||||
|
|
||||||
[Details of what the "a2server-setup" script
|
|
||||||
does](a2server_scriptdetails.md)
|
|
||||||
|
|
||||||
[See the March 2013 cover of Juiced.GS][4], featuring A2SERVER
|
|
||||||
|
|
||||||
[Watch me introduce A2SERVER at KansasFest 2011][5] (note: this contains some
|
|
||||||
outdated information)
|
|
||||||
|
|
||||||
[The A2SERVER odyssey](a2server_story.md) (warning: long)
|
|
||||||
|
|
||||||
|
|
||||||
Buckets of thanks to Steven Hirsch and Geoff Body, whose invaluable assistance
|
|
||||||
and contributions have made A2SERVER exist, along with Tony Diaz, Antoine
|
|
||||||
Vignau, Peter Wong, Martin Haye, Ken Gagne, Peter Neubauer, Anthony Martino,
|
|
||||||
James Littlejohn, and others at comp.sys.apple2 and KansasFest. (As well as
|
|
||||||
the creators, past and present, of Netatalk and Raspberry Pi.) Apple II
|
|
||||||
Forever!
|
|
||||||
|
|
||||||
Questions? Comments? email [ivan@ivanx.com](mailto:ivan@ivanx.com)
|
|
||||||
|
|
||||||
[Apple II Extravaganza home page](http://appleii.ivanx.com/)
|
|
||||||
|
|
||||||
|
|
||||||
[1]: http://www.raspberrypi.org
|
|
||||||
[2]: http://netatalk.sourceforge.net
|
|
||||||
[3]: http://ivanx.com/a2cloud
|
|
||||||
[4]: http://juiced.gs/2013/03/v18i1-now-shipping/
|
|
||||||
[5]: http://www.youtube.com/watch?v=w88NjWRK7Kk
|
|
@@ -1,19 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# --- Setting up the share volume
|
|
||||||
|
|
||||||
|
|
||||||
# skip if we're already set up
|
|
||||||
if [[ -d /srv/A2SERVER ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Shared disk is already prepared for use."
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
echo "A2SERVER: Preparing the shared files disk..."
|
|
||||||
|
|
||||||
sudo mkdir /srv/A2SERVER
|
|
||||||
|
|
||||||
sudo chown $USER:$USER /srv/A2SERVER
|
|
||||||
|
|
||||||
fi
|
|
@@ -1,126 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# download and install a2server tools:
|
|
||||||
# mkatinit, mkvolinfo, afptype, afpsync, aliases, nulib2
|
|
||||||
|
|
||||||
isRpi=
|
|
||||||
[[ -f /usr/bin/raspi-config ]] && isRpi=1
|
|
||||||
|
|
||||||
isDebian=
|
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "7." ) && ( $(uname -m) == "i686" ) ]] && isDebian=1
|
|
||||||
|
|
||||||
echo "A2SERVER: Installing A2SERVER tools..."
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/nulib2 ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Installing nulib2..."
|
|
||||||
|
|
||||||
cd /tmp
|
|
||||||
if [[ $isRpi ]]; then
|
|
||||||
wget -qO- ivanx.com/a2server/files/nulib2-rpi.tgz | sudo tar Pzx
|
|
||||||
elif [[ $isDebian ]]; then
|
|
||||||
wget -qO- ivanx.com/a2server/files/nulib2-debian7_x86.tgz | sudo tar Pzx
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/nulib2 ]]; then
|
|
||||||
|
|
||||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
|
||||||
# prepare for installing packages
|
|
||||||
sudo apt-get -y update
|
|
||||||
touch /tmp/a2server-packageReposUpdated
|
|
||||||
fi
|
|
||||||
|
|
||||||
sudo apt-get -y install build-essential
|
|
||||||
sudo apt-get -y install zlib1g-dev
|
|
||||||
sudo apt-get -y clean
|
|
||||||
cd /tmp
|
|
||||||
rm -rf /tmp/nulib &> /dev/null
|
|
||||||
mkdir /tmp/nulib
|
|
||||||
cd /tmp/nulib
|
|
||||||
wget -q -O nulib.tgz http://web.archive.org/web/20131031160750/http://www.nulib.com/downloads/nulibdist.tar.gz
|
|
||||||
tar zxf nulib.tgz
|
|
||||||
cd nufxlib*
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
cd ../nulib2*
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
cd
|
|
||||||
rm -rf /tmp/nulib
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "A2SERVER: Nulib2 has already been installed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# download and install The Unarchiver, for expanding Apple disk images
|
|
||||||
# http://wakaba.c3.cx/s/apps/unarchiver.html
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/unar ]]; then
|
|
||||||
|
|
||||||
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 [[ $isRpi || $isDebian ]]; then
|
|
||||||
sudo apt-get -y install libgnustep-base1.22
|
|
||||||
sudo apt-get clean
|
|
||||||
if [[ $isRpi ]]; then
|
|
||||||
wget -qO- ivanx.com/a2server/files/unar-rpi.tgz | sudo tar Pzx
|
|
||||||
elif [[ $isDebian ]]; then
|
|
||||||
wget -qO- ivanx.com/a2server/files/unar-debian7_x86.tgz | sudo tar Pzx
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ ! -f /usr/local/bin/unar ]]; then
|
|
||||||
sudo apt-get -y install build-essential
|
|
||||||
sudo apt-get -y install libgnustep-base-dev libz-dev libbz2-dev
|
|
||||||
sudo apt-get -y install libssl-dev libicu-dev unzip
|
|
||||||
sudo apt-get clean
|
|
||||||
rm -rf /tmp/unar &> /dev/null
|
|
||||||
mkdir /tmp/unar
|
|
||||||
cd /tmp/unar
|
|
||||||
wget -qO unar1.7_src.zip http://theunarchiver.googlecode.com/files/unar1.7_src.zip
|
|
||||||
unzip -o unar1.7_src.zip
|
|
||||||
cd The\ 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
|
|
||||||
else
|
|
||||||
echo "A2SERVER: The Unarchiver has already been installed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
sudo wget -q -O /usr/local/bin/afpsync appleii.ivanx.com/a2server/scripts/tools/afpsync.txt
|
|
||||||
sudo chmod ugo+x /usr/local/bin/afpsync
|
|
||||||
sudo wget -q -O /usr/local/bin/afptype appleii.ivanx.com/a2server/scripts/tools/afptype.txt
|
|
||||||
sudo chmod ugo+x /usr/local/bin/afptype
|
|
||||||
sudo wget -q -O /usr/local/bin/mkatinit appleii.ivanx.com/a2server/scripts/tools/mkatinit.txt
|
|
||||||
sudo chmod ugo+x /usr/local/bin/mkatinit
|
|
||||||
sudo wget -q -O /usr/local/bin/mkvolinfo appleii.ivanx.com/a2server/scripts/tools/mkvolinfo.txt
|
|
||||||
sudo chmod ugo+x /usr/local/bin/mkvolinfo
|
|
||||||
sudo wget -q -O /usr/local/bin/cppo appleii.ivanx.com/a2server/scripts/tools/cppo.txt
|
|
||||||
sudo chmod ugo+x /usr/local/bin/cppo
|
|
||||||
sudo wget -q -O /usr/local/etc/a2server-help.txt appleii.ivanx.com/a2server/scripts/tools/a2server-help.txt
|
|
||||||
sudo wget -q -O /usr/local/etc/a2server-aliases appleii.ivanx.com/a2server/scripts/tools/a2server-aliases.txt
|
|
||||||
|
|
||||||
grep a2server-aliases /etc/bash.bashrc > /dev/null || \
|
|
||||||
echo "source /usr/local/etc/a2server-aliases" | sudo tee -a /etc/bash.bashrc > /dev/null
|
|
||||||
|
|
||||||
[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && motd="/etc/issue" || 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
|
|
||||||
fi
|
|
@@ -1,415 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# A2SERVER -- a virtual machine for sharing files to Apple II clients
|
|
||||||
# by Ivan X, ivan@ivanx.com
|
|
||||||
|
|
||||||
# Installs Netatalk 2.2.4 for debian/raspbian (Wheezy) or Ubuntu (12.04)
|
|
||||||
# last update: 3-Mar-15
|
|
||||||
|
|
||||||
# The lastest version of this document, and the ready-to-use premade
|
|
||||||
# virtual machine, will be at http://appleii.ivanx.com .
|
|
||||||
|
|
||||||
# Please send corrections and comments to ivan@ivanx.com
|
|
||||||
|
|
||||||
# Thanks to Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, and others
|
|
||||||
# at comp.sys.apple2 for the work they've done and insight they've
|
|
||||||
# offered which made it possible to put this together.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --- Installing netatalk
|
|
||||||
|
|
||||||
isRpi=
|
|
||||||
[[ -f /usr/bin/raspi-config ]] && isRpi=1
|
|
||||||
|
|
||||||
isDebian=
|
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "7." ) && ( $(uname -m) == "i686" ) ]] && isDebian=1
|
|
||||||
|
|
||||||
# skip this if already done
|
|
||||||
if [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(cat /usr/local/etc/A2SERVER-version) >= 101 )); then
|
|
||||||
|
|
||||||
echo "A2SERVER: Netatalk is already installed."
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
echo "A2SERVER: Installing Netatalk (this will take a while)..."
|
|
||||||
|
|
||||||
# stop Netatalk if running (during upgrade)
|
|
||||||
[[ $(ps --no-headers -C afpd) ]] && sudo /etc/init.d/netatalk stop
|
|
||||||
|
|
||||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
|
||||||
# prepare for installing packages
|
|
||||||
sudo apt-get -y update
|
|
||||||
touch /tmp/a2server-packageReposUpdated
|
|
||||||
fi
|
|
||||||
|
|
||||||
compileFromSource=1
|
|
||||||
while [[ $isRpi || $isDebian ]]; do
|
|
||||||
# Install runtime libraries needed by Netatalk
|
|
||||||
if [[ $(apt-cache search '^libdb4.8$') ]]; then
|
|
||||||
sudo apt-get -y install libdb4.8
|
|
||||||
elif [[ $(apt-cache search '^libdb5.1$') ]]; then
|
|
||||||
sudo apt-get -y install libdb5.1
|
|
||||||
else
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if [[ $(apt-cache search '^libssl1.0.0$') ]]; then
|
|
||||||
sudo apt-get -y install libssl1.0.0
|
|
||||||
elif [[ $(apt-cache search '^libssl0.9.8$') ]]; then
|
|
||||||
sudo apt-get -y install libssl0.9.8
|
|
||||||
else
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if [[ $(apt-cache search '^libgcrypt11$') ]]; then
|
|
||||||
sudo apt-get -y install libgcrypt11
|
|
||||||
else
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# install Netatalk
|
|
||||||
if [[ $isRpi ]]; then
|
|
||||||
{ wget -qO- /tmp/netatalk.tgz ivanx.com/a2server/files/netatalk224-rpi.tgz | sudo tar Pzx; } 2> /dev/null
|
|
||||||
elif [[ $isDebian ]]; then
|
|
||||||
{ wget -qO- /tmp/netatalk.tgz ivanx.com/a2server/files/netatalk224-debian7_x86.tgz | sudo tar Pzx; } 2> /dev/null
|
|
||||||
fi
|
|
||||||
sudo mandb &> /dev/null
|
|
||||||
|
|
||||||
[[ -f /usr/local/sbin/atalkd ]] && compileFromSource=
|
|
||||||
|
|
||||||
break
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ $compileFromSource ]]; then
|
|
||||||
# Install development libraries needed by Netatalk
|
|
||||||
sudo apt-get -y install build-essential
|
|
||||||
if [[ $(apt-cache search '^libdb4.8-dev$') ]]; then
|
|
||||||
sudo apt-get -y install libdb4.8-dev
|
|
||||||
elif [[ $(apt-cache search '^libdb5.1-dev$') ]]; then
|
|
||||||
sudo apt-get -y install libdb5.1-dev
|
|
||||||
else
|
|
||||||
echo "A2SERVER: WARNING: unknown version of libdb-dev is being installed"
|
|
||||||
sudo apt-get -y install libdb-dev
|
|
||||||
fi
|
|
||||||
sudo apt-get -y install libssl-dev
|
|
||||||
sudo apt-get -y install libgcrypt11-dev
|
|
||||||
sudo apt-get clean
|
|
||||||
|
|
||||||
# get Netatalk
|
|
||||||
rm -rf /tmp/netatalk &> /dev/null
|
|
||||||
mkdir /tmp/netatalk
|
|
||||||
cd /tmp/netatalk
|
|
||||||
|
|
||||||
wget -q "http://downloads.sourceforge.net/project/netatalk/netatalk/2.2.4/netatalk-2.2.4.tar.gz"
|
|
||||||
tar zxf netatalk-2.2.4.tar.gz
|
|
||||||
cd netatalk-2.2.4
|
|
||||||
|
|
||||||
# Patch the source so file dates are preserved during a GS/OS folder copy,
|
|
||||||
# and the AsanteTalk bridge consistently starts up in AppleTalk Phase 2
|
|
||||||
# and the Dayna bridge doesn't crash GS/OS
|
|
||||||
# props to Steven Hirsch for these
|
|
||||||
sed -i ':a;N;$!ba;s/case FILPBIT_ATTR :\n *change_mdate = 1;\n/case FILPBIT_ATTR :\n/g' etc/afpd/file.c
|
|
||||||
sed -i 's/rtmp->rt_iface == iface/rtmp->rt_iface != iface/g' etc/atalkd/main.c
|
|
||||||
|
|
||||||
# prepare to build Netatalk
|
|
||||||
./configure --enable-debian --enable-ddp --enable-a2boot
|
|
||||||
|
|
||||||
# uninstall Netatalk if already installed
|
|
||||||
[[ -f /usr/local/sbin/afpd ]] && sudo make uninstall
|
|
||||||
|
|
||||||
# compile and install Netatalk
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
# to remove the Netatalk source code (optional), type:
|
|
||||||
cd
|
|
||||||
rm -rf /tmp/netatalk
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Configuring Netatalk
|
|
||||||
|
|
||||||
echo "A2SERVER: Configuring Netatalk..."
|
|
||||||
|
|
||||||
# if missing Netatalk startup file, download a fresh one
|
|
||||||
if [ ! -f /etc/init.d/netatalk ]; then
|
|
||||||
echo "A2SERVER: Downloading new Netatalk startup script..."
|
|
||||||
sudo wget -qO /etc/init.d/netatalk ivanx.com/a2server/files/netatalk-init.d-clean.txt
|
|
||||||
fi
|
|
||||||
|
|
||||||
# make the Netatalk startup script work correctly
|
|
||||||
sudo sed -i 's/bin\/sh/bin\/bash/' /etc/init.d/netatalk
|
|
||||||
|
|
||||||
# enable AppleTalk networking support in Netatalk, and run in background
|
|
||||||
sudo sed -i 's/#ATALKD_RUN=no/ATALKD_RUN=yes/' /etc/default/netatalk
|
|
||||||
sudo sed -i 's/#ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk
|
|
||||||
if [[ ! $(grep 'kernelRelease' /etc/init.d/netatalk) ]]; then
|
|
||||||
sudo sed -i 's@\(\tif \[ x\"$ATALKD_RUN\)@\n\t# check for valid AppleTalk kernel module\n\t[[ $ATALKD_RUN == "yes" ]] \&\& { kernelRelease=$(uname -r); 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/'"'"'); [[ ( $kernelMajorRelease -eq 3 \&\& $kernelMinorRelease -ge 12 \&\& $kernelMinorRelease -le 15 ) \&\& ( ! ( -f /usr/bin/raspi-config \&\& $kernelMinorRelease -eq 12 \&\& $kernelPatchRelease -ge 25 ) ) \&\& ( ( ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ) || $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d " ") != "ecb239fc084c36de93f6926e7749b80f6024f269" ) ]] \&\& { ATALKD_RUN=no; echo "[AppleTalk networking is not available.]" 1>\&2; } }\n\n\1@' /etc/init.d/netatalk
|
|
||||||
fi
|
|
||||||
|
|
||||||
# enable network boot support in netatalk
|
|
||||||
sudo sed -i 's/timelord/a2boot/g' /etc/init.d/netatalk
|
|
||||||
sudo sed -i 's/TIMELORD/A2BOOT/g' /etc/init.d/netatalk
|
|
||||||
sudo sed -i 's/#A2BOOT_RUN=no/A2BOOT_RUN=yes/' /etc/default/netatalk
|
|
||||||
|
|
||||||
# allow Guest users to be able to network boot
|
|
||||||
sudo sed -i "s/#AFPD_GUEST=nobody/AFPD_GUEST=$USER/" /etc/default/netatalk
|
|
||||||
# (For a Guest user with different permissions than the compile-time user, create a
|
|
||||||
# Linux user, and then specify that user for AFPD_GUEST instead.)
|
|
||||||
|
|
||||||
# create a symbolic link to the startup configuration file in netatalk configuration folder
|
|
||||||
[[ -L /usr/local/etc/netatalk/netatalk.conf ]] \
|
|
||||||
|| sudo ln -s /etc/default/netatalk /usr/local/etc/netatalk/netatalk.conf
|
|
||||||
|
|
||||||
# create a symbolic link to the netatalk configuration folder in /etc
|
|
||||||
[[ -L /etc/netatalk ]] || sudo ln -s /usr/local/etc/netatalk /etc/netatalk
|
|
||||||
|
|
||||||
if [[ ! $(grep '^- -ddp.*uams_randnum.so' /usr/local/etc/netatalk/afpd.conf) ]]; then
|
|
||||||
# set up to allow Guest, Cleartext, RandNum, DHX, and DHX2 login
|
|
||||||
# disable DHX (DHCAST128) on Raspberry Pi, which refuses uams if the config string is too long
|
|
||||||
[[ -f /usr/bin/raspi-config ]] && dhx="" || dhx="uams_dhx.so,"
|
|
||||||
echo -n -e \
|
|
||||||
"- -ddp -tcp -uamlist uams_guest.so,uams_clrtxt.so,uams_randnum.so" \
|
|
||||||
| sudo tee -a /usr/local/etc/netatalk/afpd.conf > /dev/null
|
|
||||||
echo -e ",${dhx}uams_dhx2.so" \
|
|
||||||
| sudo tee -a /usr/local/etc/netatalk/afpd.conf > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
# replace home folder share and end of file mark with share placeholders
|
|
||||||
sudo sed -i 's/^~/#share1\n\n#share2/' \
|
|
||||||
/usr/local/etc/netatalk/AppleVolumes.default
|
|
||||||
|
|
||||||
# disable default volume options for Mac OS X clients
|
|
||||||
sudo sed -i 's/^:DEFAULT/#:DEFAULT/' \
|
|
||||||
/usr/local/etc/netatalk/AppleVolumes.default
|
|
||||||
|
|
||||||
if [[ ! $(grep ^eth0 /usr/local/etc/netatalk/atalkd.conf) && ! $(grep ^wlan0 /usr/local/etc/netatalk/atalkd.conf) ]]; then
|
|
||||||
# enable netatalk on the default network interface
|
|
||||||
# needs -router and -zone to prevent GS/OS AppleShare CDEV crash when used
|
|
||||||
# with Dayna or Asante bridges
|
|
||||||
echo -e 'eth0 -router -phase 2 -net 1 -zone "A2SERVER"' \
|
|
||||||
| sudo tee -a /usr/local/etc/netatalk/atalkd.conf > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Raspberry Pi
|
|
||||||
if [[ $isRpi ]]; then
|
|
||||||
# blink LED upon netatalk startup so you know when to attach power to an AsanteTalk bridge
|
|
||||||
if [[ ! $(grep 'led0' /etc/init.d/netatalk) ]]; then
|
|
||||||
sudo sed -i ':a;N;$!ba;s/fi\n}/fi\n\n # blink LED on Raspberry Pi\n ([[ -e \/sys\/class\/leds\/ACT ]] \&\& led=ACT || led=led0; echo none > \/sys\/class\/leds\/$led\/trigger; for i in {1..20}; do echo 1 > \/sys\/class\/leds\/$led\/brightness; sleep 0.25; echo 0 > \/sys\/class\/leds\/$led\/brightness; sleep 0.25; done; echo mmc0 > \/sys\/class\/leds\/$led\/trigger) \&\n}/' /etc/init.d/netatalk
|
|
||||||
fi
|
|
||||||
|
|
||||||
# set console port login to 4800 bps for usage with Apple II (using RPi console cable)
|
|
||||||
sudo sed -i 's/ttyAMA0 115200/ttyAMA0 4800/' /etc/inittab
|
|
||||||
|
|
||||||
# enable serial console login with USB-serial adapter
|
|
||||||
# 10-4-13: creates unwanted console messages if no adapter present,
|
|
||||||
# and physical port isn't predictable with more than one adapter present, so
|
|
||||||
# has been superseded by scanttyUSB supplied by A2CLOUD install
|
|
||||||
#if [[ ! $(grep 'ttyUSB0 19200' /etc/inittab) ]]; then
|
|
||||||
# echo -e "\n\n#for USB-to-serial adapter with Prolific PL2303 chipset\nT1:23:respawn:/sbin/getty -L ttyUSB0 19200 vt100" | sudo tee -a /etc/inittab > /dev/null
|
|
||||||
#fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# set up GSFILES share (for GS data files, not GSOS system)
|
|
||||||
# classic Mac OS file names are allowed (31 chars, mixed case, everything but colons)
|
|
||||||
sudo sed -i \
|
|
||||||
's/^#share1/\/media\/A2SHARED\/GSFILES\ GSFILES ea:ad/' \
|
|
||||||
/usr/local/etc/netatalk/AppleVolumes.default
|
|
||||||
[[ -d /srv/A2SERVER/GSFILES ]] || mkdir -p /srv/A2SERVER/GSFILES
|
|
||||||
|
|
||||||
# set up A2FILES share (for ProDOS 8 files, and GS/OS system)
|
|
||||||
# file names must be ProDOS 8 compliant (all caps, 15 chars, letters/numbers/periods only)
|
|
||||||
# lowercase filenames will be converted to upper automatically
|
|
||||||
# need for GS/OS system because it may refer to files by either upper or lower
|
|
||||||
sudo sed -i \
|
|
||||||
's/^#share2/\/media\/A2SHARED\/A2FILES\ A2FILES options:prodos\ casefold:toupper ea:ad/' \
|
|
||||||
/usr/local/etc/netatalk/AppleVolumes.default
|
|
||||||
[[ -d /srv/A2SERVER/A2FILES ]] || mkdir -p /srv/A2SERVER/A2FILES
|
|
||||||
if [[ ! -d /srv/A2SERVER/A2FILES/.AppleDesktop ]]; then
|
|
||||||
cd /srv/A2SERVER/A2FILES
|
|
||||||
mkdir .AppleDesktop
|
|
||||||
ln -s .AppleDesktop .APPLEDESKTOP
|
|
||||||
fi
|
|
||||||
|
|
||||||
# set up ADTDISKS share (ADTPro disk image folder, if A2CLOUD is installed)
|
|
||||||
# classic Mac OS file names are allowed (31 chars, mixed case, everything but colons)
|
|
||||||
if [[ -d /usr/local/adtpro/disks ]]; then # A2CLOUD/ADTPro installed
|
|
||||||
if [[ ! -d /srv/A2SERVER/ADTDISKS ]]; then
|
|
||||||
ln -s /usr/local/adtpro/disks /srv/A2SERVER/ADTDISKS
|
|
||||||
fi
|
|
||||||
if [[ ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then
|
|
||||||
sudo sed -i 's@^# End of File@/srv/A2SERVER/ADTDISKS ADTDISKS ea:ad\n\n# End of File@' /usr/local/etc/netatalk/AppleVolumes.default
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# to make Netatalk start up when the server boots:
|
|
||||||
sudo update-rc.d netatalk defaults &> /dev/null
|
|
||||||
|
|
||||||
|
|
||||||
# --- Setting up users
|
|
||||||
|
|
||||||
# At this point, the server is usable for Guest access.
|
|
||||||
|
|
||||||
# skip if we've already done this
|
|
||||||
if [[ -f /usr/local/etc/netatalk/afppasswd ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Netatalk user logins have already been set up."
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "A2SERVER: Setting up AFP password 'apple2' for Apple II and Mac clients."
|
|
||||||
# echo "A2SERVER: Enter 'apple2' or another password of up to eight characters."
|
|
||||||
echo
|
|
||||||
# set registered user login using RandNum authentication
|
|
||||||
sudo afppasswd -c
|
|
||||||
sudo sed -i 's/^pi.*$/pi:6170706C65320000:****************:********/' /usr/local/etc/netatalk/afppasswd
|
|
||||||
# while [[ ! $(sudo afppasswd -a $USER) ]]; do
|
|
||||||
# true
|
|
||||||
# done
|
|
||||||
# (The afppasswd -c only needs to ever be done once. You can repeat
|
|
||||||
# the afppasswd -a to make Netatalk logins for other Linux users.)
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check AppleTalk kernel module for existence and validity
|
|
||||||
|
|
||||||
# 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/')
|
|
||||||
kernelPatchRelease=$(cut -d '.' -f 3- <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/')
|
|
||||||
|
|
||||||
# if on kernel 3.12 through 3.15, check if we need to delete AppleTalk module to prevent kernel panics
|
|
||||||
if [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRelease -le 15 ]]; then
|
|
||||||
# if not RPi, or RPi without ivanx-fixed AppleTalk module, delete the module
|
|
||||||
if [[ ! ( $isRpi && $kernelMinorRelease -eq 12 && $kernelPatchRelease -ge 25 ) ]]; then
|
|
||||||
if [[ -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then
|
|
||||||
if [[ $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d ' ') != "ecb239fc084c36de93f6926e7749b80f6024f269" ]]; then
|
|
||||||
# stop Netatalk
|
|
||||||
sudo /etc/init.d/netatalk stop &> /dev/null
|
|
||||||
echo "A2SERVER: Deleting defective AppleTalk kernel module."
|
|
||||||
sudo rmmod appletalk 2> /dev/null
|
|
||||||
sudo rm -r /lib/modules/$kernelRelease/kernel/net/appletalk
|
|
||||||
# disable single-user mode on Pi (other Linux can use Recovery boot)
|
|
||||||
if [[ $isRpi && $(grep ' single' /boot/cmdline.txt 2> /dev/null) ]]; then
|
|
||||||
echo "A2SERVER: Disabling single-user mode for next boot."
|
|
||||||
sudo sed -i 's/ single//' /boot/cmdline.txt
|
|
||||||
touch /tmp/singleUser # so note to restart can display following install
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Start Netatalk (if not running)
|
|
||||||
|
|
||||||
bground=
|
|
||||||
if [[ $(grep 'ATALK_BGROUND=yes' /etc/default/netatalk) ]]; then
|
|
||||||
bground=1
|
|
||||||
sudo sed -i 's/ATALK_BGROUND=yes/ATALK_BGROUND=no/' /etc/default/netatalk
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ $(ps --no-headers -C afpd) ]] || sudo /etc/init.d/netatalk start 2> /dev/null
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "A2SERVER: Netatalk is installed, configured, and running."
|
|
||||||
echo
|
|
||||||
|
|
||||||
# if atalkd isn't running (no AppleTalk), and this is a Rasbperry Pi:
|
|
||||||
if [[ ( ! $(ps aux | grep [a]talkd) ) && ( $isRpi ) ]]; then
|
|
||||||
|
|
||||||
# if AppleTalk module exists, try to load it
|
|
||||||
if [[ -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # module present, but not loaded?
|
|
||||||
sudo depmod
|
|
||||||
sudo modprobe appletalk
|
|
||||||
if [[ $(lsmod | grep appletalk) ]]; then
|
|
||||||
# if it loaded, restart netatalk
|
|
||||||
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart
|
|
||||||
else
|
|
||||||
# if we didn't load it successfully, delete it
|
|
||||||
sudo rm -r /lib/modules/$kernelRelease/kernel/net/appletalk
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if no AppleTalk module, try to download it from a2server site
|
|
||||||
if [[ ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # check for rpi kernel module
|
|
||||||
echo "A2SERVER: Attempting to install AppleTalk kernel module for Raspbian..."
|
|
||||||
wget -qO /tmp/appletalk.ko.gz appleii.ivanx.com/a2server/files/appletalk-$kernelRelease.ko.gz
|
|
||||||
if [[ $? -eq 0 ]]; then
|
|
||||||
# if we found a prebuilt one on a2server site, install it and load it
|
|
||||||
gunzip -f /tmp/appletalk.ko.gz
|
|
||||||
sudo mkdir -p /lib/modules/$kernelRelease/kernel/net/appletalk
|
|
||||||
sudo mv /tmp/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk
|
|
||||||
sudo depmod
|
|
||||||
sudo modprobe appletalk
|
|
||||||
if [[ $(lsmod | grep appletalk) ]]; then
|
|
||||||
# if it loaded, restart netatalk
|
|
||||||
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart
|
|
||||||
else
|
|
||||||
# if we didn't load it successfully, remove it
|
|
||||||
sudo rm -r /lib/modules/$kernelRelease/kernel/net/appletalk 2> /dev/null
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if we still don't have AppleTalk, try to use rpi-update
|
|
||||||
rm /tmp/rpiUpdate 2> /dev/null
|
|
||||||
if [[ ! $(ps aux | grep [a]talkd) ]]; then
|
|
||||||
# use specific rpi-update commit (at https://github.com/Hexxeh/rpi-firmware/)
|
|
||||||
# from when AppleTalk was added/fixed, so we have a consistent firmware that
|
|
||||||
# we're loading until the next proper release of Raspbian that includes it
|
|
||||||
#
|
|
||||||
# 10-26-13: when AppleTalk was added to Raspbian:
|
|
||||||
# sudo rpi-update 9530adbe31fe6b8e05b3bd5cfadfc90f067f5362
|
|
||||||
# sudo modprobe appletalk 2> /dev/null
|
|
||||||
# if [[ $(lsmod | grep appletalk) ]]; then
|
|
||||||
# if it loaded, restart netatalk
|
|
||||||
# sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# 07-23-14: when AppleTalk was fixed after kernel panics in Raspbian 2014-06-20 (kernel 3.12.22+)
|
|
||||||
sudo rm /boot/.firmware_revision
|
|
||||||
sudo rpi-update cfd9a203590737f9536de70a1e01db25a3e8e069
|
|
||||||
touch /tmp/rpiUpdate # so note to restart can display following install
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $(ps aux | grep [a]talkd) ]]; then
|
|
||||||
if [[ -f /tmp/rpiUpdate ]]; then
|
|
||||||
echo
|
|
||||||
echo "AppleTalk networking is installed but not yet active."
|
|
||||||
echo "When installation is complete, please restart your Raspberry Pi"
|
|
||||||
echo "when asked or by typing 'system-restart' at the Linux prompt"
|
|
||||||
echo "to allow Apple II computers to connect."
|
|
||||||
echo
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
echo "AppleTalk networking could not be activated"
|
|
||||||
echo "for your Raspbian kernel version ($kernelRelease)."
|
|
||||||
echo "Please try restarting with 'system-restart'. If that doesn't work,"
|
|
||||||
echo "you're not going to be able to connect from an Apple II."
|
|
||||||
echo "See http://appleii.ivanx.com/a2server for help."
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $bground ]]; then
|
|
||||||
sudo sed -i 's/ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Set up Avahi-Daemon (Bonjour/mDNS)
|
|
||||||
# thanks to: http://missingreadme.wordpress.com/2010/05/08/how-to-set-up-afp-filesharing-on-ubuntu
|
|
||||||
|
|
||||||
if [[ ! $(dpkg -l avahi-daemon 2> /dev/null | grep ^ii) || ! $(dpkg -l libnss-mdns 2> /dev/null | grep ^ii) ]]; then
|
|
||||||
echo "A2SERVER: Installing Avahi-Daemon (Bonjour/mDNS)..."
|
|
||||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
|
||||||
# prepare for installing packages
|
|
||||||
sudo apt-get -y update
|
|
||||||
touch /tmp/a2server-packageReposUpdated
|
|
||||||
fi
|
|
||||||
sudo apt-get -y install avahi-daemon libnss-mdns &> /dev/null
|
|
||||||
fi
|
|
||||||
sudo sed -i 's/^\(hosts.*\)$/\1 mdns/' /etc/nsswitch.conf
|
|
||||||
if [[ ! -f /etc/avahi/services/afpd.service && ! -f /etc/avahi/services/afpd.service_disabled ]]; then
|
|
||||||
echo -e '<?xml version="1.0" standalone="no"?><!--*-nxml-*-->\n<!DOCTYPE service-group SYSTEM "avahi-service.dtd">\n<service-group>\n <name replace-wildcards="yes">%h</name>\n <service>\n <type>_afpovertcp._tcp</type>\n <port>548</port>\n </service>\n <service>\n <type>_device-info._tcp</type>\n <port>0</port>\n <txt-record>model=MacPro</txt-record>\n </service>\n</service-group>' | sudo tee /etc/avahi/services/afpd.service > /dev/null
|
|
||||||
fi
|
|
||||||
sudo /etc/init.d/avahi-daemon restart &> /dev/null
|
|
@@ -1,444 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# this script downloads and installs the Apple boot blocks required
|
|
||||||
# for booting an Apple II client over the network, and places
|
|
||||||
# BASIC.SYSTEM on the shared drive and configures it to be the startup
|
|
||||||
# program (for Apple IIe users, and IIgs users in ProDOS network mode).
|
|
||||||
# It also can download and install GS/OS for a network boot configuration.
|
|
||||||
|
|
||||||
gsosDir="/srv/A2SERVER/A2FILES"
|
|
||||||
imagesDir=$gsosDir/GSOS.INSTALLER/IMAGES
|
|
||||||
imageToolsDir=$gsosDir/GSOS.INSTALLER/IMAGE.TOOLS
|
|
||||||
netInstallDir=$gsosDir/GSOS.INSTALLER/NET.INSTALL
|
|
||||||
|
|
||||||
p8Dir="/srv/A2SERVER/A2FILES"
|
|
||||||
diskToolsP8Dir=$p8Dir/DISK.TOOLS.P8
|
|
||||||
|
|
||||||
commDir="/srv/A2SERVER/A2FILES/COMM"
|
|
||||||
spectrumDir=$commDir/SPECTRUM
|
|
||||||
protermDir=$commDir/PROTERM
|
|
||||||
zlinkDir=$commDir/Z.LINK
|
|
||||||
adtproDir=$commDir/ADTPRO
|
|
||||||
|
|
||||||
# bail out on automated netboot setup unless -b is also specified
|
|
||||||
[[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes=
|
|
||||||
if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo
|
|
||||||
echo "Do you want to set up A2SERVER to be able to boot Apple II"
|
|
||||||
echo -n "computers over the network? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
|
|
||||||
nbmode=1
|
|
||||||
echo
|
|
||||||
|
|
||||||
sudo true
|
|
||||||
mkdir -p /tmp/netboot
|
|
||||||
cd /tmp/netboot
|
|
||||||
|
|
||||||
# this will get "Disk 7" (Apple II Setup) as a raw (block dump) image
|
|
||||||
if [[ ! -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Boot\ Blocks ]] \
|
|
||||||
|| [[ ! -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Image ]] \
|
|
||||||
|| [[ ! -f /usr/local/etc/netatalk/a2boot/Apple\ :2f:2fe\ Boot\ Blocks ]]; then
|
|
||||||
echo "A2SERVER: Downloading Apple II Boot Blocks..."
|
|
||||||
cd /tmp/netboot
|
|
||||||
|
|
||||||
wget -qO Disk_7_of_7-Apple_II_Setup.sea.bin http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_IIGS_System_6.0.1%2FDisk_7_of_7-Apple_II_Setup.sea.bin
|
|
||||||
unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null
|
|
||||||
truncate -s 819284 'Disk 7 of 7-Apple II Setup.sea'
|
|
||||||
dd if='Disk 7 of 7-Apple II Setup.sea' of=APPLE2SETUP.HDV bs=84 skip=1 2> /dev/null
|
|
||||||
|
|
||||||
# copy the Boot Blocks into the right place
|
|
||||||
mkdir -p a2setup
|
|
||||||
sudo mount -t hfs -o ro,loop APPLE2SETUP.HDV a2setup
|
|
||||||
sudo mkdir -p /usr/local/etc/netatalk/a2boot
|
|
||||||
sudo cp -p a2setup/System\ Folder/* /usr/local/etc/netatalk/a2boot
|
|
||||||
sudo umount a2setup
|
|
||||||
sudo mv /usr/local/etc/netatalk/a2boot/Apple* /usr/local/etc/netatalk/a2boot/'Apple :2f:2fe Boot Blocks'
|
|
||||||
|
|
||||||
cd /usr/local/etc/netatalk/a2boot
|
|
||||||
# thanks to Geoff Body for these Boot Blocks patches
|
|
||||||
# fix cleartext password login bug
|
|
||||||
echo -n -e "\xA8\xA2\x01\xBD\x80\x38\x99\xA0\x38\xC8\xE8\xE0\x09\x90\xF4" | \
|
|
||||||
sudo dd of='Apple :2f:2fe Boot Blocks' bs=19779 seek=1 conv=notrunc 2> /dev/null
|
|
||||||
echo -n -e "\xA8\xA2\x01\xBD\x80\x10\x99\xA0\x10\xC8\xE8\xE0\x09\x90\xF4" | \
|
|
||||||
sudo dd of='ProDOS16 Image' bs=22583 seek=1 conv=notrunc 2> /dev/null
|
|
||||||
# enable typing "8" during GS/OS netboot to force ProDOS 8 boot
|
|
||||||
echo -n -e "\x92" | sudo dd of='ProDOS16 Image' bs=256 seek=1 conv=notrunc 2> /dev/null
|
|
||||||
echo -n -e "\x20\x7d\x14" | sudo dd of='ProDOS16 Image' bs=864 seek=1 conv=notrunc 2> /dev/null
|
|
||||||
echo -n -e "\xad\x00\xc0\x29\xff\x00\xc9\xb8\x00\xd0\x06\xa9\x02\x00\x8d\x53\x14\xa9\x10\x0f\x60" | \
|
|
||||||
sudo dd of='ProDOS16 Image' bs=1661 seek=1 conv=notrunc 2> /dev/null
|
|
||||||
fi
|
|
||||||
echo "A2SERVER: Boot Blocks have been installed."
|
|
||||||
|
|
||||||
# get a2server-tools if necessary
|
|
||||||
if [[ ! -f /usr/local/bin/mkatinit ]] \
|
|
||||||
|| [[ ! -f /usr/local/bin/afptype ]] \
|
|
||||||
|| [[ ! -f /usr/local/bin/mkvolinfo ]] \
|
|
||||||
|| [[ ! -f /usr/local/bin/afpsync ]]; then
|
|
||||||
rm /tmp/2.tools &> /dev/null
|
|
||||||
wget -q -O /tmp/2.tools appleii.ivanx.com/a2server/scripts/a2server-2-tools.txt
|
|
||||||
chmod ugo+x /tmp/2.tools
|
|
||||||
/tmp/2.tools
|
|
||||||
rm /tmp/2.tools
|
|
||||||
fi
|
|
||||||
|
|
||||||
# put BASIC.SYSTEM at root for ProDOS 8 startup
|
|
||||||
cp -p /usr/local/etc/netatalk/a2boot/Basic.System $gsosDir/BASIC.SYSTEM
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
afptype -p SYS -q $gsosDir/BASIC.SYSTEM
|
|
||||||
|
|
||||||
# create tools for setting GS/OS or ProDOS 8 boot in battery RAM and rebooting. Props yet again to Geoff Body.
|
|
||||||
if [[ ! -f $p8Dir/NETBOOT.P8 ]]; then
|
|
||||||
echo
|
|
||||||
echo "A2SERVER: Creating NETBOOT.P8..."
|
|
||||||
touch $p8Dir/NETBOOT.P8
|
|
||||||
echo -n -e "\x38\x20\x1f\xfe\x90\x01\x60\xfb\x08\xc2\x30\xf4\x02\x00\xf4\x62\x00\xa2\x03\x0b\x22\x00\x00\xe1\x78\xf4\x00\x00\xf4\x00\x00\xab\xab\x2b\x38\xfb\xce\xf4\x03\xa9\x0c\x8d\x68\xc0\x9c\x47\xc0\x9c\x41\xc0\xa9\x09\x8d\x39\xc0\xa9\xc0\x8d\x39\xc0\x5c\x62\xfa\x00" | \
|
|
||||||
sudo dd of="$p8Dir/NETBOOT.P8" 2> /dev/null
|
|
||||||
afpsync -v $p8Dir > /dev/null
|
|
||||||
afptype -p SYS -q $p8Dir/NETBOOT.P8
|
|
||||||
fi
|
|
||||||
if [[ ! -f $gsosDir/NETBOOT.GSOS ]]; then
|
|
||||||
echo
|
|
||||||
echo "A2SERVER: Creating NETBOOT.GSOS..."
|
|
||||||
# create tool for setting GSOS boot in battery RAM and rebooting. Props yet again to Geoff Body.
|
|
||||||
touch $gsosDir/NETBOOT.GSOS
|
|
||||||
echo -n -e "\x38\x20\x1f\xfe\x90\x01\x60\xfb\x08\xc2\x30\xf4\x01\x00\xf4\x62\x00\xa2\x03\x0b\x22\x00\x00\xe1\x78\xf4\x00\x00\xf4\x00\x00\xab\xab\x2b\x38\xfb\xce\xf4\x03\xa9\x0c\x8d\x68\xc0\x9c\x47\xc0\x9c\x41\xc0\xa9\x09\x8d\x39\xc0\xa9\xc0\x8d\x39\xc0\x5c\x62\xfa\x00" | \
|
|
||||||
sudo dd of="$p8Dir/NETBOOT.GSOS" 2> /dev/null
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
afptype -p SYS -q $gsosDir/NETBOOT.GSOS
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkatinit -gs -d -f # GS/OS registered user and Guest starts up with SYSTEM/FINDER
|
|
||||||
mkatinit -d -f guest # ProDOS 8 Guest starts up with BASIC.SYSTEM (no registered user)
|
|
||||||
|
|
||||||
if [[ -f "/srv/A2SERVER/A2FILES/SYSTEM/START.GS.OS" ]]; then
|
|
||||||
echo "A2SERVER: GS/OS has already been downloaded and installed."
|
|
||||||
gsosInstall=1
|
|
||||||
else
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo "You can set up GS/OS 6.0.1 on your network drive, for network boot."
|
|
||||||
echo -n "This may take a while. Download and install it now? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
gsosInstall=1
|
|
||||||
|
|
||||||
# get GS/OS disks from Internet Archive and put them in IMAGES
|
|
||||||
# also dump contents into NET.INSTALL and modify scripts to work from there
|
|
||||||
# echo
|
|
||||||
# echo "Come back in a while. This takes a long time."
|
|
||||||
echo
|
|
||||||
echo "A2SERVER: Downloading GS/OS 6.0.1 installer disk images..."
|
|
||||||
cd /tmp/netboot
|
|
||||||
mkdir -p $imagesDir
|
|
||||||
mkdir -p $netInstallDir
|
|
||||||
activeDisk=0
|
|
||||||
for diskname in Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB; do
|
|
||||||
outfile="$imagesDir/$(tr [:lower:] [:upper:] <<< $diskname)"
|
|
||||||
if [ ! -f $outfile ]; then
|
|
||||||
(( activeDisk++ ))
|
|
||||||
echo "A2SERVER: Disk ${activeDisk} of 6: $diskname"
|
|
||||||
wget -qO "Disk_${activeDisk}_of_7-$diskname.sea.bin" "http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_IIGS_System_6.0.1%2FDisk_${activeDisk}_of_7-$diskname.sea.bin"
|
|
||||||
unar -k skip "Disk_${activeDisk}_of_7-$diskname.sea.bin" &> /dev/null
|
|
||||||
truncate -s 819284 "Disk ${activeDisk} of 7-${diskname}.sea"
|
|
||||||
dd if="Disk ${activeDisk} of 7-${diskname}.sea" of=${outfile} bs=84 skip=1 &> /dev/null
|
|
||||||
cppo -s -ad $outfile $netInstallDir 2> /dev/null
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
rm *.sea* &> /dev/null
|
|
||||||
sed -i "s/\([^\\]\r:\)/\1A2FILES:GSOS.INSTALLER:NET.INSTALL:/g" $netInstallDir/INSTALL/SCRIPTS/*
|
|
||||||
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
|
|
||||||
# install GS/OS
|
|
||||||
# spec for GS/OS installer scripts: GS/OS Tech Note #64
|
|
||||||
# http://www.1000bit.it/support/manuali/apple/technotes/iigs/tn.iigs.064.html
|
|
||||||
processScript () {
|
|
||||||
scriptEntries=$(cat $1 | tr '\r' '#' | tr '~' '\n' | sed 's/4#D/5/')
|
|
||||||
IFS=$'\n'
|
|
||||||
scriptEntries=($scriptEntries)
|
|
||||||
pathPrefix="/A2FILES/GSOS.INSTALLER/NET.INSTALL"$(tr ':' '/' <<< ${scriptEntries[0]##S*\\\\#})
|
|
||||||
entryCount=${#scriptEntries[@]}
|
|
||||||
(( entryCount -= 2 ))
|
|
||||||
entryIndex=3
|
|
||||||
while (( entryIndex < entryCount )); do
|
|
||||||
IFS='#'
|
|
||||||
scriptEntry=(${scriptEntries[entryIndex]})
|
|
||||||
# echo $entryIndex $entryCount ${scriptEntry[1]}
|
|
||||||
action=${scriptEntry[1]:0:1}
|
|
||||||
sourcePathMixed=$(tr ':' '/' <<< ${scriptEntry[5]})
|
|
||||||
[[ ${sourcePathMixed:0:1} != '/' ]] && sourcePathMixed="${pathPrefix}/$sourcePathMixed"
|
|
||||||
sourcePath=$(tr [:lower:] [:upper:] <<< $sourcePathMixed)
|
|
||||||
targetPath=$gsosDir/$(tr ':' '/' <<< ${scriptEntry[6]} | tr [:lower:] [:upper:])
|
|
||||||
# volumeName=$(cut -d/ -f 2 <<< $sourcePath)
|
|
||||||
targetParent=${targetPath%/*}
|
|
||||||
targetFile=${targetPath##*/}
|
|
||||||
sourceParent=${sourcePath%/*}
|
|
||||||
sourceFile=${sourcePath##*/}
|
|
||||||
|
|
||||||
if [[ $action == 1 || $action == 2 ]]; then
|
|
||||||
mkdir -p $targetParent
|
|
||||||
echo "copying: $sourcePathMixed"
|
|
||||||
echo " to: $targetPath"
|
|
||||||
echo
|
|
||||||
[[ ! -d $targetParent ]] && mkdir -p $targetParent
|
|
||||||
cp -p ${gsosDir%/*}$sourcePath $targetPath
|
|
||||||
[[ ! -d $targetParent/.AppleDouble ]] && mkdir -p $targetParent/.AppleDouble
|
|
||||||
cp -p ${gsosDir%/*}$sourceParent/.AppleDouble/$sourceFile $targetParent/.AppleDouble/$targetFile
|
|
||||||
elif [[ $action == 3 || $action == 4 ]]; then
|
|
||||||
if [[ -f "$targetPath" ]]; then
|
|
||||||
echo "deleting $targetPath"
|
|
||||||
rm "$targetPath"
|
|
||||||
[[ -f $targetParent/.AppleDouble/$targetFile ]] && rm "$targetParent/.AppleDouble/$targetFile"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
(( entryIndex++ ))
|
|
||||||
done
|
|
||||||
unset IFS
|
|
||||||
}
|
|
||||||
|
|
||||||
mkdir -p /tmp/netboot
|
|
||||||
cd /tmp/netboot
|
|
||||||
|
|
||||||
echo "A2SERVER: Preparing GS/OS installer scripts..."
|
|
||||||
# work through installer scripts
|
|
||||||
processScript $netInstallDir/INSTALL/SCRIPTS/INSTAL.SYS.FILE
|
|
||||||
processScript $netInstallDir/INSTALL/SCRIPTS/APPLESHARE
|
|
||||||
processScript $netInstallDir/INSTALL/SCRIPTS/SERVER.SYS.FILE
|
|
||||||
|
|
||||||
# sync netatalk database
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo
|
|
||||||
echo "Do you want to download and install utilities for working with"
|
|
||||||
echo -n "disk images and archive files in GS/OS? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
|
|
||||||
# download image tools and put them in IMAGE.TOOLS
|
|
||||||
echo "A2SERVER: Downloading GS/OS disk image utilities..."
|
|
||||||
mkdir -p $imageToolsDir
|
|
||||||
|
|
||||||
# get Asimov2 (for GS/OS)
|
|
||||||
echo -n "Asimov 2.0"
|
|
||||||
if [[ -f $imageToolsDir/ASIMOV ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -q -nc http://www.ninjaforce.com/downloads/Asimov.shk
|
|
||||||
nulib2 -x -s Asimov.shk > /dev/null
|
|
||||||
cp -p Asimov/Asimov $imageToolsDir/ASIMOV
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
cat Asimov/Asimov_rsrc_ >> $imageToolsDir/.AppleDouble/ASIMOV
|
|
||||||
afptype -p S16 -q $imageToolsDir/ASIMOV
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "GS-ShrinkIt 1.1"
|
|
||||||
# get GS-ShrinkIt
|
|
||||||
if [[ -f $imageToolsDir/GSHK ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -qO gshk.sea http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea
|
|
||||||
#wget -qO gshk.sea http://www.nulib.com/library/gshk11.sea
|
|
||||||
nulib2 -x -s gshk.sea > /dev/null
|
|
||||||
cp -p GSHK $imageToolsDir/GSHK
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
cat GSHK_rsrc_ >> $imageToolsDir/.AppleDouble/GSHK
|
|
||||||
afptype -p S16 -a DB07 -q $imageToolsDir/GSHK
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "MountIt 1.4"
|
|
||||||
# get MountIt (for GS/OS)
|
|
||||||
if [[ -f $imageToolsDir/MOUNTIT.SHK ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -q -nc http://www.brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK
|
|
||||||
cp -p MOUNTIT.SHK $imageToolsDir/MOUNTIT.SHK
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
afptype -p SHK -q $imageToolsDir/MOUNTIT.SHK
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo
|
|
||||||
echo "Do you want to download and install utilities for working with"
|
|
||||||
echo -n "disk images and archive files in ProDOS 8? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Downloading ProDOS 8 disk image utilities..."
|
|
||||||
|
|
||||||
mkdir -p $diskToolsP8Dir
|
|
||||||
|
|
||||||
echo -n "ShrinkIt 3.4"
|
|
||||||
# get ShrinkIt 3.4 (for ProDOS 8)
|
|
||||||
if [[ -f $diskToolsP8Dir/SHRINKIT ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -qO shrinkit.sdk http://web.archive.org/web/20131031160750/http://www.nulib.com/library/shrinkit.sdk
|
|
||||||
[[ ! -f shrinkit.sdk ]] && wget -qO shrinkit.sdk appleii.ivanx.com/a2server/files/shrinkit.sdk
|
|
||||||
nulib2 -xs shrinkit.sdk > /dev/null
|
|
||||||
cppo -s -ad SHRINKIT /SHRINKIT/SHRINKIT $diskToolsP8Dir 2> /dev/null
|
|
||||||
afpsync -v $sharepath > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "DSK2FILE 5.8"
|
|
||||||
# get DSK2FILE (for ProDOS 8)
|
|
||||||
if [[ -f $diskToolsP8Dir/DSK2FILE ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -q -O dsk2file.shk http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip
|
|
||||||
nulib2 -x -s dsk2file.shk > /dev/null
|
|
||||||
cp -p DSK2FILE58 $diskToolsP8Dir/DSK2FILE
|
|
||||||
afpsync -v $sharepath > /dev/null
|
|
||||||
afptype -p SYS -q $diskToolsP8Dir/DSK2FILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "Apple System Utilities 3.1"
|
|
||||||
if [[ -f $diskToolsP8Dir/SYSUTIL ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -qO Apple_II_System_Disk_3.2.sea.bin http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_II_Supplemental%2FApple_II_System_Disk_3.2.sea.bin
|
|
||||||
unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null
|
|
||||||
truncate -s 819284 'Apple II System Disk 3.2.sea'
|
|
||||||
dd if='Apple II System Disk 3.2.sea' of=A2SYSDISK32.HDV bs=84 skip=1 2> /dev/null
|
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/SYSUTIL.SYSTEM $diskToolsP8Dir/SYSUTIL 2> /dev/null
|
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.0 $diskToolsP8Dir 2> /dev/null
|
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.1 $diskToolsP8Dir 2> /dev/null
|
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.2 $diskToolsP8Dir 2> /dev/null
|
|
||||||
afpsync -v $sharepath > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo
|
|
||||||
echo "Do you want to download serial communications software for"
|
|
||||||
echo -n "GS/OS and ProDOS 8? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Downloading communications software..."
|
|
||||||
|
|
||||||
mkdir -p $commDir
|
|
||||||
|
|
||||||
echo -n "Spectrum"
|
|
||||||
# get Spectrum
|
|
||||||
if [[ -f $commDir/SPECTRUM/SPECTRUM.HDV ]]; then
|
|
||||||
echo " is already installed."
|
|
||||||
else
|
|
||||||
mkdir -p $spectrumDir
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -qO- http://www.speccie.co.uk/speccie/software/spectrum.2mg | dd bs=64 skip=1 of=$spectrumDir/SPECTRUM.HDV 2> /dev/null
|
|
||||||
wget -qO- http://www.speccie.co.uk/speccie/software/spectrum_extras.2mg | dd bs=64 skip=1 of=$spectrumDir/EXTRAS.HDV 2> /dev/null
|
|
||||||
wget -qO- http://www.speccie.co.uk/speccie/software/spectrum_sounds.2mg | dd bs=64 skip=1 of=$spectrumDir/SOUNDS.HDV 2> /dev/null
|
|
||||||
wget -qO- http://www.speccie.co.uk/speccie/software/spectrum_manuals.2mg | dd bs=64 skip=1 of=$spectrumDir/MANUALS.HDV 2> /dev/null
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "ProTERM and Z-Link"
|
|
||||||
# get A2CLOUD disk and copy from there
|
|
||||||
if [[ -f $commDir/PROTERM/PROTERM ]]; then
|
|
||||||
echo " are already installed."
|
|
||||||
else
|
|
||||||
mkdir -p $protermDir
|
|
||||||
mkdir -p $protermDir/.AppleDouble
|
|
||||||
mkdir -p $zlinkDir
|
|
||||||
mkdir -p $zlinkDir/.AppleDouble
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot
|
|
||||||
wget -qO A2CLOUD.HDV http://ivanx.com/a2cloud/files/A2CLOUD.HDV
|
|
||||||
cppo -ad A2CLOUD.HDV . > /dev/null
|
|
||||||
cd A2CLOUD
|
|
||||||
mv *PT3* *PROTERM* $protermDir
|
|
||||||
mv Z.LINK $zlinkDir
|
|
||||||
cd .AppleDouble
|
|
||||||
mv *PT3* *PROTERM* $protermDir/.AppleDouble
|
|
||||||
mv Z.LINK $zlinkDir/.AppleDouble
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "ADTPro and VSDRIVE"
|
|
||||||
if [[ -f $commDir/ADTPRO/ADTPRO ]]; then
|
|
||||||
echo " are already installed."
|
|
||||||
else
|
|
||||||
mkdir -p $adtproDir
|
|
||||||
mkdir -p $adtproDir/.AppleDouble
|
|
||||||
echo
|
|
||||||
cd /tmp/netboot/A2CLOUD
|
|
||||||
mv *ADTPRO* *VEDRIVE* *VSDRIVE* $adtproDir
|
|
||||||
cd .AppleDouble
|
|
||||||
mv *ADTPRO* *VEDRIVE* *VSDRIVE* $adtproDir/.AppleDouble
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# clean up
|
|
||||||
cd
|
|
||||||
[[ -d /tmp/netboot ]] && rm -rf /tmp/netboot
|
|
||||||
[[ -d ~/GNUstep ]] && rm -rf ~/GNUstep
|
|
||||||
|
|
||||||
# rock and roll!
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo
|
|
||||||
if (( $gsosInstall )); then
|
|
||||||
echo "GS/OS network boot (for registered user and Guest) and"
|
|
||||||
fi
|
|
||||||
echo "ProDOS 8 network boot (for Guest only) is now configured."
|
|
||||||
echo "See http://appleii.ivanx.com/a2server for info using it."
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo
|
|
||||||
echo "Do you want to download the patch required for using"
|
|
||||||
echo -n "a Farallon LocalTalk-to-Ethernet bridge with GS/OS? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
echo "A2SERVER: Downloading Farallon bridge patch..."
|
|
||||||
wget -O /tmp/FARALLON.PO appleii.ivanx.com/a2server/files/FARALLON.B1.PO &> /dev/null
|
|
||||||
if [[ -d $gsosDir/SYSTEM/SYSTEM.SETUP ]]; then
|
|
||||||
cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir/SYSTEM/SYSTEM.SETUP &> /dev/null
|
|
||||||
echo
|
|
||||||
echo "A2SERVER: The Farallon bridge patch is installed."
|
|
||||||
else
|
|
||||||
cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir &> /dev/null
|
|
||||||
echo
|
|
||||||
echo "On your Apple IIgs, copy the file ATALKIRQ in /A2SHARED to the"
|
|
||||||
echo "SYSTEM.SETUP folder of the SYSTEM folder of your GSOS startup disk,"
|
|
||||||
echo "or, if you can't, download the patch from the A2SERVER web site."
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "Note: Farallon bridges can only be used in GS/OS (with this patch)"
|
|
||||||
echo "and Apple IIe computers. Apple IIgs computers which network boot"
|
|
||||||
echo "directly into ProDOS 8 will freeze after a few minutes."
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
@@ -1,95 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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=
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
echo "A2SERVER: Setting up Windows file sharing..."
|
|
||||||
sudo true
|
|
||||||
|
|
||||||
if [[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]]; then
|
|
||||||
[[ -f /etc/init/smbd.conf.off ]] && sudo mv /etc/init/smbd.conf.off /etc/init/smbd.conf
|
|
||||||
[[ -f /etc/init/nmbd.conf.off ]] && sudo mv /etc/init/nmbd.conf.off /etc/init/nmbd.conf
|
|
||||||
[[ ! -f /etc/init/smbd.conf || ! -f /etc/init/nmbd.conf ]] && installSamba=1
|
|
||||||
else
|
|
||||||
sudo update-rc.d samba defaults &> /dev/null
|
|
||||||
[[ ! -f /etc/init.d/samba ]] && 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
|
|
||||||
|
|
||||||
sudo apt-get -y install samba
|
|
||||||
[[ -f /usr/bin/smbpasswd ]] || sudo apt-get -y install samba-common-bin
|
|
||||||
sudo apt-get clean
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]]; then
|
|
||||||
sudo initctl start smbd &> /dev/null
|
|
||||||
sudo initctl start nmbd &> /dev/null
|
|
||||||
else
|
|
||||||
sudo /etc/init.d/samba start &> /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
grep ^/media /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
|
|
||||||
|
|
||||||
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
|
|
||||||
if [[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]]; then
|
|
||||||
sudo initctl stop smbd &> /dev/null
|
|
||||||
sudo initctl stop nmbd &> /dev/null
|
|
||||||
[[ -f /etc/init/smbd.conf ]] && sudo mv /etc/init/smbd.conf /etc/init/smbd.conf.off
|
|
||||||
[[ -f /etc/init/nmbd.conf ]] && sudo mv /etc/init/nmbd.conf /etc/init/nmbd.conf.off
|
|
||||||
else
|
|
||||||
sudo /etc/init.d/samba stop &> /dev/null
|
|
||||||
sudo update-rc.d -f samba remove &> /dev/null
|
|
||||||
fi
|
|
||||||
echo "A2SERVER: Windows file sharing has been turned off."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
fi
|
|
@@ -1,105 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# --- Ubuntu Server console optimizaton (optional)
|
|
||||||
|
|
||||||
# This script helps when running on the Linux console within the 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=
|
|
||||||
|
|
||||||
password="your password"
|
|
||||||
[[ $isApple2Pw ]] && password="'apple2'"
|
|
||||||
[[ $isRaspberryPw ]] && password="'raspberry'"
|
|
||||||
|
|
||||||
isDebian=
|
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "7." ) && ( $(uname -m) == "i686" ) ]] && isDebian=1
|
|
||||||
|
|
||||||
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
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check that we're on Ubuntu
|
|
||||||
if [[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]]; then
|
|
||||||
|
|
||||||
# don't do any of this if we're logged in via SSH
|
|
||||||
if [[ $SSH_CLIENT || $REMOTEHOST ]]; then
|
|
||||||
echo "A2SERVER: Logged in via SSH,not performing console optimization."
|
|
||||||
echo "Run setup from the console if you want to optimize the console."
|
|
||||||
else
|
|
||||||
|
|
||||||
# if we've already done this stuff, don't do it again
|
|
||||||
if [[ ! -x /etc/update-motd.d/10-help-text ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Ubuntu console has already been optimized."
|
|
||||||
else
|
|
||||||
echo "Ubuntu console optimization for use in a virtual machine will:"
|
|
||||||
echo "- show the default username/password on the login screen"
|
|
||||||
echo "- remove the documentation URL and system statistics shown after login"
|
|
||||||
echo "- ensure the screen clears before showing the login prompt"
|
|
||||||
echo "- prevent the screen from dimming after 10 minutes (once logged in)"
|
|
||||||
echo "- eliminate a harmless but annoying startup error about piix_smbus"
|
|
||||||
echo "- fix an Ubuntu 10.04 issue with slow scrolling"
|
|
||||||
echo
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo -n "Do you want to optimize the Ubuntu console? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
|
||||||
|
|
||||||
echo "A2SERVER: Optimizing console..."
|
|
||||||
|
|
||||||
# remind the user how to log in (we're going for functionality here, not security)
|
|
||||||
if [[ ! $(grep $USER\/$password /etc/issue) ]]; then
|
|
||||||
sudo sed -i '/^Log in with.*$/d' /etc/issue
|
|
||||||
echo "Log in with '$USER' / '$password'." | sudo tee -a /etc/issue > /dev/null
|
|
||||||
echo | sudo tee -a /etc/issue > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If after logging in, you don't like the documentation URL and
|
|
||||||
# system info (or an error about it) being displayed, type:
|
|
||||||
sudo chmod -x /etc/update-motd.d/10-help-text
|
|
||||||
sudo chmod -x /etc/update-motd.d/50-landscape-sysinfo
|
|
||||||
|
|
||||||
# If the screen doesn't clear for login after the boot messages, and
|
|
||||||
# you'd like it to, type:
|
|
||||||
sudo sed -i 's/X_DEFAULT=""/X_DEFAULT="quiet"/g' /etc/default/grub
|
|
||||||
sudo update-grub
|
|
||||||
|
|
||||||
# If you see a piix4_smbus error on startup, it is harmless, but if you
|
|
||||||
# want to eliminate it, type:
|
|
||||||
echo -e '\nblacklist i2c_piix4' \
|
|
||||||
| sudo tee -a /etc/modprobe.d/blacklist.conf > /dev/null
|
|
||||||
sudo update-initramfs -u -k all
|
|
||||||
|
|
||||||
# If you want to prevent the Ubuntu screen from going blank after ten
|
|
||||||
# minutes of inactivity (once you are logged in), type:
|
|
||||||
echo -e \
|
|
||||||
'\n[[ $SSH_CLIENT || $REMOTEHOST ]] || setterm -blank 0 -powersave off -powerdown 0' \
|
|
||||||
| sudo tee -a /etc/profile > /dev/null
|
|
||||||
setterm -blank 0 -powersave off -powerdown 0
|
|
||||||
|
|
||||||
# (note: These next lines addresses an issue only for Ubuntu 10.04.)
|
|
||||||
# Type "ps aux" and press return. If you see slow text scrolling, type:
|
|
||||||
if [[ "$(lsb_release -rs 2> /dev/null)" == "10.04" ]]; then
|
|
||||||
echo -e '\nblacklist vga16fb' \
|
|
||||||
| sudo tee -a /etc/modprobe.d/blacklist-framebuffer.conf > /dev/null
|
|
||||||
if [[ ! $SSH_CLIENT ]]; then
|
|
||||||
echo "Restarting now is recommended. To resume setup, log back"
|
|
||||||
echo -n "in, press up-arrow, and press return. Restart now? "
|
|
||||||
read; R=${REPLY:0:1}
|
|
||||||
[[ $R != "y" ]] && [[ $R != "Y" ]] || sudo shutdown -r now
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
@@ -1,86 +0,0 @@
|
|||||||
# A2SERVER aliases:
|
|
||||||
|
|
||||||
|
|
||||||
alias a2server-help="more /usr/local/etc/a2server-help.txt"
|
|
||||||
alias a2server-setup="wget -q -O /tmp/a2server-setup appleii.ivanx.com/a2server/setup/; source /tmp/a2server-setup"
|
|
||||||
|
|
||||||
alias a2server-version="cat /usr/local/etc/A2SERVER-version"
|
|
||||||
alias a2server-update="wget -q -O /tmp/a2server-update appleii.ivanx.com/a2server/update/; 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 ivanx.com/a2server/files/raspbian-update.txt; source /tmp/raspbian-update'
|
|
||||||
alias rasppleii-update='raspbian-update a2cloud a2server'
|
|
||||||
|
|
||||||
alias welcome-message-edit='[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && motd=/etc/issue || motd=/etc/motd; sudo nano $motd'
|
|
||||||
|
|
||||||
alias showip='ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1'
|
|
||||||
alias showmac='ifconfig eth0 | grep "HWaddr" | cut -dH -f2 | cut -c7-23'
|
|
||||||
alias showip-wifi='ifconfig wlan0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1'
|
|
||||||
alias showmac-wifi='ifconfig wlan0 | grep "HWaddr" | cut -dH -f2 | cut -c7-23'
|
|
||||||
alias ifreset='sudo rm /etc/udev/rules.d/70-persistent-net.rules; echo Interfaces removed. You should system-restart now.'
|
|
||||||
|
|
||||||
alias netatalk-stop="sudo /etc/init.d/netatalk stop; bonjour-off"
|
|
||||||
alias netatalk-start="sudo /etc/init.d/netatalk start; bonjour-on"
|
|
||||||
alias netatalk-restart="sudo /etc/init.d/netatalk restart; bonjour-on"
|
|
||||||
alias netatalk-off='sudo /etc/init.d/netatalk stop; bonjour-off; sudo update-rc.d -f netatalk remove &> /dev/null'
|
|
||||||
alias netatalk-on='sudo update-rc.d netatalk defaults &> /dev/null; bonjour-on; sudo /etc/init.d/netatalk restart'
|
|
||||||
|
|
||||||
alias bonjour-off="sudo mv /etc/avahi/services/afpd.service /etc/avahi/services/afpd.service_disabled &> /dev/null"
|
|
||||||
alias bonjour-on="sudo mv /etc/avahi/services/afpd.service_disabled /etc/avahi/services/afpd.service &> /dev/null"
|
|
||||||
|
|
||||||
|
|
||||||
alias netatalk-router-on='sudo sed -i '"'"'s/^eth0.*$/eth0 -router -phase 2 -net 1 -zone "A2SERVER"/'"'"' /usr/local/etc/netatalk/atalkd.conf; sudo sed -i '"'"'s/^wlan0.*$/wlan0 -router -phase 2 -net 1 -zone "A2SERVER"/'"'"' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
|
||||||
alias netatalk-router-off='sudo sed -i '"'"'s/^eth0.*$/eth0/'"'"' /usr/local/etc/netatalk/atalkd.conf; sudo sed -i '"'"'s/^wlan0.*$/wlan0/'"'"' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
|
||||||
|
|
||||||
|
|
||||||
alias netatalk-eth='sudo sed -i 's/^wlan0/eth0/' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
|
||||||
alias netatalk-wifi='sudo sed -i 's/^eth0/wlan0/' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
alias appletalk-off='sudo sed -i "s/ATALKD_RUN=yes/ATALKD_RUN=no/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart'
|
|
||||||
alias appletalk-on='sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart'
|
|
||||||
|
|
||||||
|
|
||||||
NETATALK="/usr/local/etc/netatalk"
|
|
||||||
A2FILES="/srv/A2SERVER/A2FILES"
|
|
||||||
GSFILES="/srv/A2SERVER/GSFILES"
|
|
||||||
|
|
||||||
alias netboot-gsos="mkatinit -gs -d -f"
|
|
||||||
alias netboot-gsos-guest="mkatinit -gs -d -f guest"
|
|
||||||
alias netboot-p8="mkatinit -d -f"
|
|
||||||
alias netboot-p8-guest="mkatinit -d -f guest"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
alias guest-off="sudo sed -i 's/uams_guest.so,//' /usr/local/etc/netatalk/afpd.conf; [[ -f /etc/samba/smb.conf ]] && sudo sed -i 's/^ guest ok = yes/ guest ok = no/' /etc/samba/smb.conf; sudo /etc/init.d/netatalk restart"
|
|
||||||
alias guest-on="sudo sed -i 's/-uamlist uams_clrtxt.so/-uamlist uams_guest.so,uams_clrtxt.so/' /usr/local/etc/netatalk/afpd.conf; [[ -f /etc/samba/smb.conf ]] && sudo sed -i 's/^ guest ok = no/ guest ok = yes/' /etc/samba/smb.conf; sudo /etc/init.d/netatalk restart"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
alias samba-off='[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && { sudo initctl stop smbd; sudo initctl stop nmbd; [[ -f /etc/init/smbd.conf ]] && sudo mv /etc/init/smbd.conf /etc/init/smbd.conf.off; [[ -f /etc/init/nmbd.conf ]] && sudo mv /etc/init/nmbd.conf /etc/init/nmbd.conf.off; } || { sudo /etc/init.d/samba stop; sudo update-rc.d -f samba remove &> /dev/null; }'
|
|
||||||
alias samba-on='[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && { [[ -f /etc/init/smbd.conf.off ]] && sudo mv /etc/init/smbd.conf.off /etc/init/smbd.conf; [[ -f /etc/init/nmbd.conf.off ]] && sudo mv /etc/init/nmbd.conf.off /etc/init/nmbd.conf; sudo initctl start smbd; sudo initctl start nmbd; } || { sudo update-rc.d samba defaults &> /dev/null; sudo /etc/init.d/samba restart; }'
|
|
||||||
alias samba-stop='[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && { sudo initctl stop smbd; sudo initctl stop nmbd; } || { sudo /etc/init.d/samba stop; }'
|
|
||||||
alias samba-start='[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && { sudo initctl start smbd; sudo initctl start nmbd; } || { sudo /etc/init.d/samba start; }'
|
|
||||||
alias samba-restart='[[ $(lsb_release -d 2> /dev/null | grep Ubuntu) ]] && { sudo initctl restart smbd; sudo initctl restart nmbd; } || { sudo /etc/init.d/samba restart; }'
|
|
||||||
|
|
||||||
alias gsfiles-share="sudo sed -i 's/^\/media\/A2SHARED\/GSFILES\ GSFILES options:prodos/#share1/' /usr/local/etc/netatalk/AppleVolumes.default"
|
|
||||||
alias gsfiles-unshare="sudo sed -i 's/^#share1/\/media\/A2SHARED\/GSFILES\ GSFILES options:prodos/' /usr/local/etc/netatalk/AppleVolumes.default; [[ -d /srv/A2SERVER/GSFILES ]] || mkdir /srv/A2SERVER/GSFILES"
|
|
||||||
alias a2files-share="sudo sed -i 's/^\/media\/A2SHARED\/A2FILES\ A2FILES options:prodos\ casefold:toupper/#share2/' /usr/local/etc/netatalk/AppleVolumes.default"
|
|
||||||
alias a2files-unshare="sudo sed -i 's/^#share2/\/media\/A2SHARED\/A2FILES\ A2FILES options:prodos\ casefold:toupper/' /usr/local/etc/netatalk/AppleVolumes.default; [[ -d /srv/A2SERVER/A2FILES ]] || mkdir /srv/A2SERVER/A2FILES"
|
|
||||||
|
|
||||||
alias showalias="alias | cut -d= -f 1 | cut -d' ' -f2 | more"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
@@ -1,86 +0,0 @@
|
|||||||
A2SERVER commands:
|
|
||||||
(note: new commands may be added; use a2server-setup to refresh)
|
|
||||||
|
|
||||||
a2server-help: show this list of commands
|
|
||||||
a2server-setup: set up network boot, Windows access, Farallon fix,
|
|
||||||
refresh command list
|
|
||||||
a2server-version: see installed version of A2SERVER
|
|
||||||
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
|
|
||||||
|
|
||||||
welcome-message-edit: change the welcome message
|
|
||||||
|
|
||||||
showip: show the current ethernet IP address of the server
|
|
||||||
showmac: show the MAC (Ethernet hardware) address of the server
|
|
||||||
showip-wifi: show the current wifi IP address of the server
|
|
||||||
showmac-wifi: show the MAC (wifi hardware) address of the server
|
|
||||||
ifreset: reset all network interfaces (requires restart)
|
|
||||||
|
|
||||||
netatalk-stop: stop the netatalk service until reboot
|
|
||||||
netatalk-start: start the netatalk service
|
|
||||||
netatalk-restart: restart the netatalk service
|
|
||||||
netatalk-off: disable the netatalk service (even after reboot)
|
|
||||||
netatalk-on: enable the netatalk service
|
|
||||||
|
|
||||||
bonjour-off: disable advertisement of shared folders to OS X
|
|
||||||
bonjour-on : enable advertisement of shared folders to OS X
|
|
||||||
(these are automatically set by the netatalk commands above)
|
|
||||||
|
|
||||||
netatalk-router-on: use netatalk in router mode (default)
|
|
||||||
netatalk-router-off: use netatalk in node mode
|
|
||||||
(use if there is an AppleTalk router such as a GatorBox present)
|
|
||||||
|
|
||||||
netatalk-eth: use wired ethernet interface for netatalk (default)
|
|
||||||
netatalk-wifi: use wifi interface for netatalk
|
|
||||||
note: if an interface isn't available, netatalk will be reset with
|
|
||||||
router mode off; use "netatalk-router-on" to correct this if needed
|
|
||||||
|
|
||||||
appletalk-off: disable AppleTalk networking (even after reboot)
|
|
||||||
appletalk-on : enable AppleTalk networking
|
|
||||||
|
|
||||||
environment variables:
|
|
||||||
$NETATALK: directory containing netatalk configuration files
|
|
||||||
$A2FILES : directory containing A2FILES shared volume
|
|
||||||
$GSFILES : directory containing GSFILES shared volume
|
|
||||||
|
|
||||||
netboot-gsos: set the current user to netboot into GS/OS (default)
|
|
||||||
netboot-gsos-guest: set guests to netboot into GS/OS
|
|
||||||
netboot-p8: set the current user to netboot into ProDOS 8
|
|
||||||
netboot-p8-guest: set guests to netboot into ProDOS 8 (default)
|
|
||||||
note: when a IIgs is set to network boot into GS/OS, using the Network
|
|
||||||
control panel or the NETBOOT.GSOS utility, guests will behave like
|
|
||||||
registered users, and ignore the netboot setting of the guest user
|
|
||||||
|
|
||||||
guest-off: disallow guest access to A2SERVER
|
|
||||||
guest-on: allow guest access to A2SERVER (default)
|
|
||||||
note: by default, Guest access is the only way to network boot into
|
|
||||||
ProDOS 8. For registered user boot into ProDOS 8, type "netboot-p8"
|
|
||||||
|
|
||||||
samba-off: disable Windows file sharing (even after reboot)
|
|
||||||
samba-on: enable Windows file Sharing
|
|
||||||
samba-stop: stop Windows file sharing until reboot
|
|
||||||
samba-start: start Windows file sharing
|
|
||||||
samba-restart: stop and restart Windows file sharing
|
|
||||||
|
|
||||||
gsfiles-share: disable the GSFILES shared volume
|
|
||||||
gsfiles-unshare: enable the GSFILES shared volume
|
|
||||||
a2files-share: disable the A2FILES shared volume
|
|
||||||
a2files-unshare: enable the A2FILES shared volume
|
|
||||||
|
|
||||||
nulib2: create, extract, and work with NuFX (ShrinkIt) archive files
|
|
||||||
unar: extract other archive files (multiformat)
|
|
||||||
lsar: list contents of other archive files (multiformat)
|
|
||||||
|
|
||||||
afptype: set the ProDOS type/auxtype or Mac OS type/creator of a file
|
|
||||||
afpsync: register files introduced outside of AFP with netatalk
|
|
||||||
mkatinit: set up network boot configuration files
|
|
||||||
cppo: catalog and copy files from ProDOS image file (slow, but works)
|
|
||||||
(add -h to show help for the above four commands, e.g. "afptype -h")
|
|
||||||
|
|
@@ -1,114 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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 /media 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=$(echo $result | wc -l)
|
|
||||||
[[ $(echo $result | wc -w) == 0 ]] && f=0
|
|
||||||
[[ f -eq 1 && $(echo $result | grep APPLEDESKTOP) && $(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."
|
|
||||||
[[ ! $renameLower ]] && echo "Ensure filenames are all caps 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."
|
|
||||||
echo "Use afpsync -r to rename lowercase names to uppercase."
|
|
||||||
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)
|
|
||||||
processPath
|
|
||||||
else
|
|
||||||
grep ^/media /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,498 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
|
|
||||||
readcharDec () {
|
|
||||||
# read one character from file & convert to equivalent decimal value
|
|
||||||
# arg1: filename
|
|
||||||
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
||||||
# out: decimal value from 0-255
|
|
||||||
# exit: 8=extraneous arg, 11=missing arg1,
|
|
||||||
# 21=invalid arg1, 22=invalid arg2
|
|
||||||
[[ $1 ]] || return 11
|
|
||||||
[[ $3 ]] && return 8
|
|
||||||
[[ -f $1 ]] || return 21
|
|
||||||
[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \
|
|
||||||
&& ( $2 -ge 0 ) ]] || return 22; }
|
|
||||||
# args are valid
|
|
||||||
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
|
||||||
count=1 2> /dev/null; echo -n X)"
|
|
||||||
[[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; }
|
|
||||||
echo -n "${charX:0:1}" | od -t u1 | \
|
|
||||||
head -1 | sed 's/[0\ ]*//' | tr -d ' \n'
|
|
||||||
}
|
|
||||||
|
|
||||||
readcharHex () {
|
|
||||||
# read one character from file & convert to corresponding hex value
|
|
||||||
# arg1: filename
|
|
||||||
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
||||||
# out: two-digit hex value from 00-FF
|
|
||||||
# exit: 8=extraneous arg, 11=missing arg1,
|
|
||||||
# 21=invalid arg1, 22=invalid arg2
|
|
||||||
[[ $1 ]] || return 11
|
|
||||||
[[ $3 ]] && return 8
|
|
||||||
[[ -f $1 ]] || return 21
|
|
||||||
[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \
|
|
||||||
&& ( $2 -ge 0 ) ]] || return 22; }
|
|
||||||
# args are valid
|
|
||||||
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
|
||||||
count=1 2> /dev/null; echo -n X)"
|
|
||||||
[[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; }
|
|
||||||
printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \
|
|
||||||
head -1 | sed 's/[0\ ]*//' | tr -d ' \n')
|
|
||||||
}
|
|
||||||
|
|
||||||
### 2-15-11 above tested on OS X and Linux
|
|
||||||
|
|
||||||
writechars () {
|
|
||||||
# write one or more characters (bytes) to file
|
|
||||||
# arg1: filename
|
|
||||||
# arg2: (optional) offset (# of bytes to skip before writing)
|
|
||||||
# arg3 OR stdin: sequence of characters
|
|
||||||
# [stdin required if writing NUL (0) or trailing LF (0x0A) chars]
|
|
||||||
# out: nothing
|
|
||||||
# exit: 8=extraneous arg, 11=missing arg1,
|
|
||||||
# 13=missing stdin/arg3, 22=invalid arg2
|
|
||||||
[[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; }
|
|
||||||
[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \
|
|
||||||
( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } }
|
|
||||||
[[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; }
|
|
||||||
[[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; }
|
|
||||||
# args are valid
|
|
||||||
if [[ -t 0 ]]; then
|
|
||||||
echo -n "$3" | \
|
|
||||||
dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
|
|
||||||
else
|
|
||||||
dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
writecharDec () {
|
|
||||||
# write corresponding character of single-byte decimal value into file
|
|
||||||
# arg1: filename
|
|
||||||
# arg2: offset (# of bytes to skip before writing)
|
|
||||||
# arg3: decimal number from 0-255
|
|
||||||
# exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2,
|
|
||||||
# 13=missing arg3, 22=invalid arg2, 23=invalid arg3
|
|
||||||
# out: nothing
|
|
||||||
[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13
|
|
||||||
[[ $4 ]] && return 8
|
|
||||||
[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \
|
|
||||||
&& ( $2 -ge 0 ) ]] || return 22
|
|
||||||
[[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \
|
|
||||||
&& ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23
|
|
||||||
# args are valid
|
|
||||||
echo -n -e "\x$(printf %02X "$3")" | \
|
|
||||||
dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
writecharHex () {
|
|
||||||
# write corresponding character of single-byte hex value into file
|
|
||||||
# arg1: filename
|
|
||||||
# arg2: offset (# of bytes to skip before writing)
|
|
||||||
# arg3: two-digit hexadecimal number from 00-FF
|
|
||||||
# out: nothing
|
|
||||||
# exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2,
|
|
||||||
# 13=missing arg3, 22=invalid arg2, 23=invalid arg3
|
|
||||||
[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13
|
|
||||||
[[ $4 ]] && return 8
|
|
||||||
[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \
|
|
||||||
&& ( $2 -ge 0 ) ]] || return 22
|
|
||||||
[[ $(printf %02X "0x$3" 2> /dev/null) == \
|
|
||||||
$(echo -n "$3" | tr [a-z] [A-Z]) ]] || return 23
|
|
||||||
# args are valid
|
|
||||||
echo -n -e "\x$3" | \
|
|
||||||
dd of="$1" bs=1 seek=$2 conv=notrunc 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# --- 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,882 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
"""cppo: Copy or catalog one or all files from a ProDOS raw disk image.
|
|
||||||
|
|
||||||
copy all files:
|
|
||||||
cppo [-ad|-e] imagefile target_directory
|
|
||||||
copy one file:
|
|
||||||
cppo [-ad|-e] imagefile /FULL/PRODOS/FILE/PATH target_path
|
|
||||||
catalog image:
|
|
||||||
cppo -cat imagefile
|
|
||||||
|
|
||||||
-ad : Create AppleDouble header files and preserve resource forks.
|
|
||||||
-e : Append ProDOS type and auxtype to filenames, and copy resource
|
|
||||||
forks, for adding to ShrinkIt archives with Nulib2
|
|
||||||
using its -e option.
|
|
||||||
|
|
||||||
Wildcard matching/globbing (*) is not supported.
|
|
||||||
No verification or validation of the disk image is performed.
|
|
||||||
|
|
||||||
(Compatible with Python 2.6 and later, including 3.x.)
|
|
||||||
"""
|
|
||||||
|
|
||||||
# cppo by Ivan X, ivan@ivanx.com, ivanx.com/appleii
|
|
||||||
|
|
||||||
# If anyone's looking at this, and feels it's not sufficiently Pythonic,
|
|
||||||
# I know that. It's pretty much a line-for-line conversion of the original
|
|
||||||
# Bash script. I did start a beautiful from-the-ground-up object-oriented
|
|
||||||
# version, then realized it would be faster to translate it ugly and quick.
|
|
||||||
|
|
||||||
# imports for python 3 code compatibility
|
|
||||||
from __future__ import print_function
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
# Intentially fails on pre-2.6 so user can see what's wrong
|
|
||||||
b'ERROR: cppo requires Python 2.6 or later, including 3.x.'
|
|
||||||
|
|
||||||
class Globals(object):
|
|
||||||
pass
|
|
||||||
|
|
||||||
g = Globals()
|
|
||||||
|
|
||||||
g.imageData = b''
|
|
||||||
g.outFileData = bytearray(b'')
|
|
||||||
g.adFileData = bytearray(b'')
|
|
||||||
g.exFileData = bytearray(b'')
|
|
||||||
|
|
||||||
g.activeDirBlock = None
|
|
||||||
g.activeFileName = None
|
|
||||||
g.activeFileSize = None
|
|
||||||
g.activeFileBytesCopied = 0
|
|
||||||
g.resourceFork = 0
|
|
||||||
|
|
||||||
g.PDOSPATH = []
|
|
||||||
g.PDOSPATH_INDEX = 0
|
|
||||||
g.PDOSPATH_SEGMENT = None
|
|
||||||
g.DIRPATH = ""
|
|
||||||
|
|
||||||
g.targetName = None
|
|
||||||
g.targetDir = ""
|
|
||||||
g.ADdir = None
|
|
||||||
g.imageFile = None
|
|
||||||
|
|
||||||
g.AD = 0
|
|
||||||
g.EX = 0
|
|
||||||
g.DIR = 0
|
|
||||||
g.silent = 0
|
|
||||||
|
|
||||||
# functions
|
|
||||||
|
|
||||||
def pdosDateToUnixDate(arg1):
|
|
||||||
# input: ProDOS date/time bit sequence string in format:
|
|
||||||
# "yyyyyyymmmmddddd000hhhhh00mmmmmm" (ustr)
|
|
||||||
# output: seconds since Unix epoch (1-Jan-1970),
|
|
||||||
# or current date/time if no ProDOS date
|
|
||||||
year = (binToDec(slyce(arg1,0,7)) + 1900)
|
|
||||||
if (year < 1940): year += 100
|
|
||||||
month = binToDec(slyce(arg1,7,4))
|
|
||||||
day = binToDec(slyce(arg1,11,5))
|
|
||||||
hour = binToDec(slyce(arg1,19,5))
|
|
||||||
minute = binToDec(slyce(arg1,26,6))
|
|
||||||
# print(year, month, day, hour, minute)
|
|
||||||
td = (datetime.datetime(year, month, day, hour, minute) -
|
|
||||||
datetime.datetime(1970,1,1))
|
|
||||||
unixDate_naive = (td.days*24*60*60 + td.seconds)
|
|
||||||
td2 = (datetime.datetime.fromtimestamp(unixDate_naive) -
|
|
||||||
datetime.datetime.utcfromtimestamp(unixDate_naive))
|
|
||||||
utcoffset = (td2.days*24*60*60 + td2.seconds)
|
|
||||||
# print(unixDate_naive - utcoffset)
|
|
||||||
return (unixDate_naive - utcoffset) # local time zone with DST
|
|
||||||
|
|
||||||
def unixDateToADDate(arg1):
|
|
||||||
# input: seconds since Unix epoch (1-Jan-1970 00:00:00 GMT)
|
|
||||||
# output: seconds since Netatalk epoch (1-Jan-2000 00:00:00 GMT),
|
|
||||||
# in hex-ustr (big endian)
|
|
||||||
adDate = (arg1 - 946684800)
|
|
||||||
if (adDate < 0 ):
|
|
||||||
adDate += 4294967296 # to get negative hex number
|
|
||||||
adDateHex = to_hex(adDate).zfill(8).upper()
|
|
||||||
# print(arg1, adDate, adDateHex)
|
|
||||||
return adDateHex
|
|
||||||
|
|
||||||
# cppo support routines:
|
|
||||||
# arg1: directory block
|
|
||||||
# arg2: file index (if applicable)
|
|
||||||
# arg3: directory chunk # (if applicable)
|
|
||||||
|
|
||||||
#most of these not tested yet in Python
|
|
||||||
# returns byte position in disk image file
|
|
||||||
def getStartPos(arg1, arg2):
|
|
||||||
return ( (arg1 * 512) +
|
|
||||||
(39 * ((arg2 + (arg2 > 11)) % 13)) +
|
|
||||||
(4 if (arg2 > 11) else 43) )
|
|
||||||
|
|
||||||
def getStorageType(arg1, arg2):
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
firstByte = readcharDec(g.imageData, start)
|
|
||||||
return (firstByte//16)
|
|
||||||
|
|
||||||
def getFileName(arg1, arg2):
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
firstByte = readcharDec(g.imageData, start)
|
|
||||||
entryType = (firstByte//16)
|
|
||||||
nameLength = (firstByte - entryType*16)
|
|
||||||
return readchars(g.imageData, start+1, nameLength)
|
|
||||||
|
|
||||||
def getFileType(arg1, arg2):
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
return readcharHex(g.imageData, start+16)
|
|
||||||
|
|
||||||
def getKeyPointer(arg1, arg2):
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
return (readcharDec(g.imageData, start+17) +
|
|
||||||
readcharDec(g.imageData, start+18)*256)
|
|
||||||
|
|
||||||
def getFileLength(arg1, arg2):
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
return (readcharDec(g.imageData, start+21) +
|
|
||||||
readcharDec(g.imageData, start+22)*256 +
|
|
||||||
readcharDec(g.imageData, start+23)*65536)
|
|
||||||
|
|
||||||
def getAuxType(arg1, arg2):
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
return (readcharHex(g.imageData, start+32) +
|
|
||||||
readcharHex(g.imageData, start+31))
|
|
||||||
|
|
||||||
def getCreationDate(arg1, arg2):
|
|
||||||
#outputs prodos creation date/time as Unix time
|
|
||||||
# (seconds since Jan 1 1970 GMT)
|
|
||||||
#or None if there is none
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
pdosDate = (hexToBin(readcharHex(g.imageData, start+25)) +
|
|
||||||
hexToBin(readcharHex(g.imageData, start+24)) +
|
|
||||||
hexToBin(readcharHex(g.imageData, start+27)) +
|
|
||||||
hexToBin(readcharHex(g.imageData, start+26)))
|
|
||||||
try:
|
|
||||||
rVal = pdosDateToUnixDate(pdosDate)
|
|
||||||
except Exception:
|
|
||||||
rVal = None
|
|
||||||
return rVal
|
|
||||||
|
|
||||||
def getModifiedDate(arg1, arg2):
|
|
||||||
#outputs prodos modified date/time as Unix time
|
|
||||||
# (seconds since Jan 1 1970 GMT)
|
|
||||||
#or None if there is none
|
|
||||||
start = getStartPos(arg1, arg2)
|
|
||||||
pdosDate = (hexToBin(readcharHex(g.imageData, start+34)) +
|
|
||||||
hexToBin(readcharHex(g.imageData, start+33)) +
|
|
||||||
hexToBin(readcharHex(g.imageData, start+36)) +
|
|
||||||
hexToBin(readcharHex(g.imageData, start+35)))
|
|
||||||
try:
|
|
||||||
rVal = pdosDateToUnixDate(pdosDate)
|
|
||||||
except Exception:
|
|
||||||
rVal = None
|
|
||||||
return rVal
|
|
||||||
|
|
||||||
def getVolumeName():
|
|
||||||
return getWorkingDirName(2)
|
|
||||||
|
|
||||||
def getWorkingDirName(arg1):
|
|
||||||
start = ( arg1 * 512 )
|
|
||||||
firstByte = readcharDec(g.imageData, start+4)
|
|
||||||
entryType = (firstByte//16)
|
|
||||||
nameLength = (firstByte - entryType*16)
|
|
||||||
return readchars(g.imageData, start+5, nameLength)
|
|
||||||
|
|
||||||
def getDirEntryCount(arg1):
|
|
||||||
start = ( arg1 * 512 )
|
|
||||||
return (readcharDec(g.imageData, start+37) +
|
|
||||||
readcharDec(g.imageData, start+38)*256)
|
|
||||||
|
|
||||||
def getDirNextChunkPointer(arg1):
|
|
||||||
start = ( arg1 * 512 )
|
|
||||||
return (readcharDec(g.imageData, start+2) +
|
|
||||||
readcharDec(g.imageData, start+3)*256)
|
|
||||||
|
|
||||||
# -- script begins in earnest here
|
|
||||||
|
|
||||||
def copyFile(arg1, arg2):
|
|
||||||
g.outFileData = bytearray(b'')
|
|
||||||
g.exFileData = bytearray(b'')
|
|
||||||
g.activeFileBytesCopied = 0
|
|
||||||
storageType = getStorageType(arg1, arg2)
|
|
||||||
keyPointer = getKeyPointer(arg1, arg2)
|
|
||||||
fileLen = getFileLength(arg1, arg2)
|
|
||||||
if (storageType == 1): #seedling
|
|
||||||
copyBlock(keyPointer, fileLen)
|
|
||||||
elif (storageType == 2): #sapling
|
|
||||||
processIndexBlock(keyPointer)
|
|
||||||
elif (storageType == 3): #tree
|
|
||||||
processMasterIndexBlock(keyPointer)
|
|
||||||
elif (storageType == 5): #extended (forked)
|
|
||||||
processForkedFile(keyPointer)
|
|
||||||
|
|
||||||
def copyBlock(arg1, arg2):
|
|
||||||
#arg1: block to copy
|
|
||||||
#arg2: bytes to write (should be 512,
|
|
||||||
# unless final block with less than 512 bytes)
|
|
||||||
#print(arg1 + " " + arg2 + " " + g.activeFileBytesCopied)
|
|
||||||
if (arg1 == 0):
|
|
||||||
outBytes = (b'\x00' * arg2)
|
|
||||||
else:
|
|
||||||
outBytes = slyce(g.imageData, arg1*512, arg2)
|
|
||||||
if (g.resourceFork > 0):
|
|
||||||
if g.AD:
|
|
||||||
g.adFileData[g.activeFileBytesCopied+741:
|
|
||||||
(g.activeFileBytesCopied+741 + arg2)] = outBytes
|
|
||||||
if g.EX:
|
|
||||||
g.exFileData[g.activeFileBytesCopied:
|
|
||||||
(g.activeFileBytesCopied + arg2)] = outBytes
|
|
||||||
else:
|
|
||||||
g.outFileData[g.activeFileBytesCopied:
|
|
||||||
(g.activeFileBytesCopied + arg2)] = outBytes
|
|
||||||
g.activeFileBytesCopied += arg2
|
|
||||||
|
|
||||||
def processDir(arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
|
||||||
# arg1: dirBlock
|
|
||||||
# arg2/3/4/5: for non-key chunks: entryCount, entry#,
|
|
||||||
# workingDirName, processedEntryCount
|
|
||||||
|
|
||||||
entryCount = None
|
|
||||||
e = None
|
|
||||||
pe = None
|
|
||||||
workingDirName = None
|
|
||||||
|
|
||||||
if arg2:
|
|
||||||
entryCount = arg2
|
|
||||||
e = arg3
|
|
||||||
workingDirName = arg4
|
|
||||||
pe = arg5
|
|
||||||
else:
|
|
||||||
e = 0
|
|
||||||
pe = 0
|
|
||||||
entryCount = getDirEntryCount(arg1)
|
|
||||||
workingDirName = getWorkingDirName(arg1).decode("L1")
|
|
||||||
g.DIRPATH = (g.DIRPATH + "/" + workingDirName)
|
|
||||||
if g.PDOSPATH_INDEX:
|
|
||||||
if (g.PDOSPATH_INDEX == 1):
|
|
||||||
if (("/" + g.PDOSPATH_SEGMENT) != g.DIRPATH):
|
|
||||||
print("ProDOS volume name does not match disk image.")
|
|
||||||
sys.exit(2)
|
|
||||||
else:
|
|
||||||
g.PDOSPATH_INDEX += 1
|
|
||||||
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
|
||||||
else:
|
|
||||||
print(g.DIRPATH)
|
|
||||||
while (pe < entryCount):
|
|
||||||
if (getStorageType(arg1, e) > 0):
|
|
||||||
processEntry(arg1, e)
|
|
||||||
pe += 1
|
|
||||||
e += 1
|
|
||||||
if not ((e + ( e>11 ) ) % 13):
|
|
||||||
processDir(getDirNextChunkPointer(arg1),
|
|
||||||
entryCount,
|
|
||||||
e,
|
|
||||||
workingDirName,
|
|
||||||
pe)
|
|
||||||
break
|
|
||||||
|
|
||||||
def processEntry(arg1, arg2):
|
|
||||||
'''
|
|
||||||
print(getFileName(arg1, arg2), getStorageType(arg1, arg2),
|
|
||||||
getFileType(arg1, arg2), getKeyPointer(arg1, arg2),
|
|
||||||
getFileLength(arg1, arg2), getAuxType(arg1, arg2),
|
|
||||||
getCreationDate(arg1, arg2), getModifiedDate(arg1, arg2))
|
|
||||||
'''
|
|
||||||
g.activeFileName = getFileName(arg1 ,arg2).decode("L1")
|
|
||||||
g.activeFileSize = getFileLength(arg1, arg2)
|
|
||||||
|
|
||||||
if ((not g.PDOSPATH_INDEX) or (g.activeFileName == g.PDOSPATH_SEGMENT)):
|
|
||||||
|
|
||||||
if (getStorageType(arg1, arg2) == 13): # if ProDOS directory
|
|
||||||
if not g.PDOSPATH_INDEX:
|
|
||||||
g.targetDir = (g.targetDir + "/" + g.activeFileName)
|
|
||||||
g.ADdir = (g.targetDir + "/.AppleDouble")
|
|
||||||
if not (g.DIR or os.path.isdir(g.targetDir)):
|
|
||||||
makedirs(g.targetDir)
|
|
||||||
if not (g.DIR or (not g.AD) or os.path.isdir(g.ADdir)):
|
|
||||||
makedirs(g.ADdir)
|
|
||||||
if g.PDOSPATH_SEGMENT:
|
|
||||||
g.PDOSPATH_INDEX += 1
|
|
||||||
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
|
||||||
processDir(getKeyPointer(arg1, arg2))
|
|
||||||
g.DIRPATH = g.DIRPATH.rsplit("/", 1)[0]
|
|
||||||
if not g.PDOSPATH_INDEX:
|
|
||||||
g.targetDir = g.targetDir.rsplit("/", 1)[0]
|
|
||||||
g.ADdir = (g.targetDir + "/.AppleDouble")
|
|
||||||
else: # if ProDOS file
|
|
||||||
if not g.PDOSPATH_INDEX:
|
|
||||||
print(" " + g.activeFileName)
|
|
||||||
if g.DIR:
|
|
||||||
return
|
|
||||||
if not g.targetName:
|
|
||||||
g.targetName = g.activeFileName
|
|
||||||
if g.EX:
|
|
||||||
eTargetName = (g.targetName + "#" +
|
|
||||||
getFileType(arg1, arg2).lower() +
|
|
||||||
getAuxType(arg1, arg2).lower())
|
|
||||||
touch(g.targetDir + "/" + g.targetName)
|
|
||||||
if g.AD: makeADfile()
|
|
||||||
copyFile(arg1, arg2)
|
|
||||||
saveFile((g.targetDir + "/" + g.targetName), g.outFileData)
|
|
||||||
creationDate = getCreationDate(arg1, arg2)
|
|
||||||
modifiedDate = getModifiedDate(arg1, arg2)
|
|
||||||
if (creationDate is None and modifiedDate is not None):
|
|
||||||
creationDate = modifiedDate
|
|
||||||
elif (creationDate is not None and modifiedDate is None):
|
|
||||||
modifiedDate = creationDate
|
|
||||||
elif (creationDate is None and modifiedDate is None):
|
|
||||||
creationDate = (datetime.datetime.today() -
|
|
||||||
datetime.datetime(1970,1,1)).days*24*60*60
|
|
||||||
modifiedDate = creationDate
|
|
||||||
if g.AD: # AppleDouble
|
|
||||||
# set dates
|
|
||||||
ADfilePath = (g.ADdir + "/" + g.targetName)
|
|
||||||
writecharsHex(g.adFileData,
|
|
||||||
637,
|
|
||||||
(unixDateToADDate(creationDate) +
|
|
||||||
unixDateToADDate(modifiedDate)))
|
|
||||||
writecharHex(g.adFileData, 645, "80")
|
|
||||||
writecharHex(g.adFileData, 649, "80")
|
|
||||||
#set type/creator
|
|
||||||
writechars(g.adFileData, 653, b'p')
|
|
||||||
writecharsHex(g.adFileData,
|
|
||||||
654,
|
|
||||||
(getFileType(arg1, arg2) +
|
|
||||||
getAuxType(arg1, arg2)))
|
|
||||||
writechars(g.adFileData, 657, b'pdos')
|
|
||||||
saveFile(ADfilePath, g.adFileData)
|
|
||||||
touch((g.targetDir + "/" + g.targetName), modifiedDate)
|
|
||||||
if g.EX: # extended name
|
|
||||||
os.rename((g.targetDir + "/" + g.targetName),
|
|
||||||
(g.targetDir + "/" + eTargetName))
|
|
||||||
if (len(g.exFileData) > 0):
|
|
||||||
saveFile((g.targetDir + "/" + eTargetName + "r"),
|
|
||||||
g.exFileData)
|
|
||||||
touch((g.targetDir + "/" + eTargetName + "r"),
|
|
||||||
modifiedDate)
|
|
||||||
if g.PDOSPATH_SEGMENT:
|
|
||||||
syncExit()
|
|
||||||
g.targetName = None
|
|
||||||
|
|
||||||
#else:
|
|
||||||
#print(g.activeFileName + " doesn't match " + g.PDOSPATH_SEGMENT)
|
|
||||||
|
|
||||||
def processForkedFile(arg1):
|
|
||||||
# finder info except type/creator
|
|
||||||
fInfoA_entryType = readcharDec(g.imageData, 9)
|
|
||||||
fInfoB_entryType = readcharDec(g.imageData, 27)
|
|
||||||
if (fInfoA_entryType == 1):
|
|
||||||
writechars(g.imageData, 661, readchars(g.imageData, 18, 8))
|
|
||||||
elif (fInfoA_entryType == 2):
|
|
||||||
writechars(g.imageData, 669, readchars(g.imageData, 10, 16))
|
|
||||||
if (fInfoB_entryType == 1):
|
|
||||||
writechars(g.imageData, 661, readchars(g.imageData, 36, 8))
|
|
||||||
elif (fInfoB_entryType == 2):
|
|
||||||
writechars(g.imageData, 669, readchars(g.imageData, 28, 16))
|
|
||||||
|
|
||||||
for f in [0, 256]:
|
|
||||||
g.resourceFork = f
|
|
||||||
g.activeFileBytesCopied = 0
|
|
||||||
forkStart = (arg1 * 512) # start of Forked File key block
|
|
||||||
# print("--" + forkStart)
|
|
||||||
forkStorageType = readcharDec(g.imageData, forkStart+f+0)
|
|
||||||
forkKeyPointer = (readcharDec(g.imageData, forkStart+f+1) +
|
|
||||||
readcharDec(g.imageData, forkStart+f+2)*256)
|
|
||||||
forkFileLen = (readcharDec(g.imageData, forkStart+f+5) +
|
|
||||||
readcharDec(g.imageData, forkStart+f+6)*256 +
|
|
||||||
readcharDec(g.imageData, forkStart+f+7)*256*256)
|
|
||||||
g.activeFileSize = forkFileLen
|
|
||||||
if (g.resourceFork > 0):
|
|
||||||
rsrcForkLenHex = (readcharHex(g.imageData, forkStart+f+7) +
|
|
||||||
readcharHex(g.imageData, forkStart+f+6) +
|
|
||||||
readcharHex(g.imageData, forkStart+f+5))
|
|
||||||
# print(">>>" + rsrcForkLenHex)
|
|
||||||
print(" [resource fork]")
|
|
||||||
if g.AD:
|
|
||||||
writecharsHex(g.adFileData, 35, rsrcForkLenHex)
|
|
||||||
else:
|
|
||||||
print(" [data fork]")
|
|
||||||
if (forkStorageType == 1): #seedling
|
|
||||||
copyBlock(forkKeyPointer, forkFileLen)
|
|
||||||
elif (forkStorageType == 2): #sapling
|
|
||||||
processIndexBlock(forkKeyPointer)
|
|
||||||
elif (forkStorageType == 3): #tree
|
|
||||||
processMasterIndexBlock(forkKeyPointer)
|
|
||||||
# print()
|
|
||||||
g.resourceFork = 0
|
|
||||||
|
|
||||||
def processMasterIndexBlock(arg1):
|
|
||||||
processIndexBlock(arg1, True)
|
|
||||||
|
|
||||||
def processIndexBlock(arg1, arg2=False):
|
|
||||||
#arg1: indexBlock
|
|
||||||
#arg2: if True, it's a Master Index Block
|
|
||||||
pos = 0
|
|
||||||
bytesRemaining = g.activeFileSize
|
|
||||||
while (g.activeFileBytesCopied < g.activeFileSize):
|
|
||||||
targetBlock = (readcharDec(g.imageData, arg1*512+pos) +
|
|
||||||
readcharDec(g.imageData, arg1*512+(pos+256))*256)
|
|
||||||
if arg2:
|
|
||||||
processIndexBlock(targetBlock)
|
|
||||||
else:
|
|
||||||
bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied)
|
|
||||||
bs = (bytesRemaining if (bytesRemaining < 512) else 512)
|
|
||||||
copyBlock(targetBlock, bs)
|
|
||||||
pos += 1
|
|
||||||
if (pos > 255):
|
|
||||||
break # go to next entry in Master Index Block (tree)
|
|
||||||
|
|
||||||
def makeADfile():
|
|
||||||
if not g.AD: return
|
|
||||||
touch(g.ADdir + "/" + g.targetName)
|
|
||||||
g.adFileData = bytearray(b'\x00' * 741)
|
|
||||||
# ADv2 header
|
|
||||||
writecharsHex(g.adFileData, hexToDec("00"), "0005160700020000")
|
|
||||||
# number of entries
|
|
||||||
writecharsHex(g.adFileData, hexToDec("18"), "000D")
|
|
||||||
# Resource Fork
|
|
||||||
writecharsHex(g.adFileData, hexToDec("1A"), "00000002000002E500000000")
|
|
||||||
# Real Name
|
|
||||||
writecharsHex(g.adFileData, hexToDec("26"), "00000003000000B600000000")
|
|
||||||
# Comment
|
|
||||||
writecharsHex(g.adFileData, hexToDec("32"), "00000004000001B500000000")
|
|
||||||
# Dates Info
|
|
||||||
writecharsHex(g.adFileData, hexToDec("3E"), "000000080000027D00000010")
|
|
||||||
# Finder Info
|
|
||||||
writecharsHex(g.adFileData, hexToDec("4A"), "000000090000028D00000020")
|
|
||||||
# ProDOS file info
|
|
||||||
writecharsHex(g.adFileData, hexToDec("56"), "0000000B000002C100000008")
|
|
||||||
# AFP short name
|
|
||||||
writecharsHex(g.adFileData, hexToDec("62"), "0000000D000002B500000000")
|
|
||||||
# AFP File Info
|
|
||||||
writecharsHex(g.adFileData, hexToDec("6E"), "0000000E000002B100000004")
|
|
||||||
# AFP Directory ID
|
|
||||||
writecharsHex(g.adFileData, hexToDec("7A"), "0000000F000002AD00000004")
|
|
||||||
# dbd (second time) will create DEV, INO, SYN, SV~
|
|
||||||
|
|
||||||
def syncExit():
|
|
||||||
if (not g.silent and g.AD and os.path.isdir("/usr/local/etc/netatalk")):
|
|
||||||
print("File(s) have been copied to the target directory. " +
|
|
||||||
"If the directory")
|
|
||||||
print("is shared by Netatalk, please type 'afpsync' now.")
|
|
||||||
# saveFile(g.imageFile, g.imageData)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def usage():
|
|
||||||
print(sys.modules[__name__].__doc__)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# --- ID bashbyter functions (adapted)
|
|
||||||
|
|
||||||
def decToHex(arg1):
|
|
||||||
# converts single-byte decimal value to hexadecimal equivalent
|
|
||||||
# arg: decimal value from 0-255
|
|
||||||
# out: two-digit hex string from 00-FF
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (arg1<0 or arg1>255): sys.exit(21)
|
|
||||||
return to_hex(arg1).upper()
|
|
||||||
|
|
||||||
def hexToDec(arg1):
|
|
||||||
# converts single-byte hexadecimal value to decimal equivalent
|
|
||||||
# arg: two-digit hex value from 00-FF
|
|
||||||
# out: decimal value
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (len(arg1) != 2): return 21
|
|
||||||
return to_dec(arg1)
|
|
||||||
|
|
||||||
def hexToBin(arg1):
|
|
||||||
# converts single-byte hexadecimal value to binary string
|
|
||||||
# arg: two-digit hex value from 00-FF
|
|
||||||
# out: binary string value
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (len(arg1) != 2): return 21
|
|
||||||
return to_bin(arg1).zfill(8)
|
|
||||||
|
|
||||||
def binToDec(arg1):
|
|
||||||
# converts single-byte binary string (8 bits) value to decimal
|
|
||||||
# warning: no error checking
|
|
||||||
# arg: binary string up to 8 bits
|
|
||||||
# out: decimal value
|
|
||||||
return to_dec([arg1])
|
|
||||||
|
|
||||||
def binToHex(arg1):
|
|
||||||
# converts single-byte binary string (8 bits) value to hex
|
|
||||||
# warning: no error checking
|
|
||||||
# arg: binary string up to 8 bits
|
|
||||||
# out: hex value
|
|
||||||
return to_hex(arg1).upper()
|
|
||||||
|
|
||||||
def charToDec(arg1):
|
|
||||||
# converts single char (of type bytes) to corresponding decimal value
|
|
||||||
# arg: one char (of type bytes)
|
|
||||||
# out: decimal value from 0-255
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (len(arg1) != 1): return 21
|
|
||||||
return to_dec(arg1)
|
|
||||||
|
|
||||||
def charToHex(arg1):
|
|
||||||
# converts single char (of type bytes) to corresponding hex value
|
|
||||||
# arg: one char (of type bytes)
|
|
||||||
# out: hexadecimal value from 00-FF
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (len(arg1) != 1): return 21
|
|
||||||
return to_hex(arg1).upper()
|
|
||||||
|
|
||||||
def decToChar(arg1):
|
|
||||||
# converts single-byte decimal value to equivalent char (of type bytes)
|
|
||||||
# arg: decimal number from 0-255
|
|
||||||
# out: one character
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (arg1<0 or arg1>255): sys.exit(21)
|
|
||||||
return to_bytes(arg1)
|
|
||||||
|
|
||||||
def hexToChar(arg1):
|
|
||||||
# converts single-byte hex value to corresponding char (of type bytes)
|
|
||||||
# arg: two-digit hexadecimal number from 00-FF
|
|
||||||
# out: one character
|
|
||||||
#exit: 21=invalid arg
|
|
||||||
if (len(arg1) != 2): return 21
|
|
||||||
return to_bytes(arg1)
|
|
||||||
|
|
||||||
def readchars(arg1, arg2=0, arg3=0):
|
|
||||||
# read one or more characters from a bytes variable
|
|
||||||
# arg1: bytes or bytearray variable
|
|
||||||
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
||||||
# arg3: (optional) # of chars to read (default is to end of bytes var)
|
|
||||||
# out: sequence of characters (bytes or bytearray)
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
|
|
||||||
if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)):
|
|
||||||
sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
if (arg3<0): sys.exit(23)
|
|
||||||
if (arg3 == 0):
|
|
||||||
arg3 = len(arg1)
|
|
||||||
return slyce(arg1, arg2, arg3)
|
|
||||||
|
|
||||||
def readcharDec(arg1, arg2=0):
|
|
||||||
# read one character from bytes var & convert to equivalent dec value
|
|
||||||
# arg1: bytes var
|
|
||||||
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
||||||
# out: decimal value from 0-255
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2
|
|
||||||
if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)):
|
|
||||||
sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
return to_dec(slyce(arg1, arg2, 1))
|
|
||||||
|
|
||||||
def readcharHex(arg1, arg2=0):
|
|
||||||
# read one character from bytes var & convert to corresponding hex value
|
|
||||||
# arg1: bytes var
|
|
||||||
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
||||||
# out: two-digit hex value from 00-FF
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2
|
|
||||||
if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)):
|
|
||||||
sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
return to_hex(slyce(arg1, arg2, 1))
|
|
||||||
|
|
||||||
def writechars(arg1, arg2, arg3):
|
|
||||||
# write one or more characters (bytes) to bytearray
|
|
||||||
# arg1: bytearray variable
|
|
||||||
# arg2: offset (# of bytes to skip before writing)
|
|
||||||
# arg3: sequence of bytes (or bytearray)
|
|
||||||
# out: nothing
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
|
|
||||||
if not isinstance(arg1, bytearray): sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
if not (isinstance(arg3, bytes) or isinstance(arg3, bytearray)):
|
|
||||||
sys.exit(23)
|
|
||||||
arg1[arg2:arg2+len(arg3)] = arg3
|
|
||||||
|
|
||||||
def writecharDec(arg1, arg2, arg3):
|
|
||||||
# write corresponding char of single-byte decimal value into bytearray
|
|
||||||
# arg1: bytearray
|
|
||||||
# arg2: offset (# of bytes to skip before writing)
|
|
||||||
# arg3: decimal number from 0-255
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
|
|
||||||
# out: nothing
|
|
||||||
if not isinstance(arg1, bytearray): sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
if not isnumber(arg3): sys.exit(23)
|
|
||||||
arg1[arg2:arg2+1] = to_bytes(arg3)
|
|
||||||
|
|
||||||
def writecharHex(arg1, arg2, arg3):
|
|
||||||
# write corresponding character of single-byte hex value into bytearray
|
|
||||||
# arg1: bytearray
|
|
||||||
# arg2: offset (# of bytes to skip before writing)
|
|
||||||
# arg3: two-digit hexadecimal number from 00-FF
|
|
||||||
# out: nothing
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
|
|
||||||
if not isinstance(arg1, bytearray): sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
if not isinstance(arg3, type("".encode().decode())): sys.exit(23)
|
|
||||||
arg1[arg2:arg2+1] = to_bytes(arg3)
|
|
||||||
|
|
||||||
def writecharsHex(arg1, arg2, arg3):
|
|
||||||
# write corresponding characters of hex values into bytearray
|
|
||||||
# arg1: bytearray
|
|
||||||
# arg2: offset (# of bytes to skip before writing)
|
|
||||||
# arg3: string of two-digit hexadecimal numbers from 00-FF
|
|
||||||
# out: nothing
|
|
||||||
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
|
|
||||||
if not isinstance(arg1, bytearray): sys.exit(21)
|
|
||||||
if (arg2<0): sys.exit(22)
|
|
||||||
if not isinstance(arg3, type("".encode().decode())): sys.exit(23)
|
|
||||||
arg1[arg2:arg2+len(to_bytes(arg3))] = to_bytes(arg3)
|
|
||||||
|
|
||||||
#---- IvanX general purpose functions ----#
|
|
||||||
|
|
||||||
def slyce(val, start_pos=0, length=1, reverse=False):
|
|
||||||
"""returns slice of object (but not a slice object)
|
|
||||||
allows specifying length, and 3.x "bytes" consistency"""
|
|
||||||
the_slyce = val[start_pos:start_pos+length]
|
|
||||||
return (the_slyce[::-1] if reverse else the_slyce)
|
|
||||||
|
|
||||||
def to_hex(val):
|
|
||||||
"""convert bytes, decimal number, or [bin-ustr] to two-digit hex values
|
|
||||||
unlike hex(), accepts bytes; has no leading 0x or trailing L"""
|
|
||||||
from binascii import b2a_hex
|
|
||||||
if isinstance(val, list): # [bin-ustr]
|
|
||||||
val = int(val[0], 2)
|
|
||||||
if isinstance(val, bytes): # bytes
|
|
||||||
return b2a_hex(val).decode("L1")
|
|
||||||
elif isnumber(val):
|
|
||||||
# .encode().decode() always returns unicode in both P2 and P3
|
|
||||||
return (hex(val)[2:].split("L")[0]).encode("L1").decode("L1")
|
|
||||||
else:
|
|
||||||
raise Exception("to_hex() requires bytes, int/long, or [bin-ustr]")
|
|
||||||
|
|
||||||
def hex_slyce(val, start_pos=0, length=1, little_endian=False):
|
|
||||||
"""returns bytes slyce as hex-ustr"""
|
|
||||||
return to_hex(slyce(val, start_pos, length, little_endian))
|
|
||||||
|
|
||||||
def dec_slyce(val, start_pos=0, length=1, little_endian=False):
|
|
||||||
"""returns bytes slyce converted to decimal int/long"""
|
|
||||||
return to_dec(hex_slyce(val, start_pos, length, little_endian))
|
|
||||||
|
|
||||||
def bin_slyce(val, start_pos=0, length=1, little_endian=False):
|
|
||||||
"""returns bytes slyce converted to bin-ustr"""
|
|
||||||
return to_bin(hex_slyce(val, start_pos, length, little_endian))
|
|
||||||
|
|
||||||
def to_dec(val):
|
|
||||||
"""convert bytes, hex-ustr or [bin-ustr] to decimal int/long"""
|
|
||||||
if isinstance(val, list): # [bin-ustr]
|
|
||||||
return int(val[0], 2)
|
|
||||||
elif isinstance(val, bytes): # bytes
|
|
||||||
return int(to_hex(val), 16)
|
|
||||||
elif isinstance(val, type("".encode().decode())): # hex-ustr
|
|
||||||
return int(val, 16)
|
|
||||||
else:
|
|
||||||
raise Exception("to_dec() requires bytes, hex-ustr or [bin-ustr]")
|
|
||||||
|
|
||||||
def to_bin(val):
|
|
||||||
"""convert bytes, hex-ustr, or int/long to bin-ustr"""
|
|
||||||
if isinstance(val, bytes): # bytes
|
|
||||||
return (bin(to_dec(to_hex(val))))[2:].encode("L1").decode("L1")
|
|
||||||
elif isinstance(val, type("".encode().decode())): # hex-ustr
|
|
||||||
return (bin(int(val, 16)))[2:].encode("L1").decode("L1")
|
|
||||||
elif isnumber(val): # int/long
|
|
||||||
return (bin(val))[2:].encode("L1").decode("L1")
|
|
||||||
else:
|
|
||||||
raise Exception("to_bin() requires bytes, hex-ustr, or int/long")
|
|
||||||
|
|
||||||
def to_bytes(val):
|
|
||||||
"""converts hex-ustr, int/long, or [bin-ustr] to bytes"""
|
|
||||||
from binascii import a2b_hex
|
|
||||||
if isinstance(val, list): # [bin-ustr]
|
|
||||||
val = to_hex(val[0])
|
|
||||||
if isnumber(val): # int/long
|
|
||||||
val = to_hex(val)
|
|
||||||
if isinstance(val, type("".encode().decode())): # hex-ustr
|
|
||||||
return a2b_hex(bytes(val.encode("L1"))) # works on both P2 and P3
|
|
||||||
else:
|
|
||||||
raise Exception(
|
|
||||||
"to_bytes() requires hex-ustr, int/long, or [bin-ustr]")
|
|
||||||
|
|
||||||
def shift(items):
|
|
||||||
"""Shift list items to left, losing the first item.
|
|
||||||
|
|
||||||
in : list
|
|
||||||
out: list
|
|
||||||
"""
|
|
||||||
for i in range(0, (len(items)-1)):
|
|
||||||
items[i] = items[i+1]
|
|
||||||
del items[-1]
|
|
||||||
return items
|
|
||||||
|
|
||||||
def s(string):
|
|
||||||
"""Perform local variable substution, e.g. 'total: {num} items'"""
|
|
||||||
# http://stackoverflow.com/questions/2960772/
|
|
||||||
# putting-a-variable-inside-a-string-python
|
|
||||||
# http://stackoverflow.com/questions/6618795/
|
|
||||||
# get-locals-from-calling-namespace-in-python
|
|
||||||
import inspect
|
|
||||||
frame = inspect.currentframe()
|
|
||||||
try:
|
|
||||||
rVal = string.format(**frame.f_back.f_locals)
|
|
||||||
finally:
|
|
||||||
del frame
|
|
||||||
return rVal
|
|
||||||
|
|
||||||
def get_object_names(cls, include_subclasses=True):
|
|
||||||
object_names = []
|
|
||||||
for (this_object_name, this_object_id) in list(globals().items()):
|
|
||||||
if include_subclasses:
|
|
||||||
if isinstance(this_object_id, cls):
|
|
||||||
object_names.append(this_object_name)
|
|
||||||
else:
|
|
||||||
if type(this_object_id) is cls:
|
|
||||||
object_names.append(this_object_name)
|
|
||||||
return object_names
|
|
||||||
|
|
||||||
def touch(filePath, modTime=None):
|
|
||||||
# http://stackoverflow.com/questions/1158076/implement-touch-using-python
|
|
||||||
import os
|
|
||||||
if (os.name == "nt"):
|
|
||||||
if filePath[-1] == ".": filePath += "-"
|
|
||||||
filePath = filePath.replace("./", ".-/")
|
|
||||||
with open(filePath, "ab"):
|
|
||||||
os.utime(filePath, (None if (modTime is None) else (modTime, modTime)))
|
|
||||||
|
|
||||||
def mkdir(dirPath):
|
|
||||||
import os
|
|
||||||
if (os.name == "nt"):
|
|
||||||
if dirPath[-1] == ".": dirPath += "-"
|
|
||||||
dirPath = dirPath.replace("./", ".-/")
|
|
||||||
try:
|
|
||||||
os.mkdir(dirPath)
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def makedirs(dirPath):
|
|
||||||
import os
|
|
||||||
if (os.name == "nt"):
|
|
||||||
if dirPath[-1] == ".": dirPath += "-"
|
|
||||||
dirPath = dirPath.replace("./", ".-/")
|
|
||||||
try:
|
|
||||||
os.makedirs(dirPath)
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def loadFile(filePath):
|
|
||||||
import os
|
|
||||||
if (os.name == "nt"):
|
|
||||||
if filePath[-1] == ".": filePath += "-"
|
|
||||||
filePath = filePath.replace("./", ".-/")
|
|
||||||
with open(filePath, "rb") as imageHandle:
|
|
||||||
return imageHandle.read()
|
|
||||||
|
|
||||||
def saveFile(filePath, fileData):
|
|
||||||
import os
|
|
||||||
if (os.name == "nt"):
|
|
||||||
if filePath[-1] == ".": filePath += "-"
|
|
||||||
filePath = filePath.replace("./", ".-/")
|
|
||||||
with open(filePath, "wb") as imageHandle:
|
|
||||||
imageHandle.write(fileData)
|
|
||||||
|
|
||||||
def isnumber(number):
|
|
||||||
try: # make sure it's not a string
|
|
||||||
len(number)
|
|
||||||
return False
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
int(number)
|
|
||||||
except ValueError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
#---- end IvanX general purpose functions ----#
|
|
||||||
|
|
||||||
|
|
||||||
# --- start
|
|
||||||
|
|
||||||
args = sys.argv
|
|
||||||
if (len(args) == 1):
|
|
||||||
usage()
|
|
||||||
|
|
||||||
if (args[1] == "-s"):
|
|
||||||
g.silent=1
|
|
||||||
args = args[1:] #shift
|
|
||||||
|
|
||||||
if (args[1] == "-ad"):
|
|
||||||
g.AD = 1
|
|
||||||
args = args[1:] #shift
|
|
||||||
|
|
||||||
if (args[1] == "-e"):
|
|
||||||
if g.AD: usage()
|
|
||||||
g.EX = 1
|
|
||||||
args = args[1:] #shift
|
|
||||||
|
|
||||||
if (args[1] == "-cat"):
|
|
||||||
g.DIR = 1
|
|
||||||
args = args[1:]
|
|
||||||
|
|
||||||
if not ((g.DIR and len(args) >= 2) or (len(args) >= 3)):
|
|
||||||
usage()
|
|
||||||
if ((len(args) == 4) and
|
|
||||||
(slyce(args[2],0,1) != "/") and
|
|
||||||
(slyce(args[2],0,1) != ":")):
|
|
||||||
usage()
|
|
||||||
|
|
||||||
g.imageFile = args[1]
|
|
||||||
if not os.path.isfile(g.imageFile):
|
|
||||||
print("Source " + g.imageFile + " was not found.")
|
|
||||||
sys.exit(2)
|
|
||||||
g.imageData = loadFile(g.imageFile)
|
|
||||||
|
|
||||||
if (len(args) == 4):
|
|
||||||
g.PDOSPATH = args[2].upper()
|
|
||||||
targetPath = args[3]
|
|
||||||
if os.path.isdir(targetPath):
|
|
||||||
g.targetDir = targetPath
|
|
||||||
else:
|
|
||||||
g.targetDir = targetPath.rsplit("/", 1)[0]
|
|
||||||
g.targetName = targetPath.rsplit("/", 1)[1]
|
|
||||||
if not os.path.isdir(g.targetDir):
|
|
||||||
print("Target directory not found.")
|
|
||||||
sys.exit(2)
|
|
||||||
else:
|
|
||||||
if not g.DIR:
|
|
||||||
if not os.path.isdir(args[2]):
|
|
||||||
print("Target directory not found.")
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
g.activeDirBlock = 0
|
|
||||||
g.activeFileName = ""
|
|
||||||
g.activeFileSize = 0
|
|
||||||
g.activeFileBytesCopied = 0
|
|
||||||
g.resourceFork = 0
|
|
||||||
g.PDOSPATH_INDEX = 0
|
|
||||||
|
|
||||||
if (len(args) == 4):
|
|
||||||
g.PDOSPATH = g.PDOSPATH.replace(':', '/').split('/')
|
|
||||||
if not g.PDOSPATH[0]:
|
|
||||||
g.PDOSPATH_INDEX += 1
|
|
||||||
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
|
|
||||||
g.ADdir = (g.targetDir + "/.AppleDouble")
|
|
||||||
if not ((not g.AD) or os.path.isdir(g.ADdir)):
|
|
||||||
mkdir(g.ADdir)
|
|
||||||
processDir(2)
|
|
||||||
print("ProDOS file not found within image file.")
|
|
||||||
sys.exit(2)
|
|
||||||
else:
|
|
||||||
if not g.DIR:
|
|
||||||
# print(args[0], args[1], args[2])
|
|
||||||
g.targetDir = (args[2] + "/" + getVolumeName().decode("L1"))
|
|
||||||
g.ADdir = (g.targetDir + "/.AppleDouble")
|
|
||||||
if not os.path.isdir(g.targetDir):
|
|
||||||
makedirs(g.targetDir)
|
|
||||||
if not ((not g.AD) or os.path.isdir(g.ADdir)):
|
|
||||||
makedirs(g.ADdir)
|
|
||||||
processDir(2)
|
|
||||||
if not g.DIR:
|
|
||||||
syncExit()
|
|
||||||
|
|
@@ -1,286 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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,82 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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 ^/media /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,285 +0,0 @@
|
|||||||
# A2SERVER master setup script, last update 15-Feb-2015
|
|
||||||
# it downloads and executes several scripts related to the setup of
|
|
||||||
# netatalk configured for Apple II use on Debian, Raspbian, or Ubuntu.
|
|
||||||
# more info is at http://appleii.ivanx.com/a2server
|
|
||||||
|
|
||||||
# to download and execute, type:
|
|
||||||
# wget appleii.ivanx.com/a2server/setup; source setup
|
|
||||||
|
|
||||||
a2serverVersion="124"
|
|
||||||
|
|
||||||
isRpi=
|
|
||||||
[[ -f /usr/bin/raspi-config ]] && isRpi=1
|
|
||||||
|
|
||||||
isDebian=
|
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "7." ) && ( $(uname -m) == "i686" ) ]] && isDebian=1
|
|
||||||
|
|
||||||
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
|
|
||||||
echo "A2SERVER version available: $a2serverVersion"
|
|
||||||
echo "A2SERVER version installed: $(cat /usr/local/etc/A2SERVER-version)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
skipRepoUpdate=
|
|
||||||
autoAnswerYes=
|
|
||||||
setupNetBoot=
|
|
||||||
setupWindowsSharing=
|
|
||||||
updateRasppleII=
|
|
||||||
while [[ $1 ]]; do
|
|
||||||
if [[ $1 == "-r" ]]; then
|
|
||||||
shift
|
|
||||||
skipRepoUpdate="-r"
|
|
||||||
touch /tmp/a2server-packageReposUpdated
|
|
||||||
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 == "-os" || $1 == "os" ]]; then
|
|
||||||
# elif [[ ${1,,} == "rasppleii" || ${1,,} == "raspple" || ${1,,} == "rasappleii" || ${1,,} == "rasapple" || ${1,,} == "raspple2" || ${1,,} == "rasapple2" ]]; then
|
|
||||||
shift
|
|
||||||
updateRasppleII=1
|
|
||||||
elif [[ $1 == "-v" ]]; then
|
|
||||||
shift
|
|
||||||
if [[ ! -f /usr/local/etc/A2SERVER-version ]]; then
|
|
||||||
echo "A2SERVER version available: $a2serverVersion"
|
|
||||||
echo "A2SERVER version installed: none"
|
|
||||||
fi
|
|
||||||
[[ $0 == "-bash" ]] && return 1 || exit 1
|
|
||||||
elif [[ $1 ]]; then
|
|
||||||
echo "options:"
|
|
||||||
echo "-v: display installed and available versions, then exit"
|
|
||||||
echo "-y: auto-answer yes to all prompts"
|
|
||||||
echo "-r: don't update package repositories"
|
|
||||||
echo "-b: auto-setup network boot (use with -y)"
|
|
||||||
echo "-w: auto-setup Windows file sharing (use with -y)"
|
|
||||||
if [[ $isRpi ]]; then
|
|
||||||
echo "-os: update Raspbian OS, A2CLOUD, A2SERVER, and Apple II Pi"
|
|
||||||
fi
|
|
||||||
[[ $0 == "-bash" ]] && return 1 || exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ $updateRasppleII ]]; then
|
|
||||||
echo "A2SERVER: Updating Raspple II (takes up to an hour)..."
|
|
||||||
wget -qO /tmp/raspbian-update ivanx.com/a2server/files/raspbian-update.txt
|
|
||||||
source /tmp/raspbian-update a2cloud a2server $autoAnswerYes $skipRepoUpdate
|
|
||||||
[[ $0 == "-bash" ]] && return 0 || exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(cat /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."
|
|
||||||
fi
|
|
||||||
|
|
||||||
a2server_update=0
|
|
||||||
doSetup=1
|
|
||||||
|
|
||||||
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}')
|
|
||||||
[[ ($fwhash == "8aca5762") || ($fwhash == "462f3e3f476f7b6") || ($fwhash == "c32bc633039cd9") || ($fwhash == "9d34d0475f9") || ($fwhash == "d4f5315cfac4e") || ($fwhash == "6f4a90c8cb8817f") || ($fwhash == "5dd9b4962e") || ($fwhash == "17c8799375") ]] && unsupportedOS=0
|
|
||||||
elif [[ "$(lsb_release -rs 2> /dev/null)" == "12.04" ]]; then #Ubuntu 12.04?
|
|
||||||
unsupportedOS=0
|
|
||||||
elif [[ "$(lsb_release -rs 2> /dev/null)" == "7.3" || "$(lsb_release -rs 2> /dev/null)" == "7.6" || "$(lsb_release -rs 2> /dev/null)" == "7.8" ]]; then # tested Debian?
|
|
||||||
unsupportedOS=0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (( unsupportedOS )); then
|
|
||||||
echo
|
|
||||||
echo "WARNING: A2SERVER and its installer scripts have not been tested on this"
|
|
||||||
echo "operating system version. Continuing is probably fine, but might not be."
|
|
||||||
echo "Worst case could make your operating system no longer work properly,"
|
|
||||||
echo "or cause data to be lost."
|
|
||||||
echo "More information is at http://appleii.ivanx.com/a2server."
|
|
||||||
fi
|
|
||||||
|
|
||||||
doSetup=1
|
|
||||||
if [[ ! -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://appleii.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
|
|
||||||
|
|
||||||
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'"
|
|
||||||
|
|
||||||
|
|
||||||
[[ $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 are recommended"
|
|
||||||
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
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
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 appleii.ivanx.com/a2server/scripts/a2server-1-storage.txt
|
|
||||||
chmod ugo+x /tmp/1.storage
|
|
||||||
|
|
||||||
wget -q -O /tmp/2.tools appleii.ivanx.com/a2server/scripts/a2server-2-tools.txt
|
|
||||||
chmod ugo+x /tmp/2.tools
|
|
||||||
|
|
||||||
wget -q -O /tmp/3.sharing appleii.ivanx.com/a2server/scripts/a2server-3-sharing.txt
|
|
||||||
chmod ugo+x /tmp/3.sharing
|
|
||||||
|
|
||||||
wget -q -O /tmp/5.netboot appleii.ivanx.com/a2server/scripts/a2server-5-netboot.txt
|
|
||||||
chmod ugo+x /tmp/5.netboot
|
|
||||||
|
|
||||||
wget -q -O /tmp/6.samba appleii.ivanx.com/a2server/scripts/a2server-6-samba.txt
|
|
||||||
chmod ugo+x /tmp/6.samba
|
|
||||||
|
|
||||||
wget -q -O /tmp/7.console appleii.ivanx.com/a2server/scripts/a2server-7-console.txt
|
|
||||||
chmod ugo+x /tmp/7.console
|
|
||||||
|
|
||||||
echo "A2SERVER: Scripts have been downloaded. Installing..."
|
|
||||||
|
|
||||||
/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 ]] \
|
|
||||||
|| (( $(cat /usr/local/etc/A2SERVER-version) < "$a2serverVersion" )); then
|
|
||||||
echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
source /usr/local/etc/a2server-aliases
|
|
||||||
|
|
||||||
# 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/')
|
|
||||||
|
|
||||||
# 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."
|
|
||||||
echo
|
|
||||||
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 ]]; 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/singleUser ]]; then
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
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
|
|
||||||
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-autoAnswerYes 2> /dev/null
|
|
||||||
rm /tmp/a2server-packageReposUpdated 2> /dev/null
|
|
||||||
rm /tmp/a2server-setupNetBoot 2> /dev/null
|
|
||||||
rm /tmp/a2server-setupWindowsSharing 2> /dev/null
|
|
||||||
rm setup &> /dev/null
|
|
@@ -1,37 +0,0 @@
|
|||||||
currentVersion=124
|
|
||||||
|
|
||||||
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
|
|
||||||
installedVersion=$(cat /usr/local/etc/A2SERVER-version)
|
|
||||||
else
|
|
||||||
installedVersion=100
|
|
||||||
fi
|
|
||||||
|
|
||||||
autoAnswerYes=
|
|
||||||
for arg in $@; do
|
|
||||||
if [[ $arg == "-y" ]]; then
|
|
||||||
autoAnswerYes=1
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Update history:"
|
|
||||||
wget -qO- appleii.ivanx.com/a2server/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"
|
|
||||||
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/A2SERVER-version &> /dev/null
|
|
||||||
# sudo rm /usr/local/etc/netatalk/a2boot/* &> /dev/null
|
|
||||||
wget -q -O /tmp/setup appleii.ivanx.com/a2server/setup; source /tmp/setup "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset currentVersion 2> /dev/null
|
|
||||||
unset installedVersion 2> /dev/null
|
|
@@ -1,51 +0,0 @@
|
|||||||
1.0.0: Jan 2012: initial release
|
|
||||||
|
|
||||||
1.0.1: Jan 2012: fixes Netatalk date-stamp bug (thanks to Steven Hirsch)
|
|
||||||
|
|
||||||
1.0.2: Jan 2013: Netatalk 2.2.4; OS X 10.7+ login fixed; netboot fixes;
|
|
||||||
Raspbian "Wheezy" support; Ubuntu 12.04 LTS support
|
|
||||||
|
|
||||||
1.1.0: Apr 2013: Full GS/OS install; eliminated GS.SYSTEM volume;
|
|
||||||
Raspberry Pi enhancements; lots of improvements to installer;
|
|
||||||
more utilities installed for Apple II; improved cppo
|
|
||||||
NOTE: fresh install required, can't update earlier version
|
|
||||||
|
|
||||||
1.1.1: Jun 2013: Wi-Fi support; updates/additions to commands in a2server-help;
|
|
||||||
bug fixes and improvements to install script; appletalk kernel
|
|
||||||
module for Raspbian (instead of replacement kernel); RPi
|
|
||||||
console (onboard serial) set to 19,200 bps during boot
|
|
||||||
|
|
||||||
1.1.2: Oct 2013: resolves issue of no AppleTalk in Raspbian 2013-09-10 and
|
|
||||||
later; faster command-line installation on Raspberry Pi
|
|
||||||
(nulib2 and unar binaries are downloaded rather than compiled)
|
|
||||||
|
|
||||||
1.1.3: Jan 2014: shares ADTPro disks folder as ADTDISKS; added environment
|
|
||||||
variables for shared folders; can resolve by name
|
|
||||||
"a2server.local" if network client has Bonjour/zeroconf;
|
|
||||||
server presents itself as Shared computer to Macs on network;
|
|
||||||
VM based on Debian 7
|
|
||||||
|
|
||||||
1.1.4: Jan 2014: fixes bug with network boot if ADTPro disks folder is shared
|
|
||||||
|
|
||||||
1.1.5: Jul 2014: a2server-setup fixes Raspbian 20-Jul-14 AppleTalk kernel panic
|
|
||||||
|
|
||||||
1.2.0: Aug 2014: a2server-setup and Netatalk startup script addresses AppleTalk
|
|
||||||
kernel panic on any Linux kernel 3.12-3.15; Netatalk starts
|
|
||||||
in background, preventing startup delay; a2server-setup always
|
|
||||||
configures Netatalk startup script and can download a new one
|
|
||||||
if missing; a2server-setup on Raspbian or Debian 7 x86 is
|
|
||||||
faster because it downloads binaries rather than compiling
|
|
||||||
from source; unbit/unexec/usq unarchivers added; additional
|
|
||||||
virtual machine which has both A2SERVER and A2CLOUD installed
|
|
||||||
|
|
||||||
1.2.1: Jan 2015: minor fixes; support for LED blink on Raspbian 2015-01-31
|
|
||||||
|
|
||||||
1.2.2: Mar 2015: installer improvements: now has command line options,
|
|
||||||
including unattended install; installer sets passwords
|
|
||||||
automatically to 'apple2'; status messages are now prefixed by
|
|
||||||
A2SERVER:; can update Raspple II (Raspbian OS,
|
|
||||||
NOOBS install manager, A2SERVER, and A2CLOUD); minor fixes.
|
|
||||||
|
|
||||||
1.2.3: May 2015: changed Apple software links to Internet Archive
|
|
||||||
|
|
||||||
1.2.4: Jul 2015: offer to download A2CLOUD disk contents onto A2FILES volume
|
|
1749
files/A2FILES-list.txt
Normal file
1749
files/A2FILES-list.txt
Normal file
File diff suppressed because it is too large
Load Diff
65
files/dist/getexternal.sh
vendored
Executable file
65
files/dist/getexternal.sh
vendored
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||||
|
|
||||||
|
if ! hash wget; then
|
||||||
|
echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Downloading items..."
|
||||||
|
|
||||||
|
mkdir -p files/external/source
|
||||||
|
wget -O files/external/source/ciopfs-0.4.tar.gz http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz
|
||||||
|
wget -O files/external/source/macipgw.zip https://github.com/zero2sixd/macipgw/archive/2a5f6a7521a627e46b18468d44f4306fb0a7b7ab.zip
|
||||||
|
wget -O files/external/source/netatalk-2.2.4.tar.gz http://downloads.sourceforge.net/project/netatalk/netatalk/2.2.4/netatalk-2.2.4.tar.gz
|
||||||
|
wget -O files/external/source/nulib2-3.1.0a2.zip https://github.com/fadden/nulib2/archive/20fe7efb4d37fedf807416c16d74d51d893ea48a.zip
|
||||||
|
wget -O files/external/source/unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip
|
||||||
|
|
||||||
|
mkdir -p files/external/appleii
|
||||||
|
wget --max-redirect 0 -O files/external/appleii/Apple_II_System_Disk_3.2.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_II_Supplemental/Apple_II_System_Disk_3.2.sea.bin
|
||||||
|
wget -O files/external/appleii/Asimov.shk http://www.ninjaforce.com/downloads/Asimov.shk
|
||||||
|
wget -O files/external/appleii/MOUNTIT.SHK http://www.brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK
|
||||||
|
wget -O files/external/appleii/Marinetti3.0b8.po http://www.a2retrosystems.com/downloads/Marinetti3.0b8.po
|
||||||
|
wget -O files/external/appleii/PPPX.1.3d4.SHK http://www.apple2.org/marinetti/PPPX.1.3d4.SHK
|
||||||
|
wget -O files/external/appleii/dsk2file.shk http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip
|
||||||
|
wget -O files/external/appleii/gshk11.sea http://www.nulib.com/library/gshk11.sea
|
||||||
|
wget -O files/external/appleii/shrinkit.sdk http://www.nulib.com/library/shrinkit.sdk
|
||||||
|
wget -O files/external/appleii/spectrum_gold_2mg.zip http://speccie.uk/speccie/downloads/spectrum_gold_2mg.zip
|
||||||
|
wget -O files/external/appleii/uthernet2ll.bxy http://speccie.uk/speccie/downloads/uthernet2ll.bxy
|
||||||
|
wget -O files/external/appleii/uthernetll.bxy http://speccie.uk/speccie/downloads/uthernetll.bxy
|
||||||
|
|
||||||
|
unset safeUrl samUrl snapUrl
|
||||||
|
safeUrl=$(wget -qO- http://speccie.uk/software/safe2/ | grep -i 'safe2.*bxy' | tr '<>' '\n' | grep href | cut -d '=' -f 2 | tr -d '"')
|
||||||
|
samUrl=$(wget -qO- http://speccie.uk/software/sam2/ | grep -i 'sam2.*bxy' | tr '<>' '\n' | grep href | cut -d '=' -f 2 | tr -d '"')
|
||||||
|
snapUrl=$(wget -qO- http://speccie.uk/software/snap/ | grep -i 'snap.*bxy' | tr '<>' '\n' | grep href | cut -d '=' -f 2 | tr -d '"')
|
||||||
|
wget -O files/external/appleii/safe2.bxy "$safeUrl"
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
152
files/netatalk-init.d-clean.txt
Executable file
152
files/netatalk-init.d-clean.txt
Executable file
@@ -0,0 +1,152 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: netatalk
|
||||||
|
# Required-Start: $remote_fs $syslog
|
||||||
|
# Should-Start: avahi-daemon
|
||||||
|
# Required-Stop: $remote_fs $syslog
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 1
|
||||||
|
### END INIT INFO
|
||||||
|
#
|
||||||
|
# netatalk Netatalk 2.2.4 initscript
|
||||||
|
# Author: Thomas Kaiser <Thomas.Kaiser@phg-online.de>
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
DESC="Netatalk"
|
||||||
|
NAME=netatalk
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
# Guard to prevent execution if netatalk was removed.
|
||||||
|
test -x /usr/local/sbin/afpd || exit 0
|
||||||
|
|
||||||
|
# Set defaults. Please change these options in /etc/default/netatalk
|
||||||
|
ATALK_NAME=`/bin/hostname --short`
|
||||||
|
ATALK_UNIX_CHARSET='LOCALE'
|
||||||
|
ATALK_MAC_CHARSET='MAC_ROMAN'
|
||||||
|
|
||||||
|
CNID_METAD_RUN=yes
|
||||||
|
AFPD_RUN=yes
|
||||||
|
AFPD_MAX_CLIENTS=50
|
||||||
|
AFPD_UAMLIST="-U uams_dhx2.so"
|
||||||
|
AFPD_GUEST=nobody
|
||||||
|
CNID_CONFIG="-l log_note"
|
||||||
|
|
||||||
|
ATALKD_RUN=no
|
||||||
|
PAPD_RUN=no
|
||||||
|
TIMELORD_RUN=no
|
||||||
|
#A2BOOT_RUN=no
|
||||||
|
ATALK_ZONE=
|
||||||
|
ATALK_BGROUND=no
|
||||||
|
|
||||||
|
# old /etc/default/netatalk expected hostname in $HOSTNAME by default
|
||||||
|
HOSTNAME=`/bin/hostname`
|
||||||
|
|
||||||
|
# Read in netatalk configuration.
|
||||||
|
if [ -f /etc/default/netatalk ]; then
|
||||||
|
. /etc/default/netatalk
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start Netatalk servers.
|
||||||
|
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
|
||||||
|
/sbin/modprobe appletalk || echo "[could not load appletalk module]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start atalkd server.
|
||||||
|
/usr/local/sbin/atalkd
|
||||||
|
|
||||||
|
# register workstation
|
||||||
|
/usr/local/bin/nbprgstr -p 4 "$ATALK_NAME:Workstation$ATALK_ZONE"
|
||||||
|
/usr/local/bin/nbprgstr -p 4 "$ATALK_NAME:netatalk$ATALK_ZONE"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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"$TIMELORD_RUN" = x"yes" ]; then
|
||||||
|
/usr/local/sbin/timelord
|
||||||
|
echo -n " timelord"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
if [ "x$ATALK_BGROUND" = "xyes" -a "x$ATALKD_RUN" = "xyes" ]; then
|
||||||
|
echo "Starting Netatalk services in the background."
|
||||||
|
atalk_startup >/dev/null &
|
||||||
|
else
|
||||||
|
echo -n "Starting Netatalk services (this will take a while): "
|
||||||
|
atalk_startup
|
||||||
|
echo "."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
echo -n "Stopping Netatalk Daemons:"
|
||||||
|
echo -n " afpd"
|
||||||
|
start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/afpd
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if test -x /usr/local/sbin/timelord; then
|
||||||
|
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 "."
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart)
|
||||||
|
$0 force-reload
|
||||||
|
;;
|
||||||
|
|
||||||
|
force-reload)
|
||||||
|
echo -n "Restarting Netatalk Daemons (this will take a while)"
|
||||||
|
$0 stop
|
||||||
|
echo -n "."
|
||||||
|
sleep 2
|
||||||
|
echo -n "."
|
||||||
|
if $0 start; then
|
||||||
|
echo "done."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop|restart|force-reload}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@@ -7,7 +7,7 @@
|
|||||||
# Ensure URL we'll use ends in a /
|
# Ensure URL we'll use ends in a /
|
||||||
case "$A2SERVER_SCRIPT_URL" in
|
case "$A2SERVER_SCRIPT_URL" in
|
||||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://ivanx.com/a2server}/" ;;
|
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||||
esac
|
esac
|
||||||
case "$A2SERVER_BINARY_URL" in
|
case "$A2SERVER_BINARY_URL" in
|
||||||
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
||||||
@@ -16,10 +16,13 @@ esac
|
|||||||
useExternalURL=1
|
useExternalURL=1
|
||||||
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
|
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
|
||||||
|
|
||||||
|
debianVersion=$(cat /etc/debian_version 2> /dev/null)
|
||||||
|
isRpi=
|
||||||
arch=
|
arch=
|
||||||
if [[ -f /usr/bin/raspi-config ]]; then
|
if [[ -f /usr/bin/raspi-config ]]; then
|
||||||
isRpi=1
|
isRpi=1
|
||||||
elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -c 1 < /etc/debian_version) -ge "7" ) ]]; then
|
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)"
|
uname_m="$(uname -m)"
|
||||||
if [[ $uname_m == "i686" ]]; then
|
if [[ $uname_m == "i686" ]]; then
|
||||||
arch='debian_x86'
|
arch='debian_x86'
|
||||||
@@ -28,21 +31,41 @@ elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
isJessie=
|
debianName=
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "8." ) ]] && isJessie=1
|
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
|
||||||
|
|
||||||
echo "A2SERVER: Installing A2SERVER tools..."
|
echo "A2SERVER: Installing A2SERVER tools..."
|
||||||
|
|
||||||
if ! command -v nulib2 > /dev/null; then
|
# 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
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! hash nulib2 &> /dev/null; then
|
||||||
|
|
||||||
echo "A2SERVER: Installing nulib2..."
|
echo "A2SERVER: Installing nulib2..."
|
||||||
|
|
||||||
cd /tmp
|
cd /tmp
|
||||||
if [[ $arch ]]; then
|
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||||
{ wget -qO- "${binaryURL}precompiled/nulib2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
{ wget -qO- "${binaryURL}precompiled/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v nulib2 > /dev/null; then
|
if ! hash nulib2 &> /dev/null; then
|
||||||
|
|
||||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||||
# prepare for installing packages
|
# prepare for installing packages
|
||||||
@@ -55,27 +78,30 @@ if ! command -v nulib2 > /dev/null; then
|
|||||||
sudo apt-get -y clean
|
sudo apt-get -y clean
|
||||||
|
|
||||||
cd /tmp
|
cd /tmp
|
||||||
rm -rf /tmp/nulib &> /dev/null
|
rm -rf /tmp/nulib2 &> /dev/null
|
||||||
mkdir /tmp/nulib
|
mkdir /tmp/nulib2
|
||||||
cd /tmp/nulib
|
cd /tmp/nulib2
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -q -O nulibdist.tar.gz http://web.archive.org/web/20131031160750/http://www.nulib.com/downloads/nulibdist.tar.gz
|
wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7efb4d37fedf807416c16d74d51d893ea48a.zip"
|
||||||
tar zxf nulibdist.tar.gz &> /dev/null
|
unzip nulib2-3.1.0a2.zip 2> /dev/null
|
||||||
|
rm nulib2-3.1.0a2.zip &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -d nulib2-220 ]]; then
|
if [ ! -d nulib2* ]; then
|
||||||
wget -q -O nulibdist.tar.gz ${binaryURL}external/nulibdist.tar.gz
|
wget -q -O nulib2-3.1.0a2.zip "${binaryURL}external/source/nulib2-3.1.0a2.zip"
|
||||||
tar zxf nulibdist.tar.gz &> /dev/null
|
unzip nulib2-3.1.0a2.zip 2> /dev/null
|
||||||
|
rm nulib2-3.1.0a2.zip &> /dev/null
|
||||||
fi
|
fi
|
||||||
cd nufxlib*
|
cd nulib2*
|
||||||
|
cd nufxlib
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
cd ../nulib2*
|
cd ../nulib2
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
cd
|
cd
|
||||||
rm -rf /tmp/nulib
|
rm -rf /tmp/nulib2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -85,7 +111,7 @@ fi
|
|||||||
# download and install The Unarchiver, for expanding Apple disk images
|
# download and install The Unarchiver, for expanding Apple disk images
|
||||||
# http://wakaba.c3.cx/s/apps/unarchiver.html
|
# http://wakaba.c3.cx/s/apps/unarchiver.html
|
||||||
|
|
||||||
if ! command -v unar > /dev/null; then
|
if ! hash unar &> /dev/null; then
|
||||||
|
|
||||||
echo "A2SERVER: Installing The Unarchiver..."
|
echo "A2SERVER: Installing The Unarchiver..."
|
||||||
|
|
||||||
@@ -96,21 +122,21 @@ if ! command -v unar > /dev/null; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# jessie and later: Just use the unar package
|
# jessie and later: Just use the unar package
|
||||||
if [[ $isJessie ]]; then
|
if [[ $debianMajor -ge 8 ]]; then
|
||||||
sudo apt-get -y install unar
|
sudo apt-get -y install unar
|
||||||
sudo apt-get clean
|
sudo apt-get clean
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v unar > /dev/null; then
|
if ! hash unar &> /dev/null; then
|
||||||
if [[ $arch ]]; then
|
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||||
# Dependencies: for unar
|
# Dependencies: for unar
|
||||||
sudo apt-get -y install libgnustep-base1.22
|
sudo apt-get -y install libgnustep-base1.22
|
||||||
sudo apt-get clean
|
sudo apt-get clean
|
||||||
{ wget -qO- "${binaryURL}precompiled/unar-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
{ wget -qO- "${binaryURL}precompiled/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If all else fails, compile from source.
|
# If all else fails, compile from source.
|
||||||
if ! command -v unar >/dev/null; then
|
if ! hash unar &> /dev/null; then
|
||||||
|
|
||||||
# Dependencies: build-deps for unar
|
# 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 -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip
|
||||||
@@ -120,12 +146,12 @@ if ! command -v unar > /dev/null; then
|
|||||||
mkdir /tmp/unar
|
mkdir /tmp/unar
|
||||||
cd /tmp/unar
|
cd /tmp/unar
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -O unar_1.8.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.zip
|
wget -O unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip
|
||||||
unzip -o unar_1.8.zip &> /dev/null
|
unzip -o unar-1.8.1.zip &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob
|
if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob
|
||||||
wget -O unar_1.8.zip ${binaryURL}external/unar-1.8.zip
|
wget -O unar-1.8.1.zip ${binaryURL}external/source/unar-1.8.1.zip
|
||||||
unzip -o unar_1.8.zip &> /dev/null
|
unzip -o unar-1.8.1.zip &> /dev/null
|
||||||
fi
|
fi
|
||||||
cd *Unarchiver*/XADMaster
|
cd *Unarchiver*/XADMaster
|
||||||
make -f Makefile.linux
|
make -f Makefile.linux
|
||||||
@@ -141,7 +167,7 @@ else
|
|||||||
echo "A2SERVER: The Unarchiver has already been installed."
|
echo "A2SERVER: The Unarchiver has already been installed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v unzip >/dev/null; then
|
if ! hash unzip &> /dev/null; then
|
||||||
echo "A2SERVER: Installing unzip..."
|
echo "A2SERVER: Installing unzip..."
|
||||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||||
# prepare for installing packages
|
# prepare for installing packages
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
# Ensure URL we'll use ends in a /
|
# Ensure URL we'll use ends in a /
|
||||||
case "$A2SERVER_SCRIPT_URL" in
|
case "$A2SERVER_SCRIPT_URL" in
|
||||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://appleii.ivanx.com/a2server}/" ;;
|
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||||
esac
|
esac
|
||||||
case "$A2SERVER_BINARY_URL" in
|
case "$A2SERVER_BINARY_URL" in
|
||||||
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
||||||
@@ -26,12 +26,13 @@ esac
|
|||||||
useExternalURL=1
|
useExternalURL=1
|
||||||
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
|
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
|
||||||
|
|
||||||
|
debianVersion=$(cat /etc/debian_version 2> /dev/null)
|
||||||
isRpi=
|
isRpi=
|
||||||
arch=
|
arch=
|
||||||
if [[ -f /usr/bin/raspi-config ]]; then
|
if [[ -f /usr/bin/raspi-config ]]; then
|
||||||
isRpi=1
|
isRpi=1
|
||||||
arch='rpi'
|
arch='rpi'
|
||||||
elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -c 1 < /etc/debian_version) -ge "7" ) ]]; then
|
elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then
|
||||||
uname_m="$(uname -m)"
|
uname_m="$(uname -m)"
|
||||||
if [[ $uname_m == "i686" ]]; then
|
if [[ $uname_m == "i686" ]]; then
|
||||||
arch='debian_x86'
|
arch='debian_x86'
|
||||||
@@ -40,8 +41,29 @@ elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
isJessie=
|
debianName=
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "8." ) ]] && isJessie=1
|
if [[ $debianVersion ]]; then
|
||||||
|
debianMajor=$(cut -d . -f 1 <<< $debianVersion)
|
||||||
|
if [[ $debianMajor == "10" ]]; then
|
||||||
|
debianName="buster"
|
||||||
|
elif [[ $debianMajor == "9" ]]; then
|
||||||
|
debianName="stretch"
|
||||||
|
elif [[ $debianMajor == "8" ]]; then
|
||||||
|
debianName="jessie"
|
||||||
|
elif [[ $debianMajor == "7" ]]; then
|
||||||
|
debianName="wheezy"
|
||||||
|
else
|
||||||
|
debianName="unknown"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# enable SSH (disabled by default in Raspbian from late 2016 onward)
|
||||||
|
if [[ $isRpi && $debianMajor -ge 8 ]] && ! ps aux | grep -q '[s]shd'; then
|
||||||
|
echo "A2SERVER: Enabling ssh access..."
|
||||||
|
sudo systemctl enable ssh &> /dev/null && sudo systemctl start ssh &> /dev/null
|
||||||
|
else
|
||||||
|
echo "A2SERVER: ssh access is already enabled."
|
||||||
|
fi
|
||||||
|
|
||||||
# skip this if already done
|
# skip this if already done
|
||||||
if [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) >= 101 )); then
|
if [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) >= 101 )); then
|
||||||
@@ -64,6 +86,7 @@ else
|
|||||||
touch /tmp/a2server-packageReposUpdated
|
touch /tmp/a2server-packageReposUpdated
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# not being used as of 1.2.9, but it's available if full URL to .deb package is supplied
|
||||||
getOldPackage () {
|
getOldPackage () {
|
||||||
for url in $@; do
|
for url in $@; do
|
||||||
pkgFile=${url##*/}
|
pkgFile=${url##*/}
|
||||||
@@ -86,45 +109,45 @@ else
|
|||||||
urls=
|
urls=
|
||||||
while [[ $arch ]]; do
|
while [[ $arch ]]; do
|
||||||
# Install runtime libraries needed by Netatalk
|
# Install runtime libraries needed by Netatalk
|
||||||
if [[ $isJessie ]]; then
|
if [[ $(apt-cache search '^libdb5.1$') ]]; then # Wheezy
|
||||||
if [[ $arch == "rpi" ]]; then
|
|
||||||
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/d/db/libdb5.1_5.1.29-5_armhf.deb"
|
|
||||||
elif [[ $arch == "debian_x86" ]]; then
|
|
||||||
getOldPackage "http://ftp.debian.org/debian/pool/main/d/db/libdb5.1_5.1.29-5_i386.deb"
|
|
||||||
elif [[ $arch == "debian_x64" ]]; then
|
|
||||||
getOldPackage "http://ftp.debian.org/debian/pool/main/d/db/libdb5.1_5.1.29-5_amd64.deb"
|
|
||||||
fi
|
|
||||||
elif [[ $(apt-cache search '^libdb5.1$') ]]; then
|
|
||||||
# Dependencies: netatalk 2.2.4
|
# Dependencies: netatalk 2.2.4
|
||||||
sudo apt-get -y install libdb5.1
|
sudo apt-get -y install libdb5.1
|
||||||
|
elif [[ $(apt-cache search '^libdb5.3$') ]]; then # Jessie or Stretch
|
||||||
|
# Dependencies: netatalk 2.2.4
|
||||||
|
sudo apt-get -y install libdb5.3
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
if [[ $(apt-cache search '^libssl1.0.0$') ]]; then
|
if [[ $(apt-cache search '^libssl1.0.0$') ]]; then # Wheezy or Jessie
|
||||||
# Dependencies: netatalk 2.2.4
|
# Dependencies: netatalk 2.2.4
|
||||||
sudo apt-get -y install libssl1.0.0
|
sudo apt-get -y install libssl1.0.0
|
||||||
|
elif [[ $(apt-cache search '^libssl1.0.2$') ]]; then # Stretch
|
||||||
|
# Dependencies: netatalk 2.2.4
|
||||||
|
sudo apt-get -y install libssl1.0.2
|
||||||
|
elif [[ $(apt-cache search '^libssl1.1$') ]]; then # Buster
|
||||||
|
# Dependencies: netatalk 2.2.4
|
||||||
|
echo "deb http://deb.debian.org/debian/ oldstable main" | sudo tee -a /etc/apt/sources.list > /dev/null
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install libssl1.0.2
|
||||||
|
sudo sed -i '$d' /etc/apt/sources.list
|
||||||
|
sudo apt-get -y update
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $isJessie ]]; then
|
if [[ $(apt-cache search '^libgcrypt11$') ]]; then # Wheezy
|
||||||
if [[ $arch == "rpi" ]]; then
|
|
||||||
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/libg/libgcrypt11/libgcrypt11_1.5.0-5+deb7u3_armhf.deb"
|
|
||||||
elif [[ $arch == "debian_x86" ]]; then
|
|
||||||
getOldPackage "http://ftp.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11_1.5.0-5+deb7u3_i386.deb"
|
|
||||||
elif [[ $arch == "debian_x64" ]]; then
|
|
||||||
getOldPackage "http://ftp.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11_1.5.0-5+deb7u3_amd64.deb"
|
|
||||||
fi
|
|
||||||
elif [[ $(apt-cache search '^libgcrypt11$') ]]; then
|
|
||||||
# Dependencies: netatalk 2.2.4
|
# Dependencies: netatalk 2.2.4
|
||||||
sudo apt-get -y install libgcrypt11
|
sudo apt-get -y install libgcrypt11
|
||||||
|
elif [[ $(apt-cache search '^libgcrypt20$') ]]; then # Jessie, Stretch, Buster
|
||||||
|
# Dependencies: netatalk 2.2.4
|
||||||
|
sudo apt-get -y install libgcrypt20
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install Netatalk
|
# install Netatalk
|
||||||
if [[ $arch ]]; then
|
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||||
{ wget -qO- "${binaryURL}precompiled/netatalk224-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
{ wget -qO- "${binaryURL}precompiled/netatalk226-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||||
fi
|
fi
|
||||||
sudo mandb &> /dev/null
|
sudo mandb &> /dev/null
|
||||||
|
|
||||||
@@ -134,44 +157,60 @@ else
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [[ $compileFromSource ]]; then
|
if [[ $compileFromSource ]]; then
|
||||||
|
|
||||||
# Dependencies: build-deps for netatalk 2.2.4
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
sudo apt-get -y install build-essential libssl-dev
|
sudo apt-get -y install build-essential
|
||||||
if [[ $arch ]]; then
|
|
||||||
if [[ $arch == "rpi" ]]; then
|
if [[ $(dpkg -l | grep libssl-dev | tr -s ' ' | cut -d ' ' -f 3 | cut -c 1-3) == "1.1" ]]; then
|
||||||
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/d/db/libdb5.1-dev_5.1.29-5_armhf.deb"
|
echo "A2SERVER: WARNING: libssl-dev 1.1 is already installed; removing."
|
||||||
elif [[ $arch == "debian_x86" ]]; then
|
sudo apt-get -y purge libssl-dev
|
||||||
getOldPackage "http://ftp.us.debian.org/debian/pool/main/d/db/libdb5.1-dev_5.1.29-5_i386.deb"
|
sudo apt -y autoremove
|
||||||
elif [[ $arch == "debian_x64" ]]; then
|
|
||||||
getOldPackage "http://ftp.us.debian.org/debian/pool/main/d/db/libdb5.1-dev_5.1.29-5_amd64.deb"
|
|
||||||
fi
|
fi
|
||||||
elif [[ $(apt-cache search '^libdb5.1-dev$') ]]; then
|
|
||||||
|
if [[ $(apt-cache search '^libssl1.0-dev$') ]]; then # Stretch
|
||||||
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
|
sudo apt-get -y install libssl1.0-dev
|
||||||
|
else # Jessie or Wheezy (libssl-dev 1.0.x) or Buster (absent)
|
||||||
|
if [[ $(apt-cache madison libssl-dev | grep '^libssl' | head -1 | cut -d '|' -f 2 | tr -d ' ' | cut -c 1-3) == "1.1" ]]; then # Buster, so pull from Stretch
|
||||||
|
echo "deb http://deb.debian.org/debian/ oldstable main" | sudo tee -a /etc/apt/sources.list > /dev/null
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install libssl1.0.dev
|
||||||
|
sudo sed -i '$d' /etc/apt/sources.list
|
||||||
|
sudo apt-get -y update
|
||||||
|
else # Jessie or Wheezy
|
||||||
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
|
sudo apt-get -y install libssl-dev
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $(apt-cache search '^libdb5.1-dev$') ]]; then # Wheezy
|
||||||
# Dependencies: build-deps for netatalk 2.2.4
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
sudo apt-get -y install libdb5.1-dev
|
sudo apt-get -y install libdb5.1-dev
|
||||||
elif [[ $(apt-cache search '^libdb4.8-dev$') ]]; then
|
elif [[ $(apt-cache search '^libdb5.3-dev$') ]]; then # Jessie, Stretch, Buster
|
||||||
# Dependencies: build-deps for netatalk 2.2.4
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
sudo apt-get -y install libdb4.8-dev
|
sudo apt-get -y install libdb5.3-dev
|
||||||
else
|
else
|
||||||
echo "A2SERVER: WARNING: unknown version of libdb-dev is being installed."
|
echo "A2SERVER: WARNING: unknown version of libdb-dev is being installed."
|
||||||
# Dependencies: build-deps for netatalk 2.2.4
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
sudo apt-get -y install libdb-dev
|
sudo apt-get -y install libdb-dev
|
||||||
fi
|
fi
|
||||||
if [[ $isJessie ]]; then
|
|
||||||
sudo apt-get -y install libgpg-error-dev
|
if [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then # Stretch, Jessie or Wheezy
|
||||||
if [[ $arch == "rpi" ]]; then
|
|
||||||
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/libg/libgcrypt11/libgcrypt11-dev_1.5.0-5+deb7u3_armhf.deb"
|
|
||||||
elif [[ $arch == "debian_x86" ]]; then
|
|
||||||
getOldPackage "http://ftp.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11-dev_1.5.0-5+deb7u3_i386.deb"
|
|
||||||
elif [[ $arch == "debian_x64" ]]; then
|
|
||||||
getOldPackage "http://ftp.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11-dev_1.5.0-5+deb7u3_amd64.deb"
|
|
||||||
fi
|
|
||||||
elif [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then
|
|
||||||
# Dependencies: build-deps for netatalk 2.2.4
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
sudo apt-get -y install libgcrypt11-dev
|
sudo apt-get -y install libgcrypt11-dev
|
||||||
|
elif [[ $(apt-cache search '^libgcrypt20-dev$') ]]; then # Buster
|
||||||
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
|
echo "deb http://deb.debian.org/debian/ oldstable main" | sudo tee -a /etc/apt/sources.list > /dev/null
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install libgcrypt11-dev
|
||||||
|
sudo sed -i '$d' /etc/apt/sources.list
|
||||||
|
sudo apt-get -y update
|
||||||
else
|
else
|
||||||
echo "A2SERVER: WARNING: unknown version of libgcrypt-dev is being installed."
|
echo "A2SERVER: WARNING: unknown version of libgcrypt-dev is being installed."
|
||||||
# Dependencies: build-deps for netatalk 2.2.4
|
# Dependencies: build-deps for netatalk 2.2.4
|
||||||
sudo apt-get -y install $(apt-cache search '^libgcrypt.*dev$' | sort -r | head -1 | cut -d ' ' -f 1)
|
sudo apt-get -y install $(apt-cache search '^libgcrypt.*dev$' | sort -r | head -1 | cut -d ' ' -f 1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo apt-get clean
|
sudo apt-get clean
|
||||||
|
|
||||||
# get Netatalk
|
# get Netatalk
|
||||||
@@ -184,7 +223,7 @@ else
|
|||||||
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
|
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -d netatalk-2.2.4 ]]; then
|
if [[ ! -d netatalk-2.2.4 ]]; then
|
||||||
wget -O netatalk-2.2.4.tar.gz "${binaryURL}external/netatalk-2.2.4.tar.gz"
|
wget -O netatalk-2.2.4.tar.gz "${binaryURL}external/source/netatalk-2.2.4.tar.gz"
|
||||||
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
|
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
|
||||||
fi
|
fi
|
||||||
cd netatalk-2.2.4
|
cd netatalk-2.2.4
|
||||||
@@ -213,28 +252,30 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Install MacIPgw
|
# --- Install MacIPgw
|
||||||
if ! command -v macipgw > /dev/null; then
|
if ! hash macipgw &> /dev/null; then
|
||||||
echo "A2SERVER: Installing TCP over AppleTalk (MacIP)..."
|
echo "A2SERVER: Installing TCP over AppleTalk (MacIP)..."
|
||||||
|
|
||||||
if [[ $arch ]]; then
|
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||||
{ wget -qO- "${binaryURL}precompiled/macipgw-${arch}.tgz" | sudo tar Pzx; } 2> /dev/null
|
{ wget -qO- "${binaryURL}precompiled/macipgw-${arch}.tgz" | sudo tar Pzx; } 2> /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v macipgw > /dev/null; then
|
if ! hash macipgw &> /dev/null; then
|
||||||
wd="$PWD"
|
wd="$PWD"
|
||||||
sudo apt-get -y install build-essential
|
sudo apt-get -y install build-essential
|
||||||
rm -rf /tmp/macipgw &> /dev/null
|
rm -rf /tmp/macipgw &> /dev/null
|
||||||
mkdir /tmp/macipgw
|
mkdir /tmp/macipgw
|
||||||
cd /tmp/macipgw
|
cd /tmp/macipgw
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -qO macipgw.zip "https://github.com/zero2sixd/macipgw/archive/master.zip"
|
wget -qO macipgw.zip "https://github.com/zero2sixd/macipgw/archive/2a5f6a7521a627e46b18468d44f4306fb0a7b7ab.zip"
|
||||||
unzip macipgw-src.zip &> /dev/null
|
unzip macipgw.zip 2> /dev/null
|
||||||
|
rm macipgw.zip &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -d macipgw-master ]]; then
|
if [ ! -d macipgw* ]; then
|
||||||
wget -qO macipgw-src.zip "${binaryURL}external/macipgw-src.zip"
|
wget -qO macipgw.zip "${binaryURL}external/source/macipgw.zip"
|
||||||
unzip macipgw-src.zip &> /dev/null
|
unzip macipgw.zip 2> /dev/null
|
||||||
|
rm macipgw.zip &> /dev/null
|
||||||
fi
|
fi
|
||||||
cd macipgw-master
|
cd macipgw*
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
cd "$wd"
|
cd "$wd"
|
||||||
@@ -263,10 +304,13 @@ sudo sed -i 's/#ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk
|
|||||||
if [[ ! $(grep 'kernelRelease' /etc/init.d/netatalk) ]]; then
|
if [[ ! $(grep 'kernelRelease' /etc/init.d/netatalk) ]]; then
|
||||||
sudo sed -i 's@\(\tif \[ x\"$ATALKD_RUN\)@\n\t# check for valid AppleTalk kernel module\n\t[[ $ATALKD_RUN == "yes" ]] \&\& { kernelRelease=$(uname -r); kernelMajor=$(cut -d "." -f 1 <<< $kernelRelease); kernelMinor=$(cut -d "." -f 2 <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); kernelPatch=$(cut -d "." -f 3- <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); [[ ( $kernelMajor -eq 3 \&\& $kernelMinor -ge 12 \&\& $kernelMinor -le 15 ) \&\& ( ! ( -f /usr/bin/raspi-config \&\& $kernelMinor -eq 12 \&\& $kernelPatch -ge 25 ) ) \&\& ( ( ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ) || $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d " ") != "ecb239fc084c36de93f6926e7749b80f6024f269" ) ]] \&\& { ATALKD_RUN=no; echo "[AppleTalk networking is not available.]" 1>\&2; } }\n\n\1@' /etc/init.d/netatalk
|
sudo sed -i 's@\(\tif \[ x\"$ATALKD_RUN\)@\n\t# check for valid AppleTalk kernel module\n\t[[ $ATALKD_RUN == "yes" ]] \&\& { kernelRelease=$(uname -r); kernelMajor=$(cut -d "." -f 1 <<< $kernelRelease); kernelMinor=$(cut -d "." -f 2 <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); kernelPatch=$(cut -d "." -f 3- <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); [[ ( $kernelMajor -eq 3 \&\& $kernelMinor -ge 12 \&\& $kernelMinor -le 15 ) \&\& ( ! ( -f /usr/bin/raspi-config \&\& $kernelMinor -eq 12 \&\& $kernelPatch -ge 25 ) ) \&\& ( ( ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ) || $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d " ") != "ecb239fc084c36de93f6926e7749b80f6024f269" ) ]] \&\& { ATALKD_RUN=no; echo "[AppleTalk networking is not available.]" 1>\&2; } }\n\n\1@' /etc/init.d/netatalk
|
||||||
fi
|
fi
|
||||||
|
sudo sed -i 's/Starting Netatalk services (this will take a while): /Starting Netatalk services"\n\t\t\t[[ $ATALKD_RUN == "yes" ]] \&\& echo -n " (this will take 45 seconds)"\n\t\t\techo -n ":/' /etc/init.d/netatalk
|
||||||
|
sudo sed -i 's/Starting Netatalk services in the background./Netatalk services will be available in 45 seconds./' /etc/init.d/netatalk
|
||||||
|
sudo sed -i 's/-n "Restarting Netatalk Daemons (this will take a while)"/"Restarting Netatalk Daemons."/' /etc/init.d/netatalk
|
||||||
|
|
||||||
# enable MacIPgw support after launching atalkd
|
# enable MacIPgw support after launching atalkd
|
||||||
if ! grep -q -i 'macipgw' /etc/init.d/netatalk; then
|
if ! grep -q -i 'macipgw' /etc/init.d/netatalk; then
|
||||||
sudo sed -i ':a;N;$!ba;s@\(echo -n " atalkd"\)\(.*# prepare\)@\1\n\n # start MacIPgw (TCP over AppleTalk) service\n ps aux | grep -q "[m]acipgw" \&\& sudo killall macipgw 2> /dev/null\n atalkd_interface=$(grep "^[^ #]" /etc/netatalk/atalkd.conf | tail -1 | cut -d " " -f 1)\n sysctl -w net.ipv4.ip_forward=1 > /dev/null\n macipgw -n 8.8.8.8 192.168.151.0 255.255.255.0\n /sbin/iptables -t nat -A POSTROUTING -o ${atalkd_interface} -j MASQUERADE\n /sbin/iptables -A FORWARD -i ${atalkd_interface} -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n /sbin/iptables -A FORWARD -i tun1 -o ${atalkd_interface} -j ACCEPT\n\n echo -n " macipgw"\n\2@' /etc/init.d/netatalk
|
sudo sed -i ':a;N;$!ba;s@\(echo -n " atalkd"\)\(.*# prepare\)@\1\n\n\t\t# start MacIPgw (TCP over AppleTalk) service\n\t\tps aux | grep -q "[m]acipgw" \&\& sudo killall macipgw 2> /dev/null || :\n\t\tatalkd_interface=$(grep "^[^ #]" /etc/netatalk/atalkd.conf | tail -1 | cut -d " " -f 1)\n\t\tsysctl -w net.ipv4.ip_forward=1 > /dev/null\n\t\tmacipgw -n 8.8.8.8 192.168.151.0 255.255.255.0\n\t\t/sbin/iptables -t nat -A POSTROUTING -o ${atalkd_interface} -j MASQUERADE\n\t\t/sbin/iptables -A FORWARD -i ${atalkd_interface} -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n\t\t/sbin/iptables -A FORWARD -i tun1 -o ${atalkd_interface} -j ACCEPT\n\n\t\techo -n " macipgw"\n\2@' /etc/init.d/netatalk
|
||||||
sudo sed -i 's@\(start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd.*$\)@\1\n echo -n " macipgw"\n sudo killall macipgw 2> /dev/null@' /etc/init.d/netatalk
|
sudo sed -i 's@\(start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd.*$\)@\1\n echo -n " macipgw"\n sudo killall macipgw 2> /dev/null@' /etc/init.d/netatalk
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -306,12 +350,12 @@ sudo sed -i 's/^~/#share1\n\n#share2/' \
|
|||||||
sudo sed -i 's/^:DEFAULT/#:DEFAULT/' \
|
sudo sed -i 's/^:DEFAULT/#:DEFAULT/' \
|
||||||
/usr/local/etc/netatalk/AppleVolumes.default
|
/usr/local/etc/netatalk/AppleVolumes.default
|
||||||
|
|
||||||
if [[ ! $(grep ^eth0 /usr/local/etc/netatalk/atalkd.conf) && ! $(grep ^wlan0 /usr/local/etc/netatalk/atalkd.conf) ]]; then
|
# if [[ ! $(grep ^eth0 /usr/local/etc/netatalk/atalkd.conf) && ! $(grep ^wlan0 /usr/local/etc/netatalk/atalkd.conf) ]]; then
|
||||||
|
if [[ $(tac /usr/local/etc/netatalk/atalkd.conf | sed '/./,$!d' | head -1 | cut -c 1) == "#" ]]; then
|
||||||
# enable netatalk on the default network interface
|
# enable netatalk on the default network interface
|
||||||
# needs -router and -zone to prevent GS/OS AppleShare CDEV crash when used
|
# needs -router and -zone to prevent GS/OS AppleShare CDEV crash when used
|
||||||
# with Dayna or Asante bridges
|
# with Dayna or Asante bridges
|
||||||
echo -e 'eth0 -router -phase 2 -net 1 -zone "A2SERVER"' \
|
echo -e 'eth0 -router -phase 2 -net 1 -zone "A2SERVER"' | sudo tee -a /usr/local/etc/netatalk/atalkd.conf > /dev/null
|
||||||
| sudo tee -a /usr/local/etc/netatalk/atalkd.conf > /dev/null
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Raspberry Pi
|
# Raspberry Pi
|
||||||
@@ -347,7 +391,7 @@ if [[ -d /srv/A2SERVER/A2FILES && ! -d /srv/A2SERVER/.a2files ]]; then
|
|||||||
echo "A2SERVER: Converting A2FILES to support mixed case..."
|
echo "A2SERVER: Converting A2FILES to support mixed case..."
|
||||||
sudo /etc/init.d/netatalk stop &> /dev/null
|
sudo /etc/init.d/netatalk stop &> /dev/null
|
||||||
sudo /etc/init.d/samba stop &> /dev/null
|
sudo /etc/init.d/samba stop &> /dev/null
|
||||||
if ! command -v getfattr &> /dev/null; then
|
if ! hash getfattr &> /dev/null; then
|
||||||
# Dependency: for ciopfs conversion (setfattr)
|
# Dependency: for ciopfs conversion (setfattr)
|
||||||
sudo apt-get -y install attr &> /dev/null
|
sudo apt-get -y install attr &> /dev/null
|
||||||
sudo apt-get clean
|
sudo apt-get clean
|
||||||
@@ -372,6 +416,7 @@ if [[ -d /srv/A2SERVER/A2FILES && ! -d /srv/A2SERVER/.a2files ]]; then
|
|||||||
mkdir /srv/A2SERVER/A2FILES
|
mkdir /srv/A2SERVER/A2FILES
|
||||||
sudo sed -i 's/casefold:toupper //' /usr/local/etc/netatalk/AppleVolumes.default 2> /dev/null
|
sudo sed -i 's/casefold:toupper //' /usr/local/etc/netatalk/AppleVolumes.default 2> /dev/null
|
||||||
sudo sed -i 's/^VOLCASEFOLD:.*/VOLCASEFOLD:/' /srv/A2SERVER/.a2files/.appledesktop/.volinfo 2> /dev/null
|
sudo sed -i 's/^VOLCASEFOLD:.*/VOLCASEFOLD:/' /srv/A2SERVER/.a2files/.appledesktop/.volinfo 2> /dev/null
|
||||||
|
sudo sed -i 's|/media/A2SHARED/A2FILES|/srv/A2SERVER/A2FILES|' /srv/A2SERVER/.a2files/.appledesktop/.volinfo 2> /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 1.3.0: remove GSFILES if empty
|
# 1.3.0: remove GSFILES if empty
|
||||||
@@ -399,13 +444,13 @@ sudo sed -i \
|
|||||||
[[ -d /srv/A2SERVER/.a2files ]] || mkdir -p /srv/A2SERVER/.a2files
|
[[ -d /srv/A2SERVER/.a2files ]] || mkdir -p /srv/A2SERVER/.a2files
|
||||||
|
|
||||||
# set up ciopfs
|
# set up ciopfs
|
||||||
if ! command -v ciopfs > /dev/null; then
|
if ! hash ciopfs &> /dev/null; then
|
||||||
echo "A2SERVER: Installing ciopfs (case insensitive file system)..."
|
echo "A2SERVER: Installing ciopfs (case insensitive file system)..."
|
||||||
cd /tmp
|
cd /tmp
|
||||||
|
|
||||||
# Dependency: For ciopfs
|
# Dependency: For ciopfs
|
||||||
sudo apt-get -y install fuse libglib2.0-0 libattr1 libfuse2
|
sudo apt-get -y install fuse libglib2.0-0 libattr1 libfuse2
|
||||||
if [[ $arch ]]; then
|
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
|
||||||
{ wget -qO- "${binaryURL}precompiled/ciopfs-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
{ wget -qO- "${binaryURL}precompiled/ciopfs-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ -f /etc/fuse.conf ]] && sudo grep -q user_allow_other /etc/fuse.conf; then
|
if [[ -f /etc/fuse.conf ]] && sudo grep -q user_allow_other /etc/fuse.conf; then
|
||||||
@@ -414,7 +459,7 @@ if ! command -v ciopfs > /dev/null; then
|
|||||||
echo "user_allow_other" | sudo tee /etc/fuse.conf > /dev/null
|
echo "user_allow_other" | sudo tee /etc/fuse.conf > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v ciopfs > /dev/null; then
|
if ! hash ciopfs &> /dev/null; then
|
||||||
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
|
||||||
# prepare for installing packages
|
# prepare for installing packages
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
@@ -431,11 +476,16 @@ if ! command -v ciopfs > /dev/null; then
|
|||||||
cd /tmp/ciopfs
|
cd /tmp/ciopfs
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -q -O ciopfs-0.4.tar.gz http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz
|
wget -q -O ciopfs-0.4.tar.gz http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
wget -q -O ciopfs-0.4.tar.gz http://web.archive.org/web/20160911102924/http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz
|
||||||
|
fi
|
||||||
tar zxf ciopfs-0.4.tar.gz &> /dev/null
|
tar zxf ciopfs-0.4.tar.gz &> /dev/null
|
||||||
|
rm ciopfs-0.4.tar.gz &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [ ! -f ciopfs*/ciopfs.c ]; then # single brackets required for glob
|
if [ ! -f ciopfs*/ciopfs.c ]; then # single brackets required for glob
|
||||||
wget -q -O ciopfs-0.4.tar.gz ${binaryURL}external/ciopfs-0.4.tar.gz
|
wget -q -O ciopfs-0.4.tar.gz ${binaryURL}external/source/ciopfs-0.4.tar.gz
|
||||||
tar zxf ciopfs-0.4.tar.gz &> /dev/null
|
tar zxf ciopfs-0.4.tar.gz &> /dev/null
|
||||||
|
rm ciopfs-0.4.tar.gz &> ?dev/null
|
||||||
fi
|
fi
|
||||||
cd ciopfs*
|
cd ciopfs*
|
||||||
make
|
make
|
||||||
@@ -472,6 +522,8 @@ fi
|
|||||||
# to make Netatalk start up when the server boots:
|
# to make Netatalk start up when the server boots:
|
||||||
sudo update-rc.d netatalk defaults &> /dev/null
|
sudo update-rc.d netatalk defaults &> /dev/null
|
||||||
|
|
||||||
|
# prepare shared volumes for use
|
||||||
|
afpsync -v < /dev/null
|
||||||
|
|
||||||
# --- Setting up users
|
# --- Setting up users
|
||||||
|
|
||||||
@@ -533,12 +585,12 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]];
|
|||||||
sudo /etc/init.d/netatalk stop &> /dev/null
|
sudo /etc/init.d/netatalk stop &> /dev/null
|
||||||
sudo rmmod ipddp 2> /dev/null
|
sudo rmmod ipddp 2> /dev/null
|
||||||
sudo rmmod appletalk 2> /dev/null
|
sudo rmmod appletalk 2> /dev/null
|
||||||
echo "A2SERVER: Attempting to replace AppleTalk kernel module for MacIP use..."
|
echo "A2SERVER: Replacing AppleTalk kernel module (IPDDP disabled) for MacIP use..."
|
||||||
|
|
||||||
sudo mv /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko /tmp 2> /dev/null
|
sudo mv /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko /tmp 2> /dev/null
|
||||||
|
|
||||||
if [[ ${arch%_*} == "debian" ]]; then
|
if [[ ! $compileFromSource && ${arch%_*} == "debian" ]]; then
|
||||||
echo "A2SERVER: Attempting to fetch AppleTalk kernel module for Debian..."
|
echo "A2SERVER: Fetching AppleTalk kernel module for Debian..."
|
||||||
wget -qO /tmp/appletalk.tgz ${binaryURL}precompiled/appletalk-$kernelRelease-${arch}.tgz
|
wget -qO /tmp/appletalk.tgz ${binaryURL}precompiled/appletalk-$kernelRelease-${arch}.tgz
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
# if we found a prebuilt one on a2server site, install it and load it
|
# if we found a prebuilt one on a2server site, install it and load it
|
||||||
@@ -550,9 +602,12 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]];
|
|||||||
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk
|
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk
|
||||||
sudo /etc/init.d/netatalk restart &> /dev/null
|
sudo /etc/init.d/netatalk restart &> /dev/null
|
||||||
else
|
else
|
||||||
|
echo "A2SERVER: failed to load AppleTalk kernel module"
|
||||||
# if we didn't load it successfully, remove it
|
# if we didn't load it successfully, remove it
|
||||||
sudo rm /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko 2> /dev/null
|
sudo rm /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko 2> /dev/null
|
||||||
fi
|
fi
|
||||||
|
else # download failed, so premade kernel not found, remove empty file
|
||||||
|
rm /tmp/appletalk.tgz 2>/dev/null
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -566,10 +621,11 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]];
|
|||||||
|
|
||||||
# kernel module compile adapted from from: http://askubuntu.com/a/338403/288003
|
# kernel module compile adapted from from: http://askubuntu.com/a/338403/288003
|
||||||
for i in 1; do
|
for i in 1; do
|
||||||
echo "A2SERVER: Attempting to build AppleTalk kernel module..."
|
echo "A2SERVER: Building AppleTalk kernel module..."
|
||||||
[[ -f /boot/config-$kernelRelease ]] || break
|
[[ -f /boot/config-$kernelRelease ]] || break
|
||||||
sudo apt-get -y install linux-headers-$kernelRelease linux-source-$kernelMajorMinor || break
|
sudo apt-get -y install linux-headers-$kernelRelease linux-source-$kernelMajorMinor || break
|
||||||
sudo apt-get -y install build-essential
|
sudo apt-get -y install build-essential
|
||||||
|
sudo apt-get -y install libelf-dev # required as of kernel 4.14.12, apparently
|
||||||
cd /usr/src
|
cd /usr/src
|
||||||
kernelSrc=$(find linux-source-${kernelMajorMinor}*)
|
kernelSrc=$(find linux-source-${kernelMajorMinor}*)
|
||||||
if [[ ${kernelSrc##*.} == "xz" ]]; then
|
if [[ ${kernelSrc##*.} == "xz" ]]; then
|
||||||
@@ -600,6 +656,7 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]];
|
|||||||
sudo rm /usr/src/$kernelSrc
|
sudo rm /usr/src/$kernelSrc
|
||||||
sudo rm -r /usr/src/linux-source-$kernelMajorMinor
|
sudo rm -r /usr/src/linux-source-$kernelMajorMinor
|
||||||
sudo apt-get -y purge linux-source-$kernelMajorMinor
|
sudo apt-get -y purge linux-source-$kernelMajorMinor
|
||||||
|
sudo apt -y autoremove
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -650,7 +707,7 @@ if [[ ( ! $(ps aux | grep [a]talkd) ) && ( $isRpi ) ]]; then
|
|||||||
|
|
||||||
# if no AppleTalk module, try to download it from a2server site
|
# if no AppleTalk module, try to download it from a2server site
|
||||||
if [[ ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # check for rpi kernel module
|
if [[ ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # check for rpi kernel module
|
||||||
echo "A2SERVER: Attempting to install AppleTalk kernel module for Raspbian..."
|
echo "A2SERVER: Installing AppleTalk kernel module for Raspbian..."
|
||||||
wget -qO /tmp/appletalk.ko.gz ${binaryURL}appletalk-$kernelRelease-rpi.ko.gz
|
wget -qO /tmp/appletalk.ko.gz ${binaryURL}appletalk-$kernelRelease-rpi.ko.gz
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
# if we found a prebuilt one on a2server site, install it and load it
|
# if we found a prebuilt one on a2server site, install it and load it
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
# Ensure URL we'll use ends in a /
|
# Ensure URL we'll use ends in a /
|
||||||
case "$A2SERVER_SCRIPT_URL" in
|
case "$A2SERVER_SCRIPT_URL" in
|
||||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://ivanx.com/a2server}/" ;;
|
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||||
esac
|
esac
|
||||||
case "$A2SERVER_BINARY_URL" in
|
case "$A2SERVER_BINARY_URL" in
|
||||||
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
||||||
@@ -28,40 +28,171 @@ p8Dir="/srv/A2SERVER/A2FILES"
|
|||||||
diskToolsP8Dir=$p8Dir/Disk.Tools.P8
|
diskToolsP8Dir=$p8Dir/Disk.Tools.P8
|
||||||
|
|
||||||
commDir="/srv/A2SERVER/A2FILES/Comm"
|
commDir="/srv/A2SERVER/A2FILES/Comm"
|
||||||
spectrumDir=$commDir/Spectrum
|
|
||||||
protermDir=$commDir/ProTERM
|
|
||||||
zlinkDir=$commDir/Z.Link
|
|
||||||
adtproDir=$commDir/ADTPro
|
|
||||||
|
|
||||||
gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/"
|
gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/"
|
||||||
|
# alernate: http://web.archive.org/web/20080907081050/http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/
|
||||||
gsosBackupURL="http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_IIGS_System_6.0.1%2F"
|
gsosBackupURL="http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_IIGS_System_6.0.1%2F"
|
||||||
|
|
||||||
|
# --- bashByter library routines
|
||||||
|
|
||||||
|
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")"
|
||||||
|
}
|
||||||
|
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- end bashByter
|
||||||
|
|
||||||
|
cpAD () {
|
||||||
|
# copy a file with its AppleDouble component in ./.AppleDouble
|
||||||
|
# arg1 = source path, # arg2 = destination directory (not filename)
|
||||||
|
afpsync=
|
||||||
|
if [[ $1 == "-s" ]]; then
|
||||||
|
afpsync=1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
arg1="$1"
|
||||||
|
[[ "$arg1" == *"/"* ]] || arg1="./$arg1"
|
||||||
|
cp -p "$arg1" "$2"
|
||||||
|
mkdir -p "$2"/.AppleDouble
|
||||||
|
cp -p "${arg1%/*}"/.AppleDouble/"${arg1##*/}" "$2"/.AppleDouble
|
||||||
|
[[ $afpsync ]] && afpsync -v > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
checkP8YearTables () {
|
||||||
|
updateP8YearTables -c $1
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
updateP8YearTables () {
|
updateP8YearTables () {
|
||||||
# Geoff Body and Andrew Roughan helped Joseph Carter with this one
|
# JC: Geoff Body and Andrew Roughan helped Joseph Carter with this one
|
||||||
# Update ProDOS 8 year table (and spalsh date because may as well)
|
# Update ProDOS 8 year table (and spalsh date because may as well)
|
||||||
# Effectively, we're turning p8 into the 6.0.3 version here.
|
# Effectively, we're turning p8 into the 6.0.2 or 6.0.3 version here.
|
||||||
|
#
|
||||||
|
# ID: updates the year table for the Thunderclock driver in ProDOS 8;
|
||||||
|
# calculated from the day of week and date, as year is unavailable.
|
||||||
|
# accepts optional arguments for custom patches
|
||||||
|
# arg1 = year table, comma separated
|
||||||
|
# arg2 = date string for ProDOS splash screen in format "dd-Mmm-yy"
|
||||||
|
# OR for presets, arg1=602 or arg1=603, arg2 is empty
|
||||||
|
check=
|
||||||
|
if [[ $1 == "-c" ]]; then
|
||||||
|
check=1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
patch1=""
|
||||||
|
patch2=""
|
||||||
|
if [[ $1 == "602" ]]; then
|
||||||
|
patch1=$(echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d")
|
||||||
|
patch2=$(echo -n -e "\xb2\xb2\xad\xca\xf5\xee\xad\xb1\xb5")
|
||||||
|
elif [[ $1 == "603" ]]; then
|
||||||
|
patch1=$(echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d")
|
||||||
|
patch2=$(echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5")
|
||||||
|
elif [[ $1 ]]; then # year table supplied as seven comma-separated values
|
||||||
|
for year in $(tr "," " " <<< $1); do
|
||||||
|
patch1=${patch1}$(echo -n -e "\x$(printf %02X $year)")
|
||||||
|
done
|
||||||
|
if [[ $2 ]]; then # splash screen date supplied, convert to high-ascii bytes
|
||||||
|
for c in $(sed "s/./& /g" <<< $2); do
|
||||||
|
patch2=${patch2}$(decToChar $(( $(charToDec $c) + 128 )))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
wd=$PWD
|
wd=$PWD
|
||||||
cd /usr/local/etc/netatalk/a2boot
|
cd /usr/local/etc/netatalk/a2boot
|
||||||
echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="p8" bs=38 seek=1 conv=notrunc 2> /dev/null
|
files=("p8" "ProDOS16 Image" "Apple :2f:2fe Boot Blocks" "$gsosDir/System/P8")
|
||||||
echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="p8" bs=3958 seek=1 conv=notrunc 2> /dev/null
|
offset1=(3958 7030 7071 3958) # splash screen date
|
||||||
echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="ProDOS16 Image" bs=3110 seek=1 conv=notrunc 2> /dev/null
|
offset2=(38 3110 79 38) # year table
|
||||||
echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="ProDOS16 Image" bs=7030 seek=1 conv=notrunc 2> /dev/null
|
|
||||||
echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="Apple :2f:2fe Boot Blocks" bs=79 seek=1 conv=notrunc 2> /dev/null
|
i=0
|
||||||
echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="Apple :2f:2fe Boot Blocks" bs=7071 seek=1 conv=notrunc 2> /dev/null
|
if [[ $check ]]; then
|
||||||
|
# check if patched -- we're not actually doing this any more; we're always patching
|
||||||
|
patched=0 # 0 is true in this case since it's the return value
|
||||||
|
while (( $i < ${#files[@]} )); do
|
||||||
|
[[ ! -f "${files[$i]}" ]] && { (( i++ )); continue; }
|
||||||
|
if [[ ! $patch1 || $patch1 != $(sudo dd if="${files[$i]}" skip=${offset1[$i]} bs=1 count=7 2> /dev/null | tr -d '\0') ]]; then
|
||||||
|
patched=1 # 1 is false
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [[ ! $patch2 || $patch2 != $(sudo dd if="${files[$i]}" skip=${offset2[$i]} bs=1 count=9 2> /dev/null | tr -d '\0') ]]; then
|
||||||
|
patched=1 # 1 is false
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
(( i++ ))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# perform patch
|
||||||
|
while (( $i < ${#files[@]} )); do
|
||||||
|
[[ ! -f "${files[$i]}" ]] && { (( i++ )); continue; }
|
||||||
|
[[ $patch1 ]] && echo -n -e ${patch1} | sudo dd of="${files[$i]}" seek=${offset1[$i]} bs=1 conv=notrunc 2> /dev/null
|
||||||
|
[[ $patch2 ]] && echo -n -e ${patch2} | sudo dd of="${files[$i]}" seek=${offset2[$i]} bs=1 conv=notrunc 2> /dev/null
|
||||||
|
(( i++ ))
|
||||||
|
done
|
||||||
|
patched=0 # 0 is true
|
||||||
|
fi
|
||||||
|
return $patched
|
||||||
|
|
||||||
|
# echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="p8" bs=38 seek=1 conv=notrunc 2> /dev/null
|
||||||
|
# echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="p8" bs=3958 seek=1 conv=notrunc 2> /dev/null
|
||||||
|
# echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="ProDOS16 Image" bs=3110 seek=1 conv=notrunc 2> /dev/null
|
||||||
|
# echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="ProDOS16 Image" bs=7030 seek=1 conv=notrunc 2> /dev/null
|
||||||
|
# echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="Apple :2f:2fe Boot Blocks" bs=79 seek=1 conv=notrunc 2> /dev/null
|
||||||
|
# echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="Apple :2f:2fe Boot Blocks" bs=7071 seek=1 conv=notrunc 2> /dev/null
|
||||||
|
|
||||||
cd "$wd"
|
cd "$wd"
|
||||||
}
|
}
|
||||||
|
|
||||||
# bail out on automated netboot setup unless -b is also specified
|
# bail out on automated netboot setup unless -b is also specified
|
||||||
[[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes=
|
[[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes=
|
||||||
if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|
||||||
|
|
||||||
|
netbootInstalled=
|
||||||
|
if [[ -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Boot\ Blocks && \
|
||||||
|
-f /usr/local/etc/netatalk/a2boot/ProDOS16\ Image && \
|
||||||
|
-f /usr/local/etc/netatalk/a2boot/Apple\ :2f:2fe\ Boot\ Blocks && \
|
||||||
|
-f /usr/local/etc/netatalk/a2boot/p8 && \
|
||||||
|
-f /usr/local/etc/netatalk/a2boot/Basic.System && \
|
||||||
|
-f $gsosDir/USERS/USER1/SETUP/ATINIT && \
|
||||||
|
-f $gsosDir/USERS/"<ANY USER>"/SETUP/ATINIT ]] ; then
|
||||||
|
netbootInstalled=1
|
||||||
|
fi
|
||||||
|
REPLY=
|
||||||
|
if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
if [[ ! $autoAnswerYes ]]; then
|
||||||
|
if [[ ! $netbootInstalled ]]; then
|
||||||
echo
|
echo
|
||||||
echo "Do you want to set up A2SERVER to be able to boot Apple II"
|
echo "Do you want to set up A2SERVER to be able to boot Apple II"
|
||||||
echo -n "computers over the network? "
|
echo -n "computers over the network? "
|
||||||
read
|
read
|
||||||
|
else
|
||||||
|
echo "A2SERVER is already set up to boot Apple II computers over the network."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
|
|
||||||
nbmode=1
|
nbmode=1
|
||||||
@@ -69,12 +200,15 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
|
|
||||||
sudo true
|
sudo true
|
||||||
mkdir -p /tmp/netboot
|
mkdir -p /tmp/netboot
|
||||||
|
rm -r /tmp/netboot/* 2> /dev/null
|
||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
|
|
||||||
# this will get "Disk 7" (Apple II Setup) as a raw (block dump) image
|
# this will get "Disk 7" (Apple II Setup) as a raw (block dump) image
|
||||||
if [[ ! -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Boot\ Blocks ]] \
|
if [[ ! -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Boot\ Blocks ]] \
|
||||||
|| [[ ! -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Image ]] \
|
|| [[ ! -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Image ]] \
|
||||||
|| [[ ! -f /usr/local/etc/netatalk/a2boot/Apple\ :2f:2fe\ Boot\ Blocks ]]; then
|
|| [[ ! -f /usr/local/etc/netatalk/a2boot/Apple\ :2f:2fe\ Boot\ Blocks ]] \
|
||||||
|
|| [[ ! -f /usr/local/etc/netatalk/a2boot/p8 ]] \
|
||||||
|
|| [[ ! -f /usr/local/etc/netatalk/a2boot/Basic.System ]]; then
|
||||||
echo "A2SERVER: Downloading Apple II Boot Blocks..."
|
echo "A2SERVER: Downloading Apple II Boot Blocks..."
|
||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
|
|
||||||
@@ -93,10 +227,10 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
truncate -s 819284 'Disk 7 of 7-Apple II Setup.sea'
|
truncate -s 819284 'Disk 7 of 7-Apple II Setup.sea'
|
||||||
dd if='Disk 7 of 7-Apple II Setup.sea' of=APPLE2SETUP.HDV bs=84 skip=1 2> /dev/null
|
dd if='Disk 7 of 7-Apple II Setup.sea' of=APPLE2SETUP.HDV bs=84 skip=1 2> /dev/null
|
||||||
|
|
||||||
# copy the Boot Blocks into the right place
|
|
||||||
mkdir -p a2setup
|
mkdir -p a2setup
|
||||||
sudo mount -t hfs -o ro,loop APPLE2SETUP.HDV a2setup
|
sudo mount -t hfs -o ro,loop APPLE2SETUP.HDV a2setup
|
||||||
sudo mkdir -p /usr/local/etc/netatalk/a2boot
|
sudo mkdir -p /usr/local/etc/netatalk/a2boot
|
||||||
|
sudo rm -r /usr/local/etc/netatalk/a2boot/* 2> /dev/null
|
||||||
sudo cp -p a2setup/System\ Folder/* /usr/local/etc/netatalk/a2boot
|
sudo cp -p a2setup/System\ Folder/* /usr/local/etc/netatalk/a2boot
|
||||||
sudo umount a2setup
|
sudo umount a2setup
|
||||||
sudo mv /usr/local/etc/netatalk/a2boot/Apple* /usr/local/etc/netatalk/a2boot/'Apple :2f:2fe Boot Blocks'
|
sudo mv /usr/local/etc/netatalk/a2boot/Apple* /usr/local/etc/netatalk/a2boot/'Apple :2f:2fe Boot Blocks'
|
||||||
@@ -139,8 +273,8 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
echo
|
echo
|
||||||
echo "A2SERVER: Creating NETBOOT.P8..."
|
echo "A2SERVER: Creating NETBOOT.P8..."
|
||||||
touch $p8Dir/NETBOOT.P8
|
touch $p8Dir/NETBOOT.P8
|
||||||
echo -n -e "\x38\x20\x1f\xfe\x90\x01\x60\xfb\x08\xc2\x30\xf4\x02\x00\xf4\x62\x00\xa2\x03\x0b\x22\x00\x00\xe1\x78\xf4\x00\x00\xf4\x00\x00\xab\xab\x2b\x38\xfb\xce\xf4\x03\xa9\x0c\x8d\x68\xc0\x9c\x47\xc0\x9c\x41\xc0\xa9\x09\x8d\x39\xc0\xa9\xc0\x8d\x39\xc0\x5c\x62\xfa\x00" | \
|
echo -n -e "\x38\x20\x1f\xfe\x90\x01\x60\xfb\x08\xc2\x30\xf4\x02\x00\xf4\x62\x00\xa2\x03\x0b\x22\x00\x00\xe1\x78\xf4\x00\x00\xf4\x00\x00\xab\xab\x2b\x38\xfb\xce\xf4\x03\xa9\x0c\x8d\x68\xc0\x9c\x47\xc0\x9c\x41\xc0\xa9\x09\x8d\x39\xc0\xa9\xc0\x8d\x39\xc0\x5c\x62\xfa\x00" \
|
||||||
sudo dd of="$p8Dir/NETBOOT.P8" 2> /dev/null
|
| sudo dd of="$p8Dir/NETBOOT.P8" 2> /dev/null
|
||||||
afpsync -v $p8Dir > /dev/null
|
afpsync -v $p8Dir > /dev/null
|
||||||
afptype -p SYS -q $p8Dir/NETBOOT.P8
|
afptype -p SYS -q $p8Dir/NETBOOT.P8
|
||||||
fi
|
fi
|
||||||
@@ -149,8 +283,8 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
echo "A2SERVER: Creating NETBOOT.GSOS..."
|
echo "A2SERVER: Creating NETBOOT.GSOS..."
|
||||||
# create tool for setting GSOS boot in battery RAM and rebooting. Props yet again to Geoff Body.
|
# create tool for setting GSOS boot in battery RAM and rebooting. Props yet again to Geoff Body.
|
||||||
touch $gsosDir/NETBOOT.GSOS
|
touch $gsosDir/NETBOOT.GSOS
|
||||||
echo -n -e "\x38\x20\x1f\xfe\x90\x01\x60\xfb\x08\xc2\x30\xf4\x01\x00\xf4\x62\x00\xa2\x03\x0b\x22\x00\x00\xe1\x78\xf4\x00\x00\xf4\x00\x00\xab\xab\x2b\x38\xfb\xce\xf4\x03\xa9\x0c\x8d\x68\xc0\x9c\x47\xc0\x9c\x41\xc0\xa9\x09\x8d\x39\xc0\xa9\xc0\x8d\x39\xc0\x5c\x62\xfa\x00" | \
|
echo -n -e "\x38\x20\x1f\xfe\x90\x01\x60\xfb\x08\xc2\x30\xf4\x01\x00\xf4\x62\x00\xa2\x03\x0b\x22\x00\x00\xe1\x78\xf4\x00\x00\xf4\x00\x00\xab\xab\x2b\x38\xfb\xce\xf4\x03\xa9\x0c\x8d\x68\xc0\x9c\x47\xc0\x9c\x41\xc0\xa9\x09\x8d\x39\xc0\xa9\xc0\x8d\x39\xc0\x5c\x62\xfa\x00" \
|
||||||
sudo dd of="$p8Dir/NETBOOT.GSOS" 2> /dev/null
|
| sudo dd of="$p8Dir/NETBOOT.GSOS" 2> /dev/null
|
||||||
afpsync -v $gsosDir > /dev/null
|
afpsync -v $gsosDir > /dev/null
|
||||||
afptype -p SYS -q $gsosDir/NETBOOT.GSOS
|
afptype -p SYS -q $gsosDir/NETBOOT.GSOS
|
||||||
fi
|
fi
|
||||||
@@ -158,6 +292,10 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
mkatinit -gs -d -f # GS/OS registered user and Guest starts up with SYSTEM/FINDER
|
mkatinit -gs -d -f # GS/OS registered user and Guest starts up with SYSTEM/FINDER
|
||||||
mkatinit -d -f guest # ProDOS 8 Guest starts up with BASIC.SYSTEM (no registered user)
|
mkatinit -d -f guest # ProDOS 8 Guest starts up with BASIC.SYSTEM (no registered user)
|
||||||
|
|
||||||
|
netbootInstalled=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $netbootInstalled ]]; then
|
||||||
gsosInstall=
|
gsosInstall=
|
||||||
gsosReinstall=1
|
gsosReinstall=1
|
||||||
if [[ -f "$gsosDir/SYSTEM/START.GS.OS" ]]; then
|
if [[ -f "$gsosDir/SYSTEM/START.GS.OS" ]]; then
|
||||||
@@ -179,7 +317,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
echo -n "Are you sure you want to delete your entire GS/OS System folder? "
|
echo -n "Are you sure you want to delete your entire GS/OS System folder? "
|
||||||
read
|
read
|
||||||
if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
rm -r "$gsosDir/SYSTEM/* $gsosDir/System/.AppleDouble/*" 2> /dev/null
|
rm -r "$gsosDir/System"/* "$gsosDir/System/.AppleDouble"/* 2> /dev/null
|
||||||
afpsync &> /dev/null
|
afpsync &> /dev/null
|
||||||
echo
|
echo
|
||||||
break
|
break
|
||||||
@@ -188,7 +326,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
echo -n "Are you sure you want to reinstall GS/OS over your existing system? "
|
echo -n "Are you sure you want to reinstall GS/OS over your existing system? "
|
||||||
read
|
read
|
||||||
if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
rm -r "$gsosDir/SYSTEM/START.GS.OS $gsosDir/System/.AppleDouble/START.GS.OS" 2> /dev/null
|
rm -r "$gsosDir/System/Start.GS.OS $gsosDir/System/.AppleDouble/Start.GS.OS" 2> /dev/null
|
||||||
afpsync &> /dev/null
|
afpsync &> /dev/null
|
||||||
echo
|
echo
|
||||||
break
|
break
|
||||||
@@ -203,11 +341,22 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
|
|
||||||
if [[ $gsosReinstall ]]; then
|
if [[ $gsosReinstall ]]; then
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
if [[ ! $autoAnswerYes ]]; then
|
||||||
|
echo
|
||||||
echo "You can set up GS/OS for network boot. This may take a while."
|
echo "You can set up GS/OS for network boot. This may take a while."
|
||||||
|
echo
|
||||||
echo " 0: don't install GS/OS"
|
echo " 0: don't install GS/OS"
|
||||||
echo "1: GS/OS 6.0.1 (official Apple release, May 1993)"
|
echo " 1: GS/OS 6.0.1 (May 1993) [official release]"
|
||||||
echo "2: GS/OS 6.0.2 (community release by Antoine Vignau, July 2015)"
|
echo " The final version authorized by Apple. It has a few bugs,"
|
||||||
echo "3: GS/OS 6.0.3 (community release by Tony Diaz, August 2015)"
|
echo " but most of these can be patched. Predictable and might be"
|
||||||
|
echo " required if you use certain patches."
|
||||||
|
echo " 2: GS/OS 6.0.2 (Jul 2015)"
|
||||||
|
echo " A community effort released by Antoine Vignau with fixes for"
|
||||||
|
echo " some serious bugs and a few other enhancements."
|
||||||
|
echo " 3: GS/OS 6.0.3 (Aug 2015)"
|
||||||
|
echo " Continuing community effort released by Tony Diaz. Includes"
|
||||||
|
echo " previous work along with additional fixes/changes. Better"
|
||||||
|
echo " documentation of changes. Most will prefer this or Apple's"
|
||||||
|
echo " release above."
|
||||||
echo
|
echo
|
||||||
echo -n "Which flavor would you like? "
|
echo -n "Which flavor would you like? "
|
||||||
read
|
read
|
||||||
@@ -225,6 +374,8 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
# echo
|
# echo
|
||||||
echo
|
echo
|
||||||
echo "A2SERVER: Downloading GS/OS 6.0.${gsosInstall} installer disk images..."
|
echo "A2SERVER: Downloading GS/OS 6.0.${gsosInstall} installer disk images..."
|
||||||
|
mkdir -p /tmp/netboot
|
||||||
|
rm -r /tmp/netboot/* 2> /dev/null
|
||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
mkdir -p $imagesDir
|
mkdir -p $imagesDir
|
||||||
mkdir -p $netInstallDir
|
mkdir -p $netInstallDir
|
||||||
@@ -242,8 +393,8 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# delete previously downloaded installer
|
# delete previously downloaded installer
|
||||||
rm "$imagesDir/* $imagesDir/.AppleDouble/*" 2> /dev/null
|
rm "$imagesDir/* $imagesDir/.AppleDouble"/* 2> /dev/null
|
||||||
rm "$netInstallDir/* $netInstallDir/.AppleDouble/*" 2> /dev/null
|
rm "$netInstallDir/* $netInstallDir/.AppleDouble"/* 2> /dev/null
|
||||||
afpsync -v $gsosDir > /dev/null
|
afpsync -v $gsosDir > /dev/null
|
||||||
|
|
||||||
for diskname in ${diskNames[@]}; do
|
for diskname in ${diskNames[@]}; do
|
||||||
@@ -280,7 +431,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
wget -qO $outfile "${binaryURL}external/appleii/gsos603/$diskname.po"
|
wget -qO $outfile "${binaryURL}external/appleii/gsos603/$diskname.po"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
cppo -s -ad $outfile $netInstallDir 2> /dev/null
|
cppo -s -ad $outfile $netInstallDir
|
||||||
done
|
done
|
||||||
rm *.sea* &> /dev/null
|
rm *.sea* &> /dev/null
|
||||||
sed -i "s/\([^\\]\r:\)/\1A2FILES:GSOS.Installer:Net.Install:/g" $netInstallDir/Install/Scripts/*
|
sed -i "s/\([^\\]\r:\)/\1A2FILES:GSOS.Installer:Net.Install:/g" $netInstallDir/Install/Scripts/*
|
||||||
@@ -336,6 +487,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
}
|
}
|
||||||
|
|
||||||
mkdir -p /tmp/netboot
|
mkdir -p /tmp/netboot
|
||||||
|
rm -r /tmp/netboot/* 2> /dev/null
|
||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
|
|
||||||
echo "A2SERVER: Preparing GS/OS installer scripts..."
|
echo "A2SERVER: Preparing GS/OS installer scripts..."
|
||||||
@@ -360,21 +512,50 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes && gsosInstall -lt 2 ]]; then
|
# if [[ ! $autoAnswerYes && (! $gsosInstall || $gsosInstall -lt 2) ]] && ! checkP8YearTables 603; then
|
||||||
echo
|
# echo
|
||||||
echo -n "Do you want to update the ProDOS 8 year tables? "
|
# echo -n "Do you want to update the ProDOS 8 Thunderclock year table? "
|
||||||
read
|
# read
|
||||||
fi
|
# fi
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
# if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
updateP8YearTables
|
# updateP8YearTables 603
|
||||||
fi
|
# elif [[ $gsosInstall -ge 2 ]]; then
|
||||||
|
# updateP8YearTables 60${gsosInstall}
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# patch ProDOS 8 Thunderclock driver year table based on today's date
|
||||||
|
echo
|
||||||
|
echo "A2SERVER: Updating ProDOS 8 Thunderclock driver year table..."
|
||||||
|
mkdir -p /tmp/netboot
|
||||||
|
rm -r /tmp/netboot/* 2> /dev/null
|
||||||
|
wget -qO /tmp/netboot/clock.patch.py "${scriptURL}scripts/clock.patch.py"
|
||||||
|
updateP8YearTables $(python /tmp/netboot/clock.patch.py $(LANG=C date +"%a %m/%d/%y"))
|
||||||
|
|
||||||
|
gsosInstalled=""
|
||||||
|
[[ -f "$gsosDir/System/Start.GS.OS" ]] && gsosInstalled="GS/OS and "
|
||||||
|
p8ToolsInstalled=
|
||||||
|
[[ -f $diskToolsP8Dir/SHRINKIT && -f $diskToolsP8Dir/DSK2FILE && -f $diskToolsP8Dir/SYSUTIL ]] && p8ToolsInstalled=1
|
||||||
|
gsosToolsInstalled=
|
||||||
|
[[ -f $imageToolsDir/Asimov && -f $gsosDir/System/System.Setup/MountIt && -f $imageToolsDir/GSHK ]] && gsosToolsInstalled=1
|
||||||
|
toolsInstalled=
|
||||||
|
if [[ $gsosInstalled ]]; then
|
||||||
|
[[ $gsosToolsInstalled && $p8ToolsInstalled ]] && toolsInstalled=1
|
||||||
|
else
|
||||||
|
toolsInstalled=$p8ToolsInstalled
|
||||||
|
fi
|
||||||
|
REPLY=
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
if [[ ! $autoAnswerYes ]]; then
|
||||||
|
if [[ ! $toolsInstalled ]]; then
|
||||||
echo
|
echo
|
||||||
echo "Do you want to download and install utilities for working with"
|
echo "Do you want to download and install utilities for working with"
|
||||||
echo -n "disk images and archive files in GS/OS? "
|
echo -n "disk images and archive files in ${gsosInstalled}ProDOS 8? "
|
||||||
read
|
read
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "A2SERVER: Disk image and archive utilities are already installed."
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
if [[ $gsosInstalled ]]; then
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
|
|
||||||
# download image tools and put them in IMAGE.TOOLS
|
# download image tools and put them in IMAGE.TOOLS
|
||||||
@@ -390,6 +571,9 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -qO Asimov.shk http://www.ninjaforce.com/downloads/Asimov.shk
|
wget -qO Asimov.shk http://www.ninjaforce.com/downloads/Asimov.shk
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
wget -qO Asimov.shk http://web.archive.org/web/20160330184627/http://www.ninjaforce.com/downloads/Asimov.shk
|
||||||
|
fi
|
||||||
nulib2 -x -s Asimov.shk &> /dev/null
|
nulib2 -x -s Asimov.shk &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -d Asimov ]]; then
|
if [[ ! -d Asimov ]]; then
|
||||||
@@ -411,8 +595,10 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
mkdir -p /tmp/netboot/gshk
|
mkdir -p /tmp/netboot/gshk
|
||||||
cd /tmp/netboot/gshk
|
cd /tmp/netboot/gshk
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
|
wget -qO gshk11.sea http://www.nulib.com/library/gshk11.sea
|
||||||
|
if (( $? != 0 )); then
|
||||||
wget -qO gshk11.sea http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea
|
wget -qO gshk11.sea http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea
|
||||||
#wget -qO gshk11.sea http://www.nulib.com/library/gshk11.sea
|
fi
|
||||||
nulib2 -x -s gshk11.sea &> /dev/null
|
nulib2 -x -s gshk11.sea &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -f GSHK ]]; then
|
if [[ ! -f GSHK ]]; then
|
||||||
@@ -428,31 +614,34 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
|
|
||||||
echo -n "MountIt 1.4"
|
echo -n "MountIt 1.4"
|
||||||
# get MountIt (for GS/OS)
|
# get MountIt (for GS/OS)
|
||||||
if [[ -f $imageToolsDir/MOUNTIT.SHK ]]; then
|
if [[ -f $gsosDir/System/System.Setup/MountIt ]]; then
|
||||||
echo " is already installed."
|
echo " is already installed."
|
||||||
else
|
else
|
||||||
echo
|
echo
|
||||||
cd /tmp/netboot
|
mkdir -p /tmp/netboot/mountit
|
||||||
|
cd /tmp/netboot/mountit
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -q -O MOUNTIT.SHK http://www.brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK
|
wget -q -O MOUNTIT.SHK http://www.brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
wget -q -O http://web.archive.org/web/20150201044930/http://brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK
|
||||||
fi
|
fi
|
||||||
if [[ $? -ne 0 || ! -f MOUNTIT.SHK ]]; then
|
cppo -s -ad MOUNTIT.SHK System:System.Setup:MountIt . &> /dev/null
|
||||||
|
cppo -s -ad MOUNTIT.SHK ReadMe . &> /dev/null
|
||||||
|
fi
|
||||||
|
if [[ ! -f ReadMe ]]; then
|
||||||
wget -qO MOUNTIT.SHK ${binaryURL}external/appleii/MOUNTIT.SHK
|
wget -qO MOUNTIT.SHK ${binaryURL}external/appleii/MOUNTIT.SHK
|
||||||
|
cppo -s -ad MOUNTIT.SHK System:System.Setup:MountIt . &> /dev/null
|
||||||
|
cppo -s -ad MOUNTIT.SHK ReadMe . &> /dev/null
|
||||||
fi
|
fi
|
||||||
cp -p MOUNTIT.SHK $imageToolsDir/MOUNTIT.SHK
|
cpAD ./MountIt $gsosDir/System/System.Setup
|
||||||
|
mkdir -p $gsosDir/GSOS.Installer/Image.Tools/MountIt
|
||||||
|
cpAD ./ReadMe $gsosDir/GSOS.Installer/Image.Tools/MountIt
|
||||||
afpsync -v $gsosDir > /dev/null
|
afpsync -v $gsosDir > /dev/null
|
||||||
afptype -p SHK -q $imageToolsDir/MOUNTIT.SHK
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
|
||||||
echo
|
|
||||||
echo "Do you want to download and install utilities for working with"
|
|
||||||
echo -n "disk images and archive files in ProDOS 8? "
|
|
||||||
read
|
|
||||||
fi
|
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
|
|
||||||
echo "A2SERVER: Downloading ProDOS 8 disk image utilities..."
|
echo "A2SERVER: Downloading ProDOS 8 disk image utilities..."
|
||||||
|
|
||||||
mkdir -p $diskToolsP8Dir
|
mkdir -p $diskToolsP8Dir
|
||||||
@@ -465,14 +654,17 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
echo
|
echo
|
||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
|
wget -qO shrinkit.sdk http://www.nulib.com/library/shrinkit.sdk
|
||||||
|
if (( $? != 0 )); then
|
||||||
wget -qO shrinkit.sdk http://web.archive.org/web/20131031160750/http://www.nulib.com/library/shrinkit.sdk
|
wget -qO shrinkit.sdk http://web.archive.org/web/20131031160750/http://www.nulib.com/library/shrinkit.sdk
|
||||||
nulib2 -x -s shrinkit.sdk &> /dev/null
|
|
||||||
fi
|
fi
|
||||||
if [[ ! -f SHRINKIT ]]; then
|
nulib2 -x -s -e shrinkit.sdk &> /dev/null
|
||||||
|
fi
|
||||||
|
if [[ ! -f "SHRINKIT#000118i" ]]; then
|
||||||
wget -qO shrinkit.sdk ${binaryURL}external/appleii/shrinkit.sdk
|
wget -qO shrinkit.sdk ${binaryURL}external/appleii/shrinkit.sdk
|
||||||
nulib2 -x -s shrinkit.sdk &> /dev/null
|
nulib2 -x -s -e shrinkit.sdk &> /dev/null
|
||||||
fi
|
fi
|
||||||
cppo -s -ad SHRINKIT /SHRINKIT/SHRINKIT $diskToolsP8Dir 2> /dev/null
|
cppo -s -ad "SHRINKIT#000118i" /SHRINKIT/SHRINKIT $diskToolsP8Dir &> /dev/null
|
||||||
afpsync -v $sharepath > /dev/null
|
afpsync -v $sharepath > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -485,6 +677,9 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
cd /tmp/netboot
|
cd /tmp/netboot
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -q -O dsk2file.shk http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip
|
wget -q -O dsk2file.shk http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
wget -q -O dsk2file.shk http://web.archive.org/web/20120726132356/http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip
|
||||||
|
fi
|
||||||
nulib2 -x -s dsk2file.shk &> /dev/null
|
nulib2 -x -s dsk2file.shk &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -f DSK2FILE58 ]]; then
|
if [[ ! -f DSK2FILE58 ]]; then
|
||||||
@@ -506,8 +701,8 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
wget --max-redirect 0 -qO Apple_II_System_Disk_3.2.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_II_Supplemental/Apple_II_System_Disk_3.2.sea.bin
|
wget --max-redirect 0 -qO Apple_II_System_Disk_3.2.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_II_Supplemental/Apple_II_System_Disk_3.2.sea.bin
|
||||||
if (( $? != 0 )); then
|
if (( $? != 0 )); then
|
||||||
wget -qO Apple_II_System_Disk_3.2.sea.bin http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_II_Supplemental%2FApple_II_System_Disk_3.2.sea.bin
|
wget -qO Apple_II_System_Disk_3.2.sea.bin http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_II_Supplemental%2FApple_II_System_Disk_3.2.sea.bin
|
||||||
unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null
|
|
||||||
fi
|
fi
|
||||||
|
unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ ! -f 'Apple II System Disk 3.2.sea' ]]; then
|
if [[ ! -f 'Apple II System Disk 3.2.sea' ]]; then
|
||||||
wget -qO Apple_II_System_Disk_3.2.sea.bin ${binaryURL}external/appleii/Apple_II_System_Disk_3.2.sea.bin
|
wget -qO Apple_II_System_Disk_3.2.sea.bin ${binaryURL}external/appleii/Apple_II_System_Disk_3.2.sea.bin
|
||||||
@@ -515,21 +710,36 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
fi
|
fi
|
||||||
truncate -s 819284 'Apple II System Disk 3.2.sea'
|
truncate -s 819284 'Apple II System Disk 3.2.sea'
|
||||||
dd if='Apple II System Disk 3.2.sea' of=A2SYSDISK32.HDV bs=84 skip=1 2> /dev/null
|
dd if='Apple II System Disk 3.2.sea' of=A2SYSDISK32.HDV bs=84 skip=1 2> /dev/null
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/SYSUTIL.SYSTEM $diskToolsP8Dir/SYSUTIL 2> /dev/null
|
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/SYSUTIL.SYSTEM $diskToolsP8Dir/SYSUTIL &> /dev/null
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.0 $diskToolsP8Dir 2> /dev/null
|
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.0 $diskToolsP8Dir &> /dev/null
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.1 $diskToolsP8Dir 2> /dev/null
|
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.1 $diskToolsP8Dir &> /dev/null
|
||||||
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.2 $diskToolsP8Dir 2> /dev/null
|
cppo -s -ad A2SYSDISK32.HDV /UTILITIES/UTIL.2 $diskToolsP8Dir &> /dev/null
|
||||||
afpsync -v $sharepath > /dev/null
|
afpsync -v $sharepath > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
p8CommInstalled=
|
||||||
|
[[ -f $commDir/ProTERM/PROTERM && -f $commDir/Z.Link/Z.LINK && -f $commDir/ADTPro/ADTPRO && -f $commDir/ADTPro/VSDRIVE ]] && p8CommInstalled=1
|
||||||
|
gsosCommInstalled=
|
||||||
|
[[ -f $commDir/Spectrum/Spectrum && -f $commDir/SAM2/SAM2 && -f $commDir/SAFE2/SAFE2 && -f $commDir/SNAP/SNAP && -f $gsosDir/System/CDevs/TCPIP ]] && gsosCommInstalled=1
|
||||||
|
commInstalled=
|
||||||
|
if [[ $gsosInstalled ]]; then
|
||||||
|
[[ $gsosCommInstalled && $p8CommInstalled ]] && commInstalled=1
|
||||||
|
else
|
||||||
|
commInstalled=$p8CommInstalled
|
||||||
|
fi
|
||||||
|
REPLY=
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
if [[ ! $autoAnswerYes ]]; then
|
||||||
[[ -f "$gsosDir/SYSTEM/START.GS.OS" ]] && gsosInstalled="GS/OS and " || gsosInstalled=
|
if [[ ! $commInstalled ]]; then
|
||||||
echo
|
echo
|
||||||
echo "Do you want to download communications software for"
|
echo "Do you want to download communications software for"
|
||||||
echo -n "$gsosInstalled""ProDOS 8? "
|
echo -n "$gsosInstalled""ProDOS 8? "
|
||||||
read
|
read
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "A2SERVER: Communications software is already installed."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
|
|
||||||
@@ -537,42 +747,42 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
|
|
||||||
mkdir -p $commDir
|
mkdir -p $commDir
|
||||||
|
|
||||||
|
if [[ $gsosInstalled ]]; then
|
||||||
|
|
||||||
|
unset safeUrl samUrl snapUrl safeVer samVer snapVer
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
safeUrl=$(wget -qO- http://speccie.uk/software/safe2/ | grep -i 'safe2.*bxy' | tr '<>' '\n' | grep href | cut -d '=' -f 2 | tr -d '"')
|
||||||
|
samUrl=$(wget -qO- http://speccie.uk/software/sam2/ | grep -i 'sam2.*bxy' | tr '<>' '\n' | grep href | cut -d '=' -f 2 | tr -d '"')
|
||||||
|
snapUrl=$(wget -qO- http://speccie.uk/software/snap/ | grep -i 'snap.*bxy' | tr '<>' '\n' | grep href | cut -d '=' -f 2 | tr -d '"')
|
||||||
|
safeVer=$(echo $safeUrl | rev | cut -d '/' -f 1 | cut -d '.' -f 2 | rev | cut -c 5- | sed 's/./.&/g' | cut -c 2-)
|
||||||
|
samVer=$(echo $samUrl | rev | cut -d '/' -f 1 | cut -d '.' -f 2 | rev | cut -c 4- | sed 's/./.&/g' | cut -c 2-)
|
||||||
|
snapVer=$(echo $snapUrl | rev | cut -d '/' -f 1 | cut -d '.' -f 2 | rev | cut -c 5- | sed 's/./.&/g' | cut -c 2-)
|
||||||
|
fi
|
||||||
|
|
||||||
echo -n "Spectrum"
|
echo -n "Spectrum"
|
||||||
# get Spectrum
|
# get Spectrum
|
||||||
if [[ -f $spectrumDir/SPECTRUM.HDV || -f $spectrumDir/Spectrum ]]; then
|
if [[ -f $commDir/Spectrum/Spectrum ]]; then
|
||||||
echo " is already installed."
|
echo " is already installed."
|
||||||
else
|
else
|
||||||
mkdir -p $spectrumDir
|
|
||||||
echo
|
echo
|
||||||
|
mkdir -p $commDir/Spectrum
|
||||||
|
# remove images that might have been installed by 1.2.5
|
||||||
|
cd $commDir/Spectrum
|
||||||
|
rm SPECTRUM.HDV MANUALS.HDV SOUNDS.HDV EXTRAS.HDV &> /dev/null
|
||||||
|
# install Spectrum into GS/OS
|
||||||
mkdir -p /tmp/netboot/spectrum
|
mkdir -p /tmp/netboot/spectrum
|
||||||
cd /tmp/netboot/spectrum
|
cd /tmp/netboot/spectrum
|
||||||
if [[ ! -f $gsosDir/SYSTEM/START.GS.OS ]]; then
|
|
||||||
#if true; then
|
|
||||||
# provide disk images for MountIt if no GS/OS present
|
|
||||||
for filename in spectrum.2mg spectrum_extras.2mg spectrum_sounds.2mg spectrum_manuals.2mg; do
|
|
||||||
if [[ $useExternalURL ]]; then
|
if [[ $useExternalURL ]]; then
|
||||||
wget -qO $filename http://www.speccie.co.uk/speccie/software/$filename
|
wget -qO spectrum_gold_2mg.zip http://speccie.uk/speccie/downloads/spectrum_gold_2mg.zip
|
||||||
|
unzip spectrum_gold_2mg.zip Spectrum.Gold.2mg &> /dev/null
|
||||||
fi
|
fi
|
||||||
if [[ $? -ne 0 || ! -f $filename ]]; then
|
if [[ ! -f Spectrum.Gold.2mg || $(wc -c < Spectrum.Gold.2mg) -eq 0 ]]; then
|
||||||
wget -qO $filename ${binaryURL}external/appleii/spectrum/$filename
|
wget -qO spectrum_gold_2mg.zip ${binaryURL}external/appleii/spectrum_gold_2mg.zip
|
||||||
|
unzip spectrum_gold_2mg.zip Spectrum.Gold.2mg &> /dev/null
|
||||||
fi
|
fi
|
||||||
dd bs=64 skip=1 if=$filename of=$spectrumDir/${filename,,}.HDV 2> /dev/null
|
cppo -s -ad Spectrum.Gold.2mg . &> /dev/null
|
||||||
done
|
|
||||||
echo -n "The Spectrum installer disk image files can be converted to floppy disks with Asimov or DSK2FILE, or mounted directly with MountIt. If using MountIt, mount bouth SPECTRUM.HDV and EXTRAS.HDV before running the installer." > $spectrumDir/SPECTRUM.README
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
|
||||||
afptype -p TXT -q $spectrumDir/SPECTRUM.README
|
|
||||||
else
|
|
||||||
# install Spectrum into GS/OS
|
|
||||||
if [[ $useExternalURL ]]; then
|
|
||||||
wget -qO spectrum_gold_2mg.zip http://www.speccie.co.uk/speccie/software/spectrum_gold_2mg.zip
|
|
||||||
unzip -p spectrum_gold_2mg.zip 2> /dev/null | dd bs=64 skip=1 of=Spectrum.Gold.HDV 2> /dev/null
|
|
||||||
fi
|
|
||||||
if [[ ! -f Spectrum.Gold.2mg ]]; then
|
|
||||||
wget -qO spectrum_gold_2mg.zip ${binaryURL}external/appleii/spectrum/spectrum_gold_2mg.zip
|
|
||||||
unzip -p spectrum_gold_2mg.zip 2> /dev/null | dd bs=64 skip=1 of=Spectrum.Gold.HDV 2> /dev/null
|
|
||||||
fi
|
|
||||||
cppo -s -ad Spectrum.Gold.HDV .
|
|
||||||
userFolder=$(tr [:lower:] [:upper:] <<< $USER)
|
userFolder=$(tr [:lower:] [:upper:] <<< $USER)
|
||||||
|
|
||||||
for thisFolder in \
|
for thisFolder in \
|
||||||
Installer/Extras/CDEvs^System/CDevs \
|
Installer/Extras/CDEvs^System/CDevs \
|
||||||
Installer/Extras/Tools^System/Tools \
|
Installer/Extras/Tools^System/Tools \
|
||||||
@@ -580,10 +790,10 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
Installer/Extras/System.Setup^System/System.Setup \
|
Installer/Extras/System.Setup^System/System.Setup \
|
||||||
Installer/Help^System/Desk.Accs \
|
Installer/Help^System/Desk.Accs \
|
||||||
Installer/Spectrum.Sounds^System/Sounds \
|
Installer/Spectrum.Sounds^System/Sounds \
|
||||||
Spectrum.2.5.4/Add.Ons^USERS/$userFolder/Add.Ons \
|
Spectrum.*/Add.Ons^USERS/$userFolder/Add.Ons \
|
||||||
Spectrum.2.5.4/Spectrum.Script^USERS/$userFolder/Spectrum.Script \
|
Spectrum.*/Spectrum.Script^USERS/$userFolder/Spectrum.Script \
|
||||||
Spectrum.2.5.4/Add.Ons^Comm/Spectrum/Add.Ons \
|
Spectrum.*/Add.Ons^Comm/Spectrum/Add.Ons \
|
||||||
Spectrum.2.5.4/Spectrum.Script^Comm/Spectrum/Spectrum.Script \
|
Spectrum.*/Spectrum.Script^Comm/Spectrum/Spectrum.Script \
|
||||||
Manuals^Comm/Spectrum/Manuals
|
Manuals^Comm/Spectrum/Manuals
|
||||||
do
|
do
|
||||||
mkdir -p $gsosDir/"${thisFolder##*^}"
|
mkdir -p $gsosDir/"${thisFolder##*^}"
|
||||||
@@ -591,46 +801,231 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
mkdir -p $gsosDir/"${thisFolder##*^}"/.AppleDouble
|
mkdir -p $gsosDir/"${thisFolder##*^}"/.AppleDouble
|
||||||
cp -R Spectrum.Gold/${thisFolder%%^*}/.AppleDouble/* $gsosDir/"${thisFolder##*^}"/.AppleDouble
|
cp -R Spectrum.Gold/${thisFolder%%^*}/.AppleDouble/* $gsosDir/"${thisFolder##*^}"/.AppleDouble
|
||||||
done
|
done
|
||||||
mv Spectrum.Gold/Installer/SoundPatch Spectrum.Gold/Spectrum.2.5.4/Spectrum $spectrumDir
|
cpAD Spectrum.Gold/Installer/SoundPatch $commDir/Spectrum
|
||||||
mkdir -p $spectrumDir/.AppleDouble
|
cpAD Spectrum.Gold/Spectrum.*/Spectrum $commDir/Spectrum
|
||||||
mv Spectrum.Gold/Installer/.AppleDouble/SoundPatch Spectrum.Gold/Spectrum.2.5.4/.AppleDouble/Spectrum $spectrumDir/.AppleDouble
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
afpsync -v $gsosDir > /dev/null
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "ProTERM and Z-Link"
|
echo -n "Marinetti 3.0b8"
|
||||||
# get A2CLOUD disk and copy from there
|
if [[ -f $gsosDir/System/CDevs/TCPIP ]]; then
|
||||||
if [[ -f $protermDir/PROTERM ]]; then
|
echo " is already installed."
|
||||||
echo " are already installed."
|
|
||||||
else
|
else
|
||||||
mkdir -p $protermDir
|
|
||||||
mkdir -p $protermDir/.AppleDouble
|
|
||||||
mkdir -p $zlinkDir
|
|
||||||
mkdir -p $zlinkDir/.AppleDouble
|
|
||||||
echo
|
echo
|
||||||
cd /tmp/netboot
|
mkdir -p /tmp/netboot/marinetti
|
||||||
wget -qO A2CLOUD.HDV "${binaryURL}A2CLOUD.HDV"
|
cd /tmp/netboot/marinetti
|
||||||
cppo -ad A2CLOUD.HDV . > /dev/null
|
|
||||||
cd A2CLOUD
|
# Marinetti 3.0b1 -- had to repackage because installer is GS/OS self-contained app
|
||||||
mv *PT3* *PROTERM* $protermDir
|
wget -qO MarinettiB1.SHK ${binaryURL}appleii/MarinettiB1.SHK
|
||||||
mv Z.LINK $zlinkDir
|
cppo -ad -s -n MarinettiB1.SHK $gsosDir > /dev/null
|
||||||
cd .AppleDouble
|
|
||||||
mv *PT3* *PROTERM* $protermDir/.AppleDouble
|
# TCP/IP update (3.0b8)
|
||||||
mv Z.LINK $zlinkDir/.AppleDouble
|
if [[ $useExternalURL ]]; then
|
||||||
|
wget -qO Marinetti3.0b8.po http://www.a2retrosystems.com/downloads/Marinetti3.0b8.po
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
wget -qO Marinetti3.0b8.po http://web.archive.org/web/20171105043713/http://a2retrosystems.com/downloads/Marinetti3.0b8.po
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ $? != 0 || ! -f Marinetti3.0b8.po || $(wc -c < Marinetti3.0b8.po) != "819200" ]]; then
|
||||||
|
wget -qO Marinetti3.0b8.po ${binaryURL}external/appleii/Marinetti3.0b8.po
|
||||||
|
fi
|
||||||
|
cppo -ad Marinetti3.0b8.po /MARINETTI3.0B8/TCPIP $gsosDir/System/System.Setup > /dev/null
|
||||||
|
cppo -ad Marinetti3.0b8.po /MARINETTI3.0B8/CHANGELOG.3.0B8 $commDir/Marinetti > /dev/null
|
||||||
|
|
||||||
|
# PPP Scripted Link Layer update (1.3d4)
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
wget -qO PPPX.1.3d4.SHK http://www.apple2.org/marinetti/PPPX.1.3d4.SHK
|
||||||
|
fi
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
wget -qO PPPX.1.3d4.SHK http://web.archive.org/web/20160331231844/http://www.apple2.org/marinetti/PPPX.1.3d4.SHK
|
||||||
|
fi
|
||||||
|
if [[ $? != 0 || ! -f PPPX.1.3d4.SHK || $(wc -c < PPPX.1.3d4.SHK) != "22068" ]]; then
|
||||||
|
wget -qO PPPX.1.3d4.SHK ${binaryURL}external/appleii/PPPX.1.3d4.SHK
|
||||||
|
fi
|
||||||
|
cppo -ad -s PPPX.1.3d4.SHK . > /dev/null
|
||||||
|
cd PPPX.1.3d4
|
||||||
|
cpAD PPP.scripted $gsosDir/System/TCPIP
|
||||||
|
cpAD PPP.Script.DOC $commDir/Marinetti/Documentation
|
||||||
|
mkdir -p $commDir/Marinetti/PPP.scripted
|
||||||
|
cpAD Connect.Script $commDir/Marinetti/PPP.scripted
|
||||||
|
cpAD ChangeLog $commDir/Marinetti/PPP.scripted
|
||||||
|
|
||||||
|
# Uthernet Link Layer
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
wget -qO uthernetll.bxy http://speccie.uk/speccie/downloads/uthernetll.bxy
|
||||||
|
fi
|
||||||
|
if [[ $? != 0 || ! -f uthernetll.bxy || $(wc -c < uthernetll.bxy) -eq 0 ]]; then
|
||||||
|
wget -qO uthernetll.bxy ${binaryURL}external/appleii/uthernetll.bxy
|
||||||
|
fi
|
||||||
|
cppo -ad -s -n uthernetll.bxy $gsosDir/System/TCPIP > /dev/null
|
||||||
|
|
||||||
|
# Uthernet II Link Layer
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
wget -qO uthernet2ll.bxy http://speccie.uk/speccie/downloads/uthernet2ll.bxy
|
||||||
|
fi
|
||||||
|
if [[ $? != 0 || ! -f uthernet2ll.bxy || $(wc -c < uthernet2ll.bxy) -eq 0 ]]; then
|
||||||
|
wget -qO uthernet2ll.bxy ${binaryURL}external/appleii/uthernet2ll.bxy
|
||||||
|
fi
|
||||||
|
cppo -ad -s -n uthernet2ll.bxy $gsosDir/System/TCPIP > /dev/null
|
||||||
|
|
||||||
|
# MacIP Link Layer settings for A2SERVER
|
||||||
|
wget -qO- ${binaryURL}macip-prefs.tgz | tar Pxz
|
||||||
|
|
||||||
afpsync -v $gsosDir > /dev/null
|
afpsync -v $gsosDir > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -n "ADTPro and VSDRIVE"
|
echo -n "SAFE2 $safeVer"
|
||||||
if [[ -f $adtproDir/ADTPRO ]]; then
|
if [[ -f $commDir/SAFE2/SAFE2 ]]; then
|
||||||
echo " are already installed."
|
echo " is already installed."
|
||||||
else
|
else
|
||||||
mkdir -p $adtproDir
|
echo
|
||||||
mkdir -p $adtproDir/.AppleDouble
|
mkdir -p $commDir/SAFE2
|
||||||
|
mkdir -p /tmp/netboot/safe2
|
||||||
|
cd /tmp/netboot/safe2
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
[[ ! $safeUrl ]] && safeUrl="http://speccie.uk/speccie/downloads/safe230.bxy"
|
||||||
|
wget -qO safe2.bxy "$safeUrl"
|
||||||
|
cppo -s -ad safe2.bxy . &> /dev/null
|
||||||
|
fi
|
||||||
|
if [[ ! -f SAFE2.Archive/Safe2 ]]; then
|
||||||
|
wget -qO safe2.bxy ${binaryURL}external/appleii/safe2.bxy
|
||||||
|
cppo -s -ad safe2.bxy . &> /dev/null
|
||||||
|
fi
|
||||||
|
cd SAFE2.Archive
|
||||||
|
cpAD Safe2 $commDir/SAFE2
|
||||||
|
cpAD The.Manual $commDir/SAFE2
|
||||||
|
cpAD Read.Me.First $commDir/SAFE2
|
||||||
|
cpAD Version.History $commDir/SAFE2
|
||||||
|
cpAD Fonts/SAFE.8 $gsosDir/System/Fonts
|
||||||
|
cpAD Fonts/Shaston.16 $gsosDir/System/Fonts
|
||||||
|
cpAD TimeZone/TimeZone $gsosDir/System/CDEvs
|
||||||
|
cpAD TimeZone/Tool056 $gsosDir/System/Tools
|
||||||
|
rm -r $gsosDir/System/Desk.Accs/Help.Files/SAFE2 2> /dev/null
|
||||||
|
mv Help/Help.Files/SAFE2 $gsosDir/System/Desk.Accs/Help.Files
|
||||||
|
wget -qO- ${binaryURL}safe2-setup.tgz | tar Pzx
|
||||||
|
|
||||||
|
afpsync -v $gsosDir > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "SAM2 $samVer"
|
||||||
|
if [[ -f $commDir/SAM2/SAM2 ]]; then
|
||||||
|
echo " is already installed."
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
mkdir -p $commDir/SAM2
|
||||||
|
mkdir -p $commDir/SAM2/SAM2.Data
|
||||||
|
mkdir -p /tmp/netboot/sam2
|
||||||
|
cd /tmp/netboot/sam2
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
[[ ! $samUrl ]] && samUrl="http://speccie.uk/speccie/downloads/sam206.bxy"
|
||||||
|
wget -qO sam2.bxy "$samUrl"
|
||||||
|
cppo -s -ad sam2.bxy . &> /dev/null
|
||||||
|
fi
|
||||||
|
if [[ ! -f SAM2.Archive/SAM2/SAM2 ]]; then
|
||||||
|
wget -qO sam2.bxy ${binaryURL}external/appleii/sam2.bxy
|
||||||
|
cppo -s -ad sam2.bxy . &> /dev/null
|
||||||
|
fi
|
||||||
|
cd SAM2.Archive
|
||||||
|
cpAD SAM2/SAM2 $commDir/SAM2
|
||||||
|
cpAD SAM2/SAM2.Data/Taglines $commDir/SAM2/SAM2.Data
|
||||||
|
cpAD Sounds/SP.Snds.Aux $gsosDir/System/Sounds
|
||||||
|
cpAD Fonts/SAM.8 $gsosDir/System/Fonts
|
||||||
|
cpAD Fonts/SAM.10 $gsosDir/System/Fonts
|
||||||
|
cpAD The.Manual $commDir/SAM2
|
||||||
|
cpAD Read.Me.First $commDir/SAM2
|
||||||
|
cpAD Version.History $commDir/SAM2
|
||||||
|
rm -r $gsosDir/System/Desk.Accs/Help.Files/SAM2 2> /dev/null
|
||||||
|
mv Help/Help.Files/SAM2 $gsosDir/System/Desk.Accs/Help.Files
|
||||||
|
# cpAD Fonts/SIS.3.10 $gsosDir/System/Fonts
|
||||||
|
# cpAD Fonts/SIS.4.10 $gsosDir/System/Fonts
|
||||||
|
# cpAD Tools/HTMLTool/TOOL130 $gsosDir/System/Tools
|
||||||
|
# cpAD Tools/Hierarchic/Hierarchic $gsosDir/System/CDEvs
|
||||||
|
# cpAD Fonts/Shaston.16 $gsosDir/System/Fonts
|
||||||
|
|
||||||
|
afpsync -v $gsosDir > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "SNAP $snapVer"
|
||||||
|
if [[ -f $commDir/SNAP/SNAP ]]; then
|
||||||
|
echo " is already installed."
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
mkdir -p $commDir/SNAP
|
||||||
|
mkdir -p /tmp/netboot/snap
|
||||||
|
cd /tmp/netboot/snap
|
||||||
|
if [[ $useExternalURL ]]; then
|
||||||
|
[[ ! $snapUrl ]] && snapUrl="http://speccie.uk/speccie/downloads/snap118.bxy"
|
||||||
|
wget -qO snap.bxy "$snapUrl"
|
||||||
|
cppo -s -ad snap.bxy . &> /dev/null
|
||||||
|
fi
|
||||||
|
if [[ ! -f SNAP.Archive/SNAP ]]; then
|
||||||
|
wget -qO snap.bxy ${binaryURL}external/appleii/snap.bxy
|
||||||
|
cppo -s -ad snap.bxy . &> /dev/null
|
||||||
|
fi
|
||||||
|
cd SNAP.Archive
|
||||||
|
cpAD SNAP $commDir/SNAP
|
||||||
|
cpAD Fonts/SNAP.8 $gsosDir/System/Fonts
|
||||||
|
cpAD Fonts/SNAP.10 $gsosDir/System/Fonts
|
||||||
|
cpAD The.Manual $commDir/SNAP
|
||||||
|
cpAD Read.Me.First $commDir/SNAP
|
||||||
|
cpAD Change.List $commDir/SNAP
|
||||||
|
cpAD Quick.Start $commDir/SNAP
|
||||||
|
rm -r $gsosDir/System/Desk.Accs/Help.Files/SNAP 2> /dev/null
|
||||||
|
mv Help/Help.Files/SNAP $gsosDir/System/Desk.Accs/Help.Files
|
||||||
|
wget -qO- ${binaryURL}snap-setup.tgz | tar Pzx
|
||||||
|
# cpAD Fonts/SIS.3.10 $gsosDir/System/Fonts
|
||||||
|
# cpAD Fonts/SIS.4.10 $gsosDir/System/Fonts
|
||||||
|
# cpAD Tools/HTMLTool/TOOL130 $gsosDir/System/Tools
|
||||||
|
# cpAD Tools/Hierarchic/Hierarchic $gsosDir/System/CDEvs
|
||||||
|
# cpAD Fonts/Shaston.16 $gsosDir/System/Fonts
|
||||||
|
|
||||||
|
afpsync -v $gsosDir > /dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "ProTERM 3.1"
|
||||||
|
# get A2CLOUD disk and copy from there
|
||||||
|
if [[ -f $commDir/ProTERM/PROTERM ]]; then
|
||||||
|
echo " is already installed."
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
mkdir -p $commDir/ProTERM
|
||||||
|
mkdir -p $commDir/ProTERM/.AppleDouble
|
||||||
|
cd /tmp/netboot
|
||||||
|
wget -qO A2CLOUD.HDV "${binaryURL}appleii/A2CLOUD.HDV"
|
||||||
|
cppo -s -ad A2CLOUD.HDV . &> /dev/null
|
||||||
|
cd A2CLOUD
|
||||||
|
mv *PT3* *PROTERM* $commDir/ProTERM
|
||||||
|
cd .AppleDouble
|
||||||
|
mv *PT3* *PROTERM* $commDir/ProTERM/.AppleDouble
|
||||||
|
afpsync -v $gsosDir > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Z-Link 12-15-91"
|
||||||
|
# get A2CLOUD disk and copy from there
|
||||||
|
if [[ -f $commDir/Z.Link/Z.LINK ]]; then
|
||||||
|
echo " is already installed."
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
mkdir -p $commDir/Z.Link
|
||||||
|
mkdir -p $commDir/Z.Link/.AppleDouble
|
||||||
|
cd /tmp/netboot/A2CLOUD
|
||||||
|
mv Z.LINK $commDir/Z.Link
|
||||||
|
cd .AppleDouble
|
||||||
|
mv Z.LINK $commDir/Z.Link/.AppleDouble
|
||||||
|
afpsync -v $gsosDir > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "ADTPro 2.0.1"
|
||||||
|
if [[ -f $commDir/ADTPro/ADTPRO ]]; then
|
||||||
|
echo " is already installed."
|
||||||
|
else
|
||||||
|
mkdir -p $commDir/ADTPro
|
||||||
|
mkdir -p $commDir/ADTPro/.AppleDouble
|
||||||
echo
|
echo
|
||||||
cd /tmp/netboot/A2CLOUD
|
cd /tmp/netboot/A2CLOUD
|
||||||
mv *ADTPRO* *VEDRIVE* *VSDRIVE* $adtproDir
|
mv *ADTPRO* *VEDRIVE* *VSDRIVE* $commDir/ADTPro
|
||||||
cd .AppleDouble
|
cd .AppleDouble
|
||||||
mv *ADTPRO* *VEDRIVE* *VSDRIVE* $adtproDir/.AppleDouble
|
mv *ADTPRO* *VEDRIVE* *VSDRIVE* $commDir/ADTPro/.AppleDouble
|
||||||
afpsync -v $gsosDir > /dev/null
|
afpsync -v $gsosDir > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -651,31 +1046,30 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
REPLY=
|
||||||
|
if [[ -d $gsosDir/SYSTEM/SYSTEM.SETUP ]]; then
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
if [[ ! $autoAnswerYes ]]; then
|
||||||
|
if [[ ! -f $gsosDir/SYSTEM/SYSTEM.SETUP/ATALKIRQ ]]; then
|
||||||
echo
|
echo
|
||||||
echo "Do you want to download the patch required for using"
|
echo "Do you want to download the patch required for using"
|
||||||
echo -n "a Farallon LocalTalk-to-Ethernet bridge with GS/OS? "
|
echo -n "a Farallon LocalTalk-to-Ethernet bridge with GS/OS? "
|
||||||
read
|
read
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "A2SERVER: The Farallon bridge patch has already been installed."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
# Farallon bridge patch for GS/OS courtesy of Geoff Body
|
# Farallon bridge patch for GS/OS courtesy of Geoff Body
|
||||||
echo "A2SERVER: Downloading Farallon bridge patch..."
|
echo "A2SERVER: Downloading Farallon bridge patch..."
|
||||||
wget -O /tmp/FARALLON.PO "${binaryURL}FARALLON.B1.PO" &> /dev/null
|
wget -qO /tmp/FARALLON.PO "${binaryURL}appleii/FARALLON.B1.PO" &> /dev/null
|
||||||
if [[ -d $gsosDir/SYSTEM/SYSTEM.SETUP ]]; then
|
|
||||||
cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir/SYSTEM/SYSTEM.SETUP &> /dev/null
|
cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir/SYSTEM/SYSTEM.SETUP &> /dev/null
|
||||||
echo
|
echo
|
||||||
echo "A2SERVER: The Farallon bridge patch is installed."
|
echo "A2SERVER: The Farallon bridge patch is installed."
|
||||||
else
|
|
||||||
cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir &> /dev/null
|
|
||||||
echo
|
|
||||||
echo "On your Apple IIgs, copy the file ATALKIRQ in /A2SHARED to the"
|
|
||||||
echo "SYSTEM.SETUP folder of the SYSTEM folder of your GSOS startup disk,"
|
|
||||||
echo "or, if you can't, download the patch from the A2SERVER web site."
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
echo "Note: Farallon bridges can only be used in GS/OS (with this patch)"
|
echo "Note: Farallon bridges can only be used in GS/OS (with this patch)"
|
||||||
echo "and Apple IIe computers. Apple IIgs computers which network boot"
|
echo "and Apple IIe computers. Apple IIgs computers which network boot"
|
||||||
echo "directly into ProDOS 8 will freeze after a few minutes."
|
echo "directly into ProDOS 8 will freeze after a few minutes."
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
@@ -31,7 +31,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then
|
|||||||
# Dependency: samba for Windows/modern Macs
|
# Dependency: samba for Windows/modern Macs
|
||||||
# FIXME: Figure out when smbpasswd moved and adjust this as necessary
|
# FIXME: Figure out when smbpasswd moved and adjust this as necessary
|
||||||
sudo apt-get -y install samba
|
sudo apt-get -y install samba
|
||||||
command -v smbpasswd > /dev/null || sudo apt-get -y install samba-common-bin
|
hash smbpasswd &> /dev/null || sudo apt-get -y install samba-common-bin
|
||||||
sudo apt-get clean
|
sudo apt-get clean
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ password="your password"
|
|||||||
[[ $isRaspberryPw ]] && password="'raspberry'"
|
[[ $isRaspberryPw ]] && password="'raspberry'"
|
||||||
|
|
||||||
isDebian=
|
isDebian=
|
||||||
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "7." ) && ( $(uname -m) == "i686" ) ]] && isDebian=1
|
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 [[ $isDebian ]]; then
|
if [[ $isDebian ]]; then
|
||||||
if { lspci 2> /dev/null | grep -q VirtualBox; }; then
|
if { lspci 2> /dev/null | grep -q VirtualBox; }; then
|
||||||
|
180
scripts/clock.patch.py
Executable file
180
scripts/clock.patch.py
Executable file
@@ -0,0 +1,180 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
'''CLOCK.PATCH by Greg Branche implemented in Python 2/3 for A2SERVER
|
||||||
|
|
||||||
|
This is a line-for-line conversion of an edited version of CLOCK.PATCH
|
||||||
|
from the System Tools 2 disk in GS/OS 6.0.1. It's not good Python,
|
||||||
|
but I thought it would be an interesting exercise. In general
|
||||||
|
I have tried replicate each line as closely to BASIC as possible.
|
||||||
|
|
||||||
|
Because BASIC substrings are 1-based and python's are 0-based, various
|
||||||
|
indexes are minus one of their BASIC equivalents.
|
||||||
|
|
||||||
|
The one change is that you can optionally pass the day and date by
|
||||||
|
command line argument (e.g "Wed 3/13/15"). I also improved error
|
||||||
|
checking. These are in the BASIC lines that don't end in 0.
|
||||||
|
|
||||||
|
Rather than modifying PRODOS, this outputs a string of comma-separated
|
||||||
|
year values for a calling script (the a2server-setup installer),
|
||||||
|
followed by a space and a dd-Mmm-yy date string.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# imports for python 3 code compatibility
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
|
||||||
|
# other imports
|
||||||
|
import sys
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# substitute raw_input for input in Python2
|
||||||
|
try: input = raw_input
|
||||||
|
except NameError: pass
|
||||||
|
|
||||||
|
dow_str = None
|
||||||
|
day = None
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
dow_str = sys.argv[1] # day of week passed on command line
|
||||||
|
day = sys.argv[2] # date passed on command line
|
||||||
|
|
||||||
|
# 60000 REM # of days in each month
|
||||||
|
data = [31,28,31,30,31,30,31,31,30,31,30] # 60010 DATA 31,28,31,30,31,30,31,31,30,31,30
|
||||||
|
# 60020 REM Names of days of week
|
||||||
|
data += [ # 60030 DATA SUN,MON,TUE,WED,THU,FRI,SAT
|
||||||
|
"SUN","MON","TUE","WED","THU","FRI","SAT"]
|
||||||
|
data = iter(data)
|
||||||
|
# 110 REM cu() = cumulative # of days in year
|
||||||
|
cu = [0] * 13 # 120 DIM CU(12)
|
||||||
|
# 130 REM fill array with # of days in year
|
||||||
|
cu[1] = 0 # 140 CU(1) = 0: REM January
|
||||||
|
for i in range(2,13): # 150 FOR I = 2 TO 12
|
||||||
|
x = next(data) # 160 READ X
|
||||||
|
cu[i] = cu[i-1] + x # 170 CU(I) = CU(I - 1) + X
|
||||||
|
# 180 NEXT I
|
||||||
|
|
||||||
|
# 200 REM DN$() = Names for days of week
|
||||||
|
dn = [""] * 8 # 210 DIM DN$(7)
|
||||||
|
# 220 REM fill array with names of days of week
|
||||||
|
for i in range(1,8): # 230 FOR I = 1 TO 7
|
||||||
|
dn[i] = next(data) # 240 READ DN$(I)
|
||||||
|
# 250 NEXT I
|
||||||
|
|
||||||
|
# 270 REM yt() is the year table values
|
||||||
|
yt = [0] * 8 # 280 DIM YT(7)
|
||||||
|
|
||||||
|
def mod7(x): # 340 DEF FN MOD7(X) = INT (((X / 7) - INT (X / 7)) * 7 + .5)
|
||||||
|
return int(((x / 7) - int(x / 7)) * 7 + .5)
|
||||||
|
|
||||||
|
def find_slash_pos(day): # 799 REM Finds position of / within date string
|
||||||
|
x = -1 # 800 X = 0: REM On exit, contains position of /, or 0 if none found
|
||||||
|
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
|
||||||
|
|
||||||
|
while True: # 999 REM get the user's input and convert
|
||||||
|
if not day:
|
||||||
|
print( # 1010 PRINT "Please enter today's date (mm/dd/yy)"
|
||||||
|
"Please enter today's date (mm/dd/yy)")
|
||||||
|
day = input("-> ") # 1020 INPUT "-> ";DAY$
|
||||||
|
x = find_slash_pos(day) # 1030 GOSUB 800: REM find slash separator
|
||||||
|
input_ok = False
|
||||||
|
while not input_ok:
|
||||||
|
if not (x != -1): # 1040 IF X < > 0 THEN 1080
|
||||||
|
print( # 1050 PRINT "Invalid date entered. Please try again."; CHR$ (7)
|
||||||
|
"Invalid date entered. Please try again.\x07")
|
||||||
|
break # 1060 GOTO 1010
|
||||||
|
# 1070 REM Convert month value to numeric variable
|
||||||
|
mo = int(day[0:0+x]) # 1080 MO = VAL ( MID$ (DAY$,1,X - 1))
|
||||||
|
day = day[x+1:] # 1090 DAY$ = MID$ (DAY$,X + 1)
|
||||||
|
if mo < 1 or mo > 12: x = -1; continue # 1100 IF MO < 1 OR MO > 12 THEN 1050: REM Range check the month value
|
||||||
|
x = find_slash_pos(day) # 1110 GOSUB 800: REM Parse out the current day
|
||||||
|
if x == -1: continue # 1120 IF X = 0 THEN 1050
|
||||||
|
# 1130 REM Convert day string into numeric value
|
||||||
|
da = int(day[0:0+x]) # 1140 DA = VAL ( MID$ (DAY$,1,X - 1))
|
||||||
|
day = day[x+1:] # 1150 DAY$ = MID$ (DAY$,X + 1)
|
||||||
|
if da < 1 or da > 31: x = -1; continue # 1160 IF DA < 1 OR DA > 31 THEN 1050: REM Range check the day value
|
||||||
|
if mo == 2 and da > 29: # 1161 IF MO = 2 AND DA > 29 THEN 1050
|
||||||
|
x = -1; continue
|
||||||
|
if (mo == 4 or # 1162 IF (MO = 4 OR MO = 6 OR MO = 9 OR MO = 11) AND DA > 30 THEN 1050
|
||||||
|
mo == 6 or
|
||||||
|
mo == 9 or
|
||||||
|
mo == 11) and da > 30: x = -1; continue
|
||||||
|
# 1170 REM Convert year string into numeric value
|
||||||
|
yr = int(day) # 1180 YR = VAL (DAY$)
|
||||||
|
if yr < 0 or yr > 99: x = -1; continue # 1190 IF YR < 0 OR YR > 99 THEN 1050: REM Only allow 0-99
|
||||||
|
if yr > 39: yr = yr + 1900 # 1200 IF YR > 39 THEN YR = YR + 1900: REM 40-99 must be 1940-1999
|
||||||
|
if yr < 40: yr = yr + 2000 # 1210 IF YR < 40 THEN YR = YR + 2000: REM 0-39 must be 2000-2039
|
||||||
|
if ((yr / 4) != int(yr / 4) and # 1211 IF ((YR / 4) < > INT(YR / 4)) AND MO = 2 AND DA > 28 THEN 1050
|
||||||
|
mo == 2 and
|
||||||
|
da > 28): x = -1; continue
|
||||||
|
input_ok = True
|
||||||
|
if x != -1: break
|
||||||
|
else: dow_str = ""; day = ""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
if not dow_str:
|
||||||
|
print(
|
||||||
|
"Please enter the day of the week") # 1230 PRINT "Please enter the day of the week"
|
||||||
|
dow_str = input("(e.g. Wed) -> ") # 1240 INPUT "(e.g. Wed) -> ";DOW$
|
||||||
|
input_ok = False
|
||||||
|
while not input_ok:
|
||||||
|
if not (len(dow_str) >= 3): # 1250 IF LEN (DOW$) > = 3 THEN 1270: REM Must be at least 3 characters
|
||||||
|
print( # 1260 PRINT "Invalid day of week. Please try again."; CHR$ (7): GOTO 1230
|
||||||
|
"Invalid day of week. Please try again.\x07")
|
||||||
|
break
|
||||||
|
if len(dow_str) > 3: # 1270 IF LEN (DOW$) > 3 THEN DOW$ = LEFT$ (DOW$,3)
|
||||||
|
dow_str = dow_str[0:0+3]
|
||||||
|
# 1280 REM Shift any lower case letters to upper case
|
||||||
|
b = "" # 1290 B$ = ""
|
||||||
|
for i in range(0,3): # 1300 FOR I = 1 TO 3
|
||||||
|
a = dow_str[i:i+1] # 1310 A$ = MID$ (DOW$,I,1)
|
||||||
|
if ( # 1320 IF ASC (A$) > = ASC ("a") AND ASC (A$) < = ASC ("z") THEN A$ = CHR$ ( ASC (A$) - ( ASC ("a") - ASC ("A")))
|
||||||
|
ord(a) >= ord("a") and ord(a) <= ord("z")): a = chr(ord(a) - (ord("a") - ord("A")))
|
||||||
|
b = b + a # 1330 B$ = B$ + A$
|
||||||
|
# 1340 NEXT I
|
||||||
|
dow_str = b # 1350 DOW$ = B$
|
||||||
|
# 1360 REM Now convert day-of-week string to numeric value
|
||||||
|
dow_num = 0 # 1370 DOW = 0
|
||||||
|
for i in range (1,8): # 1380 FOR I = 1 TO 7
|
||||||
|
if dow_str == dn[i]: # 1390 IF DOW$ = DN$(I) THEN DOW = I:I = 7
|
||||||
|
dow_num = i; i = 7
|
||||||
|
# 1400 NEXT I
|
||||||
|
if dow_num == 0: dow_str = ""; continue # 1410 IF DOW = 0 THEN 1260
|
||||||
|
input_ok = True
|
||||||
|
if len(dow_str) >= 3: break
|
||||||
|
else: dow_str = ""; day = ""
|
||||||
|
# 1430 REM Calculate the number of days so far this year
|
||||||
|
dys = da + cu[mo] # 1440 DYS = DA + CU(MO)
|
||||||
|
oyr = yr
|
||||||
|
# 1450 REM Must account for extra day in leap year
|
||||||
|
if ((yr / 4) == int(yr / 4)) and (mo > 2): # 1460 IF (YR / 4) = INT (YR / 4) AND MO > 2 THEN DYS = DYS + 1
|
||||||
|
dys = dys + 1
|
||||||
|
|
||||||
|
# 1480 REM Now calculate the index to use to fill in the table
|
||||||
|
idx = dow_num - mod7(dys) + 1 # 1490 IDX = DOW - FN MOD7(DYS) + 1
|
||||||
|
idx = abs(idx - 10) # 1500 IDX = ABS (IDX - 10)
|
||||||
|
if idx > 7: idx = idx - 7 # 1510 IF IDX > 7 THEN IDX = IDX - 7
|
||||||
|
|
||||||
|
# 1530 REM Now we can fill in the year table
|
||||||
|
for i in range(1,8): # 1540 FOR I = 1 TO 7
|
||||||
|
if '_i' in vars() and i < (_i + 1): continue # python: simulate change of i within loop
|
||||||
|
x = yr - 1900 # 1550 X = YR - 1900
|
||||||
|
if x >= 100: x = x - 100 # 1560 IF X > = 100 THEN X = X - 100
|
||||||
|
yt[idx] = x # 1570 YT(IDX) = X: REM store the year into table
|
||||||
|
idx = idx - 1 # 1580 IDX = IDX - 1
|
||||||
|
if idx < 1: idx = 7 # 1590 IF IDX < 1 THEN IDX = 7
|
||||||
|
if not ((yr / 4) != int(yr / 4)): # 1600 IF (YR / 4) < > INT (YR / 4) THEN 1660: REM not a leap year
|
||||||
|
i = i + 1; _i = i # 1610 I = I + 1: REM update index
|
||||||
|
if i > 7: continue # 1620 IF I > 7 THEN 1670: REM if entire array done, exit
|
||||||
|
yt[idx] = x # 1630 YT(IDX) = X: REM duplicate entry for leap year
|
||||||
|
idx = idx - 1 # 1640 IDX = IDX - 1
|
||||||
|
if idx < 1: idx = 7 # 1650 IF IDX < 1 THEN IDX = 7
|
||||||
|
yr = yr + 1 # 1660 YR = YR + 1
|
||||||
|
# 1670 NEXT I
|
||||||
|
|
||||||
|
print(",".join([str(x) for x in yt[1:]]) + " " +
|
||||||
|
str(da).encode("L1").decode("L1").zfill(2) + "-" +
|
||||||
|
datetime.date(1900, mo, 1).strftime('%b') + "-" +
|
||||||
|
str(oyr).encode("L1").decode("L1")[2:])
|
@@ -2,17 +2,17 @@
|
|||||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||||
|
|
||||||
alias a2server-help="more /usr/local/etc/a2server-help.txt"
|
alias a2server-help="more /usr/local/etc/a2server-help.txt"
|
||||||
alias a2server-setup="wget -q -O /tmp/a2server-setup ${A2SERVER_SCRIPT_URL}setup/index.txt || { echo \"Can't download A2SERVER setup scripts. Do you has internet?\"; false; } && source /tmp/a2server-setup"
|
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-version="cat /usr/local/etc/A2SERVER-version"
|
||||||
alias a2server-update="wget -q -O /tmp/a2server-update ${A2SERVER_SCRIPT_URL}update/index.txt || { echo \"Can't download A2SERVER setup scripts. Do you has internet?\"; false; } && source /tmp/a2server-update"
|
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-shutdown='sudo shutdown -h now'
|
||||||
alias system-restart='sudo shutdown -r 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 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}scripts/raspbian-update.txt; source /tmp/raspbian-update'
|
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 rasppleii-update='raspbian-update a2cloud a2server'
|
||||||
|
|
||||||
alias welcome-message-edit='sudo nano /etc/motd'
|
alias welcome-message-edit='sudo nano /etc/motd'
|
||||||
@@ -33,8 +33,8 @@ alias bonjour-off="sudo mv /etc/avahi/services/afpd.service /etc/avahi/services/
|
|||||||
alias bonjour-on="sudo mv /etc/avahi/services/afpd.service_disabled /etc/avahi/services/afpd.service &> /dev/null"
|
alias bonjour-on="sudo mv /etc/avahi/services/afpd.service_disabled /etc/avahi/services/afpd.service &> /dev/null"
|
||||||
|
|
||||||
|
|
||||||
alias netatalk-router-on='sudo sed -i '"'"'s/^eth0.*$/eth0 -router -phase 2 -net 1 -zone "A2SERVER"/'"'"' /usr/local/etc/netatalk/atalkd.conf; sudo sed -i '"'"'s/^wlan0.*$/wlan0 -router -phase 2 -net 1 -zone "A2SERVER"/'"'"' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
alias netatalk-router-on='sudo sed -i '"'"'s/^\([^# ]*\)\( .*\)$/\1 -router\2 -zone "A2SERVER"/'"'"' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
||||||
alias netatalk-router-off='sudo sed -i '"'"'s/^eth0.*$/eth0/'"'"' /usr/local/etc/netatalk/atalkd.conf; sudo sed -i '"'"'s/^wlan0.*$/wlan0/'"'"' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
alias netatalk-router-off='sudo sed -i '"'"'s/^\([^#].*\) -router\(.*\) -zone [^ ]*\(.*\)$/\1\2\3/'"'"' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
||||||
|
|
||||||
|
|
||||||
alias netatalk-eth='sudo sed -i 's/^wlan0/eth0/' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
alias netatalk-eth='sudo sed -i 's/^wlan0/eth0/' /usr/local/etc/netatalk/atalkd.conf; netatalk-restart'
|
||||||
@@ -42,7 +42,7 @@ alias netatalk-wifi='sudo sed -i 's/^eth0/wlan0/' /usr/local/etc/netatalk/atalkd
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
alias appletalk-off='sudo sed -i "s/ATALKD_RUN=yes/ATALKD_RUN=no/" /etc/default/netatalk; sudo killall macipgw > /dev/null; /etc/init.d/netatalk restart'
|
alias appletalk-off='sudo sed -i "s/ATALKD_RUN=yes/ATALKD_RUN=no/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart'
|
||||||
alias appletalk-on='sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart'
|
alias appletalk-on='sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart'
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||||
|
|
||||||
export A2SERVER_SCRIPT_URL="${A2SERVER_SCRIPT_URL:-http://ivanx.com/a2server/}"
|
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/}"
|
export A2SERVER_BINARY_URL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files/}"
|
||||||
source /usr/local/etc/a2server-aliases
|
source /usr/local/etc/a2server-aliases
|
||||||
|
@@ -43,7 +43,6 @@ processPath () {
|
|||||||
echo "AppleDouble files have been updated for volume $sharepath."
|
echo "AppleDouble files have been updated for volume $sharepath."
|
||||||
else
|
else
|
||||||
[[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath."
|
[[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath."
|
||||||
[[ ! $renameLower ]] && echo "Ensure filenames are all caps on volume $sharepath."
|
|
||||||
if [[ $showerrors ]]; then
|
if [[ $showerrors ]]; then
|
||||||
echo $result \
|
echo $result \
|
||||||
| while read LINE; do
|
| while read LINE; do
|
||||||
@@ -63,7 +62,6 @@ processPath () {
|
|||||||
$0 $sharepath
|
$0 $sharepath
|
||||||
else
|
else
|
||||||
echo "Use afpsync -e to see error details."
|
echo "Use afpsync -e to see error details."
|
||||||
echo "Use afpsync -r to rename lowercase names to uppercase."
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
unset IFS
|
unset IFS
|
||||||
|
@@ -158,7 +158,7 @@ readchars () {
|
|||||||
&& ( $3 -ge 0 ) ]] || return 23; }
|
&& ( $3 -ge 0 ) ]] || return 23; }
|
||||||
# args are valid
|
# args are valid
|
||||||
dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \
|
dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \
|
||||||
2> /dev/null
|
2> /dev/null | tr -d ' \0'
|
||||||
}
|
}
|
||||||
|
|
||||||
readcharDec () {
|
readcharDec () {
|
||||||
@@ -175,7 +175,7 @@ readcharDec () {
|
|||||||
&& ( $2 -ge 0 ) ]] || return 22; }
|
&& ( $2 -ge 0 ) ]] || return 22; }
|
||||||
# args are valid
|
# args are valid
|
||||||
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
||||||
count=1 2> /dev/null; echo -n X)"
|
count=1 2> /dev/null | tr -d '\0'; echo -n X)"
|
||||||
[[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; }
|
[[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; }
|
||||||
echo -n "${charX:0:1}" | od -t u1 | \
|
echo -n "${charX:0:1}" | od -t u1 | \
|
||||||
head -1 | sed 's/[0\ ]*//' | tr -d ' \n'
|
head -1 | sed 's/[0\ ]*//' | tr -d ' \n'
|
||||||
@@ -195,7 +195,7 @@ readcharHex () {
|
|||||||
&& ( $2 -ge 0 ) ]] || return 22; }
|
&& ( $2 -ge 0 ) ]] || return 22; }
|
||||||
# args are valid
|
# args are valid
|
||||||
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
||||||
count=1 2> /dev/null; echo -n X)"
|
count=1 2> /dev/null | tr -d '\0'; echo -n X)"
|
||||||
[[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; }
|
[[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; }
|
||||||
printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \
|
printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \
|
||||||
head -1 | sed 's/[0\ ]*//' | tr -d ' \n')
|
head -1 | sed 's/[0\ ]*//' | tr -d ' \n')
|
||||||
|
File diff suppressed because it is too large
Load Diff
1
scripts/tools/netatalk-maketar.txt
Normal file
1
scripts/tools/netatalk-maketar.txt
Normal file
File diff suppressed because one or more lines are too long
109
setup/index.txt
109
setup/index.txt
@@ -1,7 +1,7 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
||||||
|
|
||||||
# A2SERVER master setup script, last update 17-Nov-15
|
# A2SERVER master setup script, last update 15-Jul-20
|
||||||
# it downloads and executes several scripts related to the setup of
|
# it downloads and executes several scripts related to the setup of
|
||||||
# netatalk configured for Apple II use on Debian or Raspbian.
|
# netatalk configured for Apple II use on Debian or Raspbian.
|
||||||
# more info is at http://ivanx.com/a2server
|
# more info is at http://ivanx.com/a2server
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
# to download and execute, type:
|
# to download and execute, type:
|
||||||
# wget ivanx.com/a2server/setup; source setup
|
# wget ivanx.com/a2server/setup; source setup
|
||||||
|
|
||||||
a2serverVersion="128"
|
a2serverVersion="153"
|
||||||
|
|
||||||
# Ensure URL we'll use ends in a /
|
# Ensure URL we'll use ends in a /
|
||||||
case "$A2SERVER_SCRIPT_URL" in
|
case "$A2SERVER_SCRIPT_URL" in
|
||||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://ivanx.com/a2server}/" ;;
|
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||||
esac
|
esac
|
||||||
case "$A2SERVER_BINARY_URL" in
|
case "$A2SERVER_BINARY_URL" in
|
||||||
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
|
||||||
@@ -27,29 +27,35 @@ isRpi=
|
|||||||
[[ -f /usr/bin/raspi-config ]] && isRpi=1
|
[[ -f /usr/bin/raspi-config ]] && isRpi=1
|
||||||
|
|
||||||
isDebian=
|
isDebian=
|
||||||
lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -c 1 < /etc/debian_version) -ge "7" ) ]] && isDebian=1
|
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
|
||||||
|
|
||||||
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
|
installedVersion=
|
||||||
echo "A2SERVER version available: $a2serverVersion"
|
if [ -f /usr/local/etc/A2SERVER-version ]; then
|
||||||
echo "A2SERVER version installed: $(cat /usr/local/etc/A2SERVER-version)"
|
installedVersion="$(cat /usr/local/etc/A2SERVER-version)"
|
||||||
fi
|
fi
|
||||||
|
echo "A2SERVER version available: $a2serverVersion"
|
||||||
|
echo "A2SERVER version installed: ${installedVersion:=None}"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
[[ $scriptURL != *"ivanx.com"* ]] && echo "Using script URL: $scriptURL"
|
[[ $scriptURL != *"ivanx.com"* && $scriptURL != *"raw.githubusercontent.com/RasppleII/a2server"* ]] && echo "Using script URL: $scriptURL"
|
||||||
[[ $binaryURL != *"ivanx.com"* ]] && echo "Using binary URL: $binaryURL"
|
[[ $binaryURL != *"ivanx.com"* ]] && echo "Using binary URL: $binaryURL"
|
||||||
[[ ! $useExternalURL ]] && echo -e "Not using external URLs. Payloads must be in:\n ${binaryURL}external\n (See A2SERVER developer page for more information.)"
|
[[ ! $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.)"
|
||||||
|
|
||||||
skipRepoUpdate=
|
skipRepoUpdate=
|
||||||
autoAnswerYes=
|
autoAnswerYes=
|
||||||
|
installAll=
|
||||||
setupNetBoot=
|
setupNetBoot=
|
||||||
setupWindowsSharing=
|
setupWindowsSharing=
|
||||||
updateRasppleII=
|
compileAlways=
|
||||||
rm /tmp/a2server-* 2> /dev/null
|
rm /tmp/a2server-* 2> /dev/null
|
||||||
while [[ $1 ]]; do
|
while [[ $1 ]]; do
|
||||||
if [[ $1 == "-r" ]]; then
|
if [[ $1 == "-r" ]]; then
|
||||||
shift
|
shift
|
||||||
skipRepoUpdate="-r"
|
skipRepoUpdate="-r"
|
||||||
touch /tmp/a2server-packageReposUpdated
|
touch /tmp/a2server-packageReposUpdated
|
||||||
|
elif [[ $1 == "-i" ]]; then
|
||||||
|
shift
|
||||||
|
installAll="-i"
|
||||||
elif [[ $1 == "-y" ]]; then
|
elif [[ $1 == "-y" ]]; then
|
||||||
shift
|
shift
|
||||||
autoAnswerYes="-y"
|
autoAnswerYes="-y"
|
||||||
@@ -62,38 +68,27 @@ while [[ $1 ]]; do
|
|||||||
shift
|
shift
|
||||||
setupWindowsSharing="-w"
|
setupWindowsSharing="-w"
|
||||||
touch /tmp/a2server-setupWindowsSharing
|
touch /tmp/a2server-setupWindowsSharing
|
||||||
elif [[ $1 == "-os" || $1 == "os" ]]; then
|
elif [[ $1 == "-c" ]]; then
|
||||||
# elif [[ ${1,,} == "rasppleii" || ${1,,} == "raspple" || ${1,,} == "rasappleii" || ${1,,} == "rasapple" || ${1,,} == "raspple2" || ${1,,} == "rasapple2" ]]; then
|
|
||||||
shift
|
shift
|
||||||
updateRasppleII=1
|
compileAlways="-c"
|
||||||
|
touch /tmp/a2server-compileAlways
|
||||||
elif [[ $1 == "-v" ]]; then
|
elif [[ $1 == "-v" ]]; then
|
||||||
shift
|
shift
|
||||||
if [[ ! -f /usr/local/etc/A2SERVER-version ]]; then
|
# Version was already printed
|
||||||
echo "A2SERVER version available: $a2serverVersion"
|
|
||||||
echo "A2SERVER version installed: none"
|
|
||||||
fi
|
|
||||||
[[ $0 == "-bash" ]] && return 1 || exit 1
|
[[ $0 == "-bash" ]] && return 1 || exit 1
|
||||||
elif [[ $1 ]]; then
|
elif [[ $1 ]]; then
|
||||||
echo "options:"
|
echo "options:"
|
||||||
echo "-v: display installed and available versions, then exit"
|
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 "-y: auto-answer yes to all prompts"
|
||||||
echo "-r: don't update package repositories"
|
echo "-r: don't update package repositories"
|
||||||
echo "-b: auto-setup network boot (use with -y)"
|
echo "-b: auto-setup network boot (use with -y)"
|
||||||
echo "-w: auto-setup Windows file sharing (use with -y)"
|
echo "-w: auto-setup Windows file sharing (use with -y)"
|
||||||
if [[ $isRpi ]]; then
|
echo "-c: compile non-package items, rather than downloading binaries"
|
||||||
echo "-os: update Raspbian OS, A2CLOUD, A2SERVER, and Apple II Pi"
|
|
||||||
fi
|
|
||||||
[[ $0 == "-bash" ]] && return 1 || exit 1
|
[[ $0 == "-bash" ]] && return 1 || exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ $updateRasppleII ]]; then
|
|
||||||
echo "A2SERVER: Updating Raspple II (takes up to an hour)..."
|
|
||||||
wget -qO /tmp/raspbian-update "${A2SERVER_SCRIPT_URL}scripts/raspbian-update.txt"
|
|
||||||
source /tmp/raspbian-update a2cloud a2server $autoAnswerYes $skipRepoUpdate
|
|
||||||
[[ $0 == "-bash" ]] && return 0 || exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 110 )); }; then
|
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 110 )); }; then
|
||||||
echo
|
echo
|
||||||
echo "WARNING: The current A2SERVER installer scripts haven't been tested for"
|
echo "WARNING: The current A2SERVER installer scripts haven't been tested for"
|
||||||
@@ -105,28 +100,35 @@ fi
|
|||||||
a2server_update=0
|
a2server_update=0
|
||||||
doSetup=1
|
doSetup=1
|
||||||
|
|
||||||
|
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 152 )); }; then
|
||||||
|
a2server_update=1
|
||||||
|
fi
|
||||||
|
|
||||||
unsupportedOS=1
|
unsupportedOS=1
|
||||||
if [[ $isRpi ]]; then #supported Raspbian? (16-Feb-15, 20-Jun-14, 09-Jan-14, etc)
|
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}')
|
fwhash=$(zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 'as of' | awk '{print $NF}')
|
||||||
fwsupported="-8aca5762- -462f3e3f476f7b6- -c32bc633039cd9- -9d34d0475f9-
|
fwsupported="-8aca5762- -462f3e3f476f7b6- -c32bc633039cd9- -9d34d0475f9-
|
||||||
-d4f5315cfac4e- -6f4a90c8cb8817f- -5dd9b4962e- -17c8799375-
|
-d4f5315cfac4e- -6f4a90c8cb8817f- -5dd9b4962e- -17c8799375-
|
||||||
-960832a6c2590635216c296b6ee0bebf67b21d50-"
|
-960832a6c2590635216c296b6ee0bebf67b21d50-
|
||||||
|
-2a329e0c7d8ea19c085bac5633aa4fccee0f21be-
|
||||||
|
-b2420fc150ae4616f5d9ec24bdaedc630586a529-"
|
||||||
[[ "$fwsupported" == *-$fwhash-* ]] && unsupportedOS=
|
[[ "$fwsupported" == *-$fwhash-* ]] && unsupportedOS=
|
||||||
# [[ ($fwhash == "8aca5762") || ($fwhash == "462f3e3f476f7b6") || ($fwhash == "c32bc633039cd9") || ($fwhash == "9d34d0475f9") || ($fwhash == "d4f5315cfac4e") || ($fwhash == "6f4a90c8cb8817f") || ($fwhash == "5dd9b4962e") || ($fwhash == "17c8799375") ]] && unsupportedOS=
|
# [[ ($fwhash == "8aca5762") || ($fwhash == "462f3e3f476f7b6") || ($fwhash == "c32bc633039cd9") || ($fwhash == "9d34d0475f9") || ($fwhash == "d4f5315cfac4e") || ($fwhash == "6f4a90c8cb8817f") || ($fwhash == "5dd9b4962e") || ($fwhash == "17c8799375") ]] && unsupportedOS=
|
||||||
elif [[ $isDebian ]]; then # supported Debian?
|
elif [[ $isDebian ]]; then # supported Debian?
|
||||||
debianVersion=$(cat /etc/debian_version)
|
debianVersion=$(cat /etc/debian_version)
|
||||||
debianSupported="-8.2- -7.9- -7.8- -7.6- -7.3-"
|
debianSupported="-10.4- -9.2- -8.2- -7.9- -7.8- -7.6- -7.3-"
|
||||||
[[ $debianSupported == *-$debianVersion-* ]] && unsupportedOS=
|
[[ $debianSupported == *-$debianVersion-* ]] && unsupportedOS=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $unsupportedOS && $isRpi ]]; then
|
if [[ $unsupportedOS && $isRpi ]]; then
|
||||||
echo
|
echo
|
||||||
echo "A2SERVER and its installer scripts have been tested on Raspbian Wheezy and"
|
echo "A2SERVER and its installer scripts have been tested on Raspbian Buster,"
|
||||||
echo "Jessie, though not this specific firmware version ($fwhash). Just FYI."
|
echo "Stretch, Jessie, and Wheezy, though not this specific firmware version"
|
||||||
|
echo "(${fwhash:0:7}). Just FYI."
|
||||||
unsupportedOS=
|
unsupportedOS=
|
||||||
elif [[ $unsupportedOS && $isDebian ]]; then
|
elif [[ $unsupportedOS && $isDebian ]]; then
|
||||||
echo
|
echo
|
||||||
echo "A2SERVER and its installer scripts have been tested on Debian 7 and 8,"
|
echo "A2SERVER and its installer scripts have been tested on Debian 7/8/9/10,"
|
||||||
echo "though not this specific point release ($debianVersion). Just FYI."
|
echo "though not this specific point release ($debianVersion). Just FYI."
|
||||||
unsupportedOS=
|
unsupportedOS=
|
||||||
fi
|
fi
|
||||||
@@ -135,13 +137,12 @@ if [[ $unsupportedOS ]]; then
|
|||||||
echo
|
echo
|
||||||
echo "WARNING: A2SERVER and its installer scripts have only been tested on"
|
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 "Debian and Raspbian. Continuing is probably fine, but might not be."
|
||||||
echo "Worst case could make your operating system no longer work properly,"
|
echo "Theoretical worst case would be your operating system no longer works"
|
||||||
echo "or cause data to be lost."
|
echo "properly or data is lost, so consider backing up first."
|
||||||
echo "More information is at http://ivanx.com/a2server."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
doSetup=1
|
doSetup=1
|
||||||
if [[ ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then
|
if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then
|
||||||
echo
|
echo
|
||||||
echo "Setting up A2SERVER will take up to 60 minutes, during which"
|
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 "you'll see a bunch of stuff spit out across the screen."
|
||||||
@@ -167,21 +168,23 @@ if (( $doSetup )); then
|
|||||||
|
|
||||||
if (( $doSetup )); then
|
if (( $doSetup )); then
|
||||||
|
|
||||||
|
checkPw=1
|
||||||
|
while [[ $checkPw ]] ; do
|
||||||
userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':')
|
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 '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=
|
[[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw=
|
||||||
|
|
||||||
password="your password"
|
password="your password"
|
||||||
[[ $isApple2Pw ]] && password="'apple2'"
|
[[ $isApple2Pw ]] && password="apple2"
|
||||||
[[ $isRaspberryPw ]] && password="'raspberry'"
|
[[ $isRaspberryPw ]] && password="raspberry"
|
||||||
|
checkPw=
|
||||||
|
|
||||||
[[ $isRpi ]] && a2server="your Raspberry Pi" || a2server="A2SERVER"
|
[[ $isRpi ]] && a2server="your Raspberry Pi" || a2server="A2SERVER"
|
||||||
if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2SERVER-version ]]; then
|
if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2SERVER-version ]]; then
|
||||||
if [[ ! $autoAnswerYes ]]; then
|
if [[ ! $autoAnswerYes ]]; then
|
||||||
echo
|
echo
|
||||||
echo "To ensure that all client computers are able to connect to"
|
echo "To ensure that all client computers are able to connect to"
|
||||||
echo "${a2server} using the same password, you are recommended"
|
echo "${a2server} using the same password, you probably want"
|
||||||
echo "to change your user password to 'apple2'."
|
echo "to change your user password to 'apple2'."
|
||||||
echo
|
echo
|
||||||
echo -n "Do you want to change the password for user '$USER' to 'apple2' now? "
|
echo -n "Do you want to change the password for user '$USER' to 'apple2' now? "
|
||||||
@@ -190,11 +193,13 @@ if (( $doSetup )); then
|
|||||||
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
|
||||||
echo "A2SERVER: changing password for user '$USER' to 'apple2'..."
|
echo "A2SERVER: changing password for user '$USER' to 'apple2'..."
|
||||||
echo "$USER:apple2" | sudo chpasswd
|
echo "$USER:apple2" | sudo chpasswd
|
||||||
|
checkPw=1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "During this installation, enter ${password} if prompted for passwords."
|
echo "During this installation, enter '${password}' if prompted for passwords."
|
||||||
echo
|
echo
|
||||||
|
|
||||||
sudo true
|
sudo true
|
||||||
@@ -222,6 +227,16 @@ if (( $doSetup )); then
|
|||||||
|
|
||||||
echo "A2SERVER: Scripts have been downloaded. Installing..."
|
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
|
/tmp/1.storage
|
||||||
rm /tmp/1.storage
|
rm /tmp/1.storage
|
||||||
/tmp/2.tools
|
/tmp/2.tools
|
||||||
@@ -257,9 +272,10 @@ if (( $doSetup )); then
|
|||||||
echo "via the AppleShare control panel."
|
echo "via the AppleShare control panel."
|
||||||
if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then
|
if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then
|
||||||
echo
|
echo
|
||||||
echo "You can network boot GS/OS. On a ROM 01 IIgs, set slot 1 or 2, and slot 7,"
|
echo "You can network boot GS/OS."
|
||||||
echo 'to AppleTalk, and Startup Slot to 7 or "Scan". On a ROM 3 IIgs, set'
|
echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)"
|
||||||
echo "slot 1 or 2, and startup slot, to AppleTalk."
|
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
|
fi
|
||||||
if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then
|
if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then
|
||||||
echo
|
echo
|
||||||
@@ -338,8 +354,5 @@ fi
|
|||||||
|
|
||||||
unset a2server_update 2> /dev/null
|
unset a2server_update 2> /dev/null
|
||||||
unset doSetup 2> /dev/null
|
unset doSetup 2> /dev/null
|
||||||
rm /tmp/a2server-autoAnswerYes 2> /dev/null
|
rm /tmp/a2server-* 2> /dev/null
|
||||||
rm /tmp/a2server-packageReposUpdated 2> /dev/null
|
|
||||||
rm /tmp/a2server-setupNetBoot 2> /dev/null
|
|
||||||
rm /tmp/a2server-setupWindowsSharing 2> /dev/null
|
|
||||||
rm setup &> /dev/null
|
rm setup &> /dev/null
|
||||||
|
120
update/devhistory.txt
Normal file
120
update/devhistory.txt
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
1.0.0: Jan 2012: initial release
|
||||||
|
|
||||||
|
1.0.1: Jan 2012: fixes Netatalk date-stamp bug (thanks to Steven Hirsch)
|
||||||
|
|
||||||
|
1.0.2: Jan 2013: Netatalk 2.2.4; OS X 10.7+ login fixed; netboot fixes;
|
||||||
|
Raspbian "Wheezy" support; Ubuntu 12.04 LTS support
|
||||||
|
|
||||||
|
1.1.0: Apr 2013: Full GS/OS install; eliminated GS.SYSTEM volume;
|
||||||
|
Raspberry Pi enhancements; lots of improvements to installer;
|
||||||
|
more utilities installed for Apple II; improved cppo
|
||||||
|
NOTE: fresh install required, can't update earlier version
|
||||||
|
|
||||||
|
1.1.1: Jun 2013: Wi-Fi support; updates/additions to commands in a2server-help;
|
||||||
|
bug fixes and improvements to install script; appletalk kernel
|
||||||
|
module for Raspbian (instead of replacement kernel); RPi
|
||||||
|
console (onboard serial) set to 19,200 bps during boot
|
||||||
|
|
||||||
|
1.1.2: Oct 2013: resolves issue of no AppleTalk in Raspbian 2013-09-10 and
|
||||||
|
later; faster command-line installation on Raspberry Pi
|
||||||
|
(nulib2 and unar binaries are downloaded rather than compiled)
|
||||||
|
|
||||||
|
1.1.3: Jan 2014: shares ADTPro disks folder as ADTDISKS; added environment
|
||||||
|
variables for shared folders; can resolve by name
|
||||||
|
"a2server.local" if network client has Bonjour/zeroconf;
|
||||||
|
server presents itself as Shared computer to Macs on network;
|
||||||
|
VM based on Debian 7
|
||||||
|
|
||||||
|
1.1.4: Jan 2014: fixes bug with network boot if ADTPro disks folder is shared
|
||||||
|
|
||||||
|
1.1.5: Jul 2014: a2server-setup fixes Raspbian 20-Jul-14 AppleTalk kernel panic
|
||||||
|
|
||||||
|
1.2.0: Aug 2014: a2server-setup and Netatalk startup script addresses AppleTalk
|
||||||
|
kernel panic on any Linux kernel 3.12-3.15; Netatalk starts
|
||||||
|
in background, preventing startup delay; a2server-setup always
|
||||||
|
configures Netatalk startup script and can download a new one
|
||||||
|
if missing; a2server-setup on Raspbian or Debian 7 x86 is
|
||||||
|
faster because it downloads binaries rather than compiling
|
||||||
|
from source; unbit/unexec/usq unarchivers added; additional
|
||||||
|
virtual machine which has both A2SERVER and A2CLOUD installed
|
||||||
|
|
||||||
|
1.2.1: Jan 2015: minor fixes; support for LED blink on Raspbian 2015-01-31
|
||||||
|
|
||||||
|
1.2.2: Mar 2015: installer improvements: now has command line options,
|
||||||
|
including unattended install; installer sets passwords
|
||||||
|
automatically to 'apple2'; status messages are now prefixed by
|
||||||
|
A2SERVER:; can update Raspple II (Raspbian OS,
|
||||||
|
NOOBS install manager, A2SERVER, and A2CLOUD); minor fixes.
|
||||||
|
|
||||||
|
1.2.3: May 2015: changed Apple software links to Internet Archive
|
||||||
|
|
||||||
|
1.2.4: Jul 2015: offer to download A2CLOUD disk contents onto A2FILES volume
|
||||||
|
|
||||||
|
1.2.4+:Oct 2015: support for using A2SERVER scripts from a location other than
|
||||||
|
[unannounced] ivanx.com/a2server for development purposes
|
||||||
|
|
||||||
|
1.2.5: Nov 2015: netboot install option for GS/OS 6.0.2/3
|
||||||
|
netboot always downloads GS/OS disk images even if present
|
||||||
|
provides error if a2setup doesn't have internet
|
||||||
|
remove persisting a2server-setup options after aborted install
|
||||||
|
fixed installer bug that omits first and last script elements
|
||||||
|
download images from Apple, with Internet Archive as a backup
|
||||||
|
install HFS.FST during netboot install
|
||||||
|
|
||||||
|
1.2.5+:Nov 2015: Merged Ivan's 1.2.5 release, removed support for Ubuntu for
|
||||||
|
[unannounced] now (see RasppleII/a2server#11), patched ProDOS 8 in boot
|
||||||
|
files for current year table, install unar from a package if
|
||||||
|
it exists.
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
1.2.7: Dec 2015: preliminary Jessie support; case insensitive file system for
|
||||||
|
[unannounced] A2FILES; removes GSFILES if empty; DOS3.3.FST and TEACH are
|
||||||
|
installed with netboot installation; minor bug fixes and
|
||||||
|
tweaks; Ubuntu support removed; branches unified
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
1.3.1: Jan 2016: patch Prodos 8 Thunderclock year table based on current date
|
||||||
|
[unannounced]
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
1.5.1: May 2016: changed URLs from rawgit.com to raw.githubusercontent.com
|
||||||
|
to resolve https problems during install; OS X temp dir
|
||||||
|
path corrected; added getexternal.sh to repo;
|
||||||
|
cppo changes; minor text changes (JTC); better Debian
|
||||||
|
version checking (JTC)
|
||||||
|
[unannounced]
|
||||||
|
|
||||||
|
1.5.1r2: Oct 2017: set internal version to 1.5.1; expanded version history
|
||||||
|
[unannounced]
|
||||||
|
|
||||||
|
1.5.2: Nov 2017: support for Stretch; suppress null byte read warnings in
|
||||||
|
Bash 4.4; enable SSH server on Raspberry Pi if disabled;
|
||||||
|
use Internet Archive backup URL's for external downloads if
|
||||||
|
possible; compile AppleTalk kernel if -c flag is
|
||||||
|
specified (rather than downloading); better cleanup after
|
||||||
|
AppleTalk kernel compile; notification if AppleTalk kernel
|
||||||
|
module doesn't load; fixed download links for comm software;
|
||||||
|
bug fixes when compiling macipgw and ciopfs;
|
||||||
|
os option (Raspbian update) removed from a2server-setup
|
||||||
|
|
||||||
|
1.5.3a1: July 2020: initial support for Debian/Raspbian Buster
|
@@ -4,7 +4,7 @@
|
|||||||
# Ensure URL we'll use ends in a /
|
# Ensure URL we'll use ends in a /
|
||||||
case "$A2SERVER_SCRIPT_URL" in
|
case "$A2SERVER_SCRIPT_URL" in
|
||||||
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
|
||||||
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://ivanx.com/a2server}/" ;;
|
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
currentVersion=$(wget -qO- "${scriptURL}setup/index.txt" | grep '^a2serverVersion' | cut -d '"' -f 2)
|
currentVersion=$(wget -qO- "${scriptURL}setup/index.txt" | grep '^a2serverVersion' | cut -d '"' -f 2)
|
||||||
@@ -37,9 +37,8 @@ else
|
|||||||
read
|
read
|
||||||
fi
|
fi
|
||||||
if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then
|
if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then
|
||||||
sudo rm /usr/local/etc/A2SERVER-version &> /dev/null
|
|
||||||
# sudo rm /usr/local/etc/netatalk/a2boot/* &> /dev/null
|
# sudo rm /usr/local/etc/netatalk/a2boot/* &> /dev/null
|
||||||
wget -q -O /tmp/setup "${scriptURL}setup/index.txt"; source /tmp/setup "$@"
|
wget -q -O /tmp/setup "${scriptURL}setup/index.txt"; source /tmp/setup -i "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
unset currentVersion 2> /dev/null
|
unset currentVersion 2> /dev/null
|
||||||
|
@@ -48,44 +48,41 @@
|
|||||||
|
|
||||||
1.2.3: May 2015: changed Apple software links to Internet Archive
|
1.2.3: May 2015: changed Apple software links to Internet Archive
|
||||||
|
|
||||||
1.2.4: Jul 2015: offer to download A2CLOUD disk contents onto A2FILES volume
|
1.2.4: Jul 2015: install option for ProTERM, Z.Link, ADTPro, Spectrum images
|
||||||
|
|
||||||
1.2.4+:Oct 2015: support for using A2SERVER scripts from a location other than
|
1.2.5: Nov 2015: netboot install option for GS/OS 6.0.2/3; install HFS.FST
|
||||||
ivanx.com/a2server for development purposes
|
during netboot install
|
||||||
[not released]
|
|
||||||
|
|
||||||
1.2.5: Nov 2015: netboot install option for GS/OS 6.0.2/3
|
1.2.6: Nov 2015: full, ready to use install of Spectrum
|
||||||
netboot always downloads GS/OS disk images even if present
|
[unannounced; released briefly, then withdrawn]
|
||||||
provides error if a2setup doesn't have internet
|
|
||||||
remove persisting a2server-setup options after aborted install
|
|
||||||
fixed installer bug that omits first and last script elements
|
|
||||||
download images from Apple, with Internet Archive as a backup
|
|
||||||
install HFS.FST during netboot install
|
|
||||||
|
|
||||||
1.2.5+:Nov 2015: Merged Ivan's 1.2.5 release, removed support for Ubuntu for
|
1.5.0: Jan 2016: mixed case filenames for A2FILES; remove GSFILES if empty;
|
||||||
now (see RasppleII/a2server#11), patched ProDOS 8 in boot
|
install Marinetti 3.0b8 with internet access via MacIP;
|
||||||
files for current year table, install unar from a package if
|
fully install Spectrum, SAFE2, SAM2, SNAP, MountIt; install
|
||||||
it exists.
|
DOS3.3 and TEACH; remove Ubuntu support; move/media/A2SHARED/*
|
||||||
[not released]
|
to /srv/A2SERVER; faster install (precompiled binaries) on
|
||||||
|
64-bit Debian; cppo supports ShrinkIt, DOS 3.3, DSK, 2MG,mixed
|
||||||
|
case filenames; nulib2 handles empty forks (thanks Andy);
|
||||||
|
new installer options; patch P8 Thunderclock driver year table
|
||||||
|
for current date; install from any host URL for development;
|
||||||
|
source code at GitHub (thanks Joseph)
|
||||||
|
|
||||||
1.2.6: Nov 2015: full, ready to use install of Spectrum; install unzip
|
1.5.1: Jan 2016: fixed GitHub URLs to prevent https errors during installation
|
||||||
[released briefly, then withdrawn]
|
(thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html);
|
||||||
|
bug fixes and minor text changes
|
||||||
|
|
||||||
1.2.6+:Nov 2015: merged Ivan's 1.2.6
|
1.5.1r2: Oct 2017: corrected version number
|
||||||
[not released]
|
|
||||||
|
|
||||||
1.2.7: Dec 2015: codebase unified; preliminary Jessie support; case insensitive
|
1.5.2: Nov 2017: support for Debian/Raspbian Stretch; fixes minor bugs during
|
||||||
file system for A2FILES; removes GSFILES if empty; DOS3.3.FST
|
install; enable SSH server if disabled on Raspberry Pi; fixes
|
||||||
and TEACH are installed with netboot installation; minor bug
|
changed download links for GS/OS communication software
|
||||||
fixes and tweaks
|
|
||||||
[not released]
|
|
||||||
|
|
||||||
1.2.8: Dec 2015: moved /media/A2SHARED to /srv/A2SERVER
|
1.5.3a2: July 2020: initial support for Debian/Raspbian Buster
|
||||||
macipgw installed
|
|
||||||
files subdirectory reorganized
|
Big thanks to: Anthony Martino, Henry Courbis, Joseph Carter, Jason King,
|
||||||
64-bit Debian binaries
|
Andy McFadden, Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, David Schmidt,
|
||||||
A2SERVER_SCRIPT_URL now works everywhere
|
David Schmenk, Ewen Wannop, Andrew Roughan, Antoine Vignau, Martin Haye,
|
||||||
A2SERVER_BINARY_URL can now be specified
|
Ken Gagne, Peter Neubauer, James Littlejohn, Ninjaforce; the creators of
|
||||||
self-hosted binaries fallback, or preferred with A2SERVER_NO_EXTERNAL
|
Netatalk, The Unarchiver, ciopfs, macipgw; and the entire Apple II community.
|
||||||
better information at start and end of install
|
Redistribution of Spectrum, SAFE2, SAM2, SNAP by permission of Ewen Wannop.
|
||||||
[not released]
|
Thanks for using A2SERVER!
|
||||||
|
Reference in New Issue
Block a user