91 Commits

Author SHA1 Message Date
Ivan X
4fb47b06ed documentation updates 2020-07-15 07:02:11 -07:00
Ivan X
a615ed1808 initial Buster compatibility 2020-07-15 06:06:44 -07:00
Ivan X
5e0feab69c support for Debian and Raspbian Stretch
suppress null byte read warnings in Bash 4.4
enable SSH server on Raspberry Pi if disabled
Internet Archive backup URL's for external downloads, where possible
compiles 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 communication software
fixed bugs possibly preventing compile of macipgw and ciopfs
fixed minor bugs during initial setup prompts
os option (Raspbian update) removed from a2server-setup
2017-11-26 16:37:44 -05:00
Ivan X
a3a7a9479d set internal version to 1.5.1; expanded version history 2017-10-29 05:21:55 -04:00
Ivan X
34836dcbb4 updated version history 2016-05-28 11:00:35 -04:00
Ivan X
7b7917d417 changed rawgit.com to raw.githubusercontent.com to resolve https issues 2016-05-28 10:11:26 -04:00
T. Joseph Carter
938db3c46b 2-tools: Make jessie+ condition actually jessie+ 2016-04-10 01:38:10 -07:00
Ivan X
4d1b5db5e3 cppo fixes temp directory paths on OS X 2016-02-19 21:46:46 -05:00
Ivan X
7d1a06a916 added text files from files subdirectory 2016-02-17 22:25:23 -05:00
Ivan X
f9b120002a Merge branch 'master' of https://github.com/RasppleII/a2server 2016-02-17 05:44:58 -05:00
Ivan X
49d50e49ac Fixed inaccurate text at end of a2server-setup for ROM 01 IIgs 2016-02-17 05:43:59 -05:00
T. Joseph Carter
dfa1e26c80 README.md: code spans to avoid _ errors
Put a couple of filenames in code spans so that _ characters in them
would not turn on unwanted <em> in HTML.  This is something GitHub's
Markdown markup doesn't do because it's almost never what you want, but
everything else does because that's what John Gruber designed.
2016-02-15 03:52:32 -08:00
T. Joseph Carter
d86e3bfa88 5-netboot: Guidance on choosing GS/OS version
Closes #45.
2016-01-30 15:27:33 -08:00
T. Joseph Carter
cd20570999 *.txt: Fix Debian wheezy/jessie version checks
Found some checks that assumed all Debian was wheezy, and also a bunch
of use of cut assuming that there will never be a Debian version higher
than 9.0.  Let's just futureproof that code right now.  This closes #56
and uses the method described therein anywhere -c 1 is used now.  For
the checks against -c 1-2, we still use -d . -f 1 as described in the
issue, but modify the following conditionals to test for just the
numeric, without the decimal.
2016-01-30 03:25:27 -08:00
T. Joseph Carter
cd8271cd56 setup/index.txt: Print version once
A minor thing, but reducing slightly duplicated code is always a good
thing, and printing the version number is never a bad idea.
2016-01-29 04:22:54 -08:00
Ivan X
750b9998df fixed bug in entering 30-day month dates in clock.patch 2016-01-19 07:38:23 -05:00
Ivan X
9ba5258fe0 expanded README.md 2016-01-18 06:26:40 -05:00
Ivan X
50875f5c3f internet archive backup for MountIt 2016-01-17 22:27:41 -05:00
Ivan X
ca4e3b76e6 another revision to version history 2016-01-17 22:04:42 -05:00
Ivan X
3a82176d0a slight revision to version history 2016-01-17 17:28:13 -05:00
Ivan X
061c3c1897 show first prompt if < 1.5.0 2016-01-17 17:16:35 -05:00
Ivan X
dea2ea2ce2 fixed netboot user setup 2016-01-17 15:37:02 -05:00
Ivan X
bb5f42462e fixed issues with download Apple II titles from original hosts 2016-01-17 15:03:40 -05:00
Ivan X
59d293ec84 no longer skips first prompt if using -i option 2016-01-17 13:16:21 -05:00
Ivan X
9dfbe0e9f3 removed "Attempting" status language because it bugged me 2016-01-17 13:09:38 -05:00
Ivan X
ca12a4a9e9 better detection of distribution URL during startup message 2016-01-17 13:07:39 -05:00
Ivan X
94b6dcaa26 fixed a2server-setup and -update aliases not respecting env vars
using new installer -i flag in a2server-update to trigger reinstall
2016-01-17 12:23:24 -05:00
Ivan X
da204bd05b set version number to 1.5.0; updated version history 2016-01-17 11:49:03 -05:00
Ivan X
fbc1ce5ba2 fixed detection of installed comm software; minor text changes 2016-01-17 10:06:01 -05:00
Ivan X
b7528026de fixed cppo cleanup on exit 2016-01-17 10:05:35 -05:00
Ivan X
60f88e4e8a use rawgit.com for default A2SERVER_SCRIPT_URL 2016-01-16 23:47:03 -05:00
Ivan X
13343a5c2a doesn't add eth0 to atalk.conf if something already there
improve content and formatting of /etc/init.d/netatalk status messages
2016-01-16 20:58:10 -05:00
Ivan X
95fb701098 get Spectrum/SAFE/SAM/SNAP URL's from dist page; display version numbers 2016-01-16 14:32:51 -05:00
Ivan X
3a0e123c0a clean up /tmp/cppo-* files on exit; centralized exit 2016-01-16 14:30:53 -05:00
Ivan X
5c47545772 provide -i option to reinstall core A2SERVER (not Apple II software)
bump version to 1.3.2
2016-01-15 14:08:45 -05:00
Ivan X
c5460eb292 reorganized and reduced number of netboot and software install prompts
better detection and less prompting for already installed software
preconfiguration of SAFE2 and SNAP
2016-01-15 14:06:22 -05:00
Ivan X
653218535f download and install nulib2-3.1.0a2 (rather than a1) 2016-01-15 13:40:13 -05:00
Ivan X
a0ded5a7cf fixed bug in 'appletalk-off' alias 2016-01-15 13:37:24 -05:00
Ivan X
3cc2beabcf support nulib2-3.1.0a2 (rather than working around bug in 3.1.0a1) 2016-01-15 13:34:52 -05:00
Ivan X
4ca810bd26 SNAP installed 2016-01-12 07:32:24 -05:00
Ivan X
f8d7a916e2 SAM2 (POP email) client installed; fix for extracting sdk with nulib2 2016-01-11 02:53:14 -05:00
Ivan X
80c4818d47 install SAFE2 (FTP client) 2016-01-11 01:46:39 -05:00
Ivan X
b846df61da extract .sdk containing one image into same folder 2016-01-11 01:45:48 -05:00
Ivan X
ec0bf3b9d5 cppo properly handles archived disk images (.sdk files) 2016-01-11 01:00:01 -05:00
Ivan X
631ad8a2e2 fixed bug preventing proper afpsync following mixed-case volume conversion 2016-01-10 18:42:09 -05:00
Ivan X
4ad9e10c77 full path display of filenames rather than quasi-hierarchy 2016-01-10 18:41:16 -05:00
Ivan X
9760380115 credit to Greg Branche for original Applesoft 2016-01-10 11:54:57 -05:00
Ivan X
5660347bc8 patches P8 Thunderclock driver year tables automatically based on current date 2016-01-10 11:32:22 -05:00
Ivan X
6f835905af only prompts for updating P8 year tables if 6.0.1 and not already patched 2016-01-10 07:50:28 -05:00
Ivan X
9bd8b0d3f0 python implementation of Apple's CLOCK.PATCH on GS/OS 6.0.1 System Tools 2 2016-01-09 16:53:57 -05:00
Ivan X
9b87db8eb4 installs Marinetti 3.0b8 with MacIP preconfigured 2016-01-06 07:25:18 -05:00
Ivan X
71274cb18f cppo detects invalid SHK rather than creating empty folder 2016-01-06 06:12:24 -05:00
Ivan X
502e638964 install Marinetti 3.0b1 2016-01-05 07:08:48 -05:00
Ivan X
85cbf4d741 '-n' arg for restoring SHK archives in place rather than new parent folder 2016-01-05 07:07:31 -05:00
Ivan X
c5c14759d1 cppo: case insensitive ProDOS single-file; fixed argument validation 2016-01-05 05:52:15 -05:00
Ivan X
6e9ddb5e47 cppo: bug fix on DOS 3.3 file extract 2016-01-04 16:32:48 -05:00
Ivan X
180dcc5634 cppo: -uc option works with SHK; case insensitive extract spec 2016-01-04 10:07:39 -05:00
Ivan X
7163390b19 MountIt is installed, not just an SHK archive 2016-01-04 03:50:22 -05:00
Ivan X
e0a78c5756 cppo: SHK has same process and output as HDV
resource forks are not displayed if not using -e or -ad
2016-01-04 03:49:04 -05:00
Ivan X
8327a5eb8d cppo appends "+" to extended files during ordinary -cat of SHK archives 2016-01-04 01:02:42 -05:00
Ivan X
4a0d574f8a Spectrum: not installed if no GS/OS; fixed install issues 2016-01-03 19:30:11 -05:00
Ivan X
e58fd1bbb1 added Raspbian firmware ab06f63 to valid list at startup check
(current Jessie and raspberrypi-bootloader package, kernel 4.1.13)
2016-01-03 18:33:40 -05:00
Ivan X
02442b16e5 change 'command -v' to 'hash'; make sure libdb5.1 installs on Wheezy
(Raspbian Wheezy has both libdb5.1 and libdb5.3, so now tries 5.1 first.)
2016-01-03 17:39:09 -05:00
Ivan X
00adf2673d updates Nulib2 to 3.1.0a1; -c forces compile (no binaries); URL fixes 2016-01-03 16:06:40 -05:00
Ivan X
fc7aaf4d53 more bug fixes, and minor enhancements 2016-01-03 13:33:25 -05:00
Ivan X
0ca7ef94b8 cppo bug fix to the bug fix 2016-01-03 05:49:35 -05:00
Ivan X
1403fde73d cppo bug fix on unreferenced origFileName 2016-01-03 05:30:17 -05:00
Ivan X
7e12bbd696 Merge branch 'master' of https://github.com/RasppleII/a2server 2016-01-03 05:17:40 -05:00
Ivan X
1af347ae8f replace nulib2 with 3.1.0a1 which handles empty forks correctly
hide all cppo output in netboot install
remove guidance about uppercase filenames in afpsync error message
2016-01-03 05:14:34 -05:00
T. Joseph Carter
22020603f6 docs/ivanx: Delete, see RasppleII/orig-archive
Having an outdated copy of the source code in a subdir of the source
code was proving to be annoying--it's bitten both Ivan and I a time or
two, and we have a GitHub organization to put repositories for these
kinds of things.  As such, this stuff is neither needed nor particularly
desirable where it is.  It lives on here:

<https://github.com/RasppleII/orig-archive/>
2016-01-02 17:52:55 -08:00
Ivan X
5fab6a21af cppo DOS 3.3 support
(from previous commits:)
supports ProDOS, DOS 3.3, and ShrinkIt archive as source
handles 2mg images
auto-determines sector ordering for 140K disks
2016-01-02 19:06:00 -05:00
Ivan X
6b45259759 cppo support for dos-order and 2mg images 2016-01-01 05:25:19 +09:00
Ivan X
4692537443 cppo supports all features for SHK's as for PO's, including single file 2016-01-01 03:06:52 +09:00
Ivan X
4e4bd8dbbd cppo supports -cat argument for shrinkit archives 2016-01-01 01:40:13 +09:00
Ivan X
d2775f4d27 cppo can be used with -e, -ad, or neither for shk's 2016-01-01 01:12:23 +09:00
Ivan X
8f6fae4bb4 minor fixes and refusal to use -shk option on Windows 2016-01-01 00:19:32 +09:00
Ivan X
53404e7784 support for ShrinkIt archives in addition to disk images 2015-12-31 01:25:41 +09:00
Ivan X
01d3ce1775 libdb5.3+libgcrypt20 on Jessie rather than installing older Wheezy libs
removed libdb4.8 support
fixed source URL's to use external/source when locally hosting externals
2015-12-25 12:37:56 +09:00
Ivan X
14f5ef66be alternate URL for precompiled binaries with A2SERVER_BINARY_URL
self-hosted external dependency fallback; or default via A2SERVER_NO_EXTERNAL=1
a2serverrc sets default A2SERVER_SCRIPT_URL and A2SERVER_BINARY_URL
64-bit Debian precompiled binary support
support for reorganized files subdirectory
better information re unsupported OS at start of install
info about netboot at end of install
no longer deletes ~/GNUstep
install libdb5.1 and libssl1.0.0 by default instead of older versions
small tweaks and fixes regarding Debian detection, case insensitive fs, etc
updated source code path for The Unarchiver
this is internal version 1.2.8; see "release" notes about external dependencies
2015-12-24 13:02:17 +09:00
T. Joseph Carter
04ad897c97 Merge branch 'master' of https://github.com/RasppleII/a2server
Minor/trivial conflict in a2server-2-tools.txt
2015-12-21 16:28:18 -08:00
T. Joseph Carter
06bc59ece7 scripts/*.txt: Collapse multiple apt-gets in a row
As Debian has gone from large to huge, actions operating on the package
database have gotten slower and slower, so it's best to do them as few
times as possible.

Here we've got the trivial optimization.  A more complete optimization
requires a refactoring of code, and we're kind of in a 1.3.0 "freeze",
so let's not do that here and now.
2015-12-21 16:17:13 -08:00
Ivan X
c2bb79860a on Debian, provides AppleTalk without IPDDP to enable MacIPgw 2015-12-20 00:40:28 -05:00
T. Joseph Carter
343bde59fa License terms for A2SERVER
This doesn't close the open issue on the subject, since precisely what's
under what license isn't really addressed yet, but at least the license
is specified.  For those unfamiliar with the WTFPL, it's a public domain
release like CC0, except instead of trying to legally emulate the public
domain if that concept is foreign to your jurisdiction, it basically
gives all software licenses a giant middle finger.

What it lacks in finesse and niceties or in legal rigor of the CC0, it
makes up for in simplicity: Do whatever the f*** you want with the code!
It's pretty hard to misconstrue what that means.  :)
2015-12-18 01:32:53 -05:00
Ivan X
024f579850 macipgw installed; a2serverc created
(macipgw tested on Wheezy and Jessie; works on Raspbian only, not Debian x86)
2015-12-18 00:57:21 -05:00
T. Joseph Carter
0fffaf93cb License terms for A2SERVER
This doesn't close the open issue on the subject, since precisely what's
under what license isn't really addressed yet, but at least the license
is specified.  For those unfamiliar with the WTFPL, it's a public domain
release like CC0, except instead of trying to legally emulate the public
domain if that concept is foreign to your jurisdiction, it basically
gives all software licenses a giant middle finger.

What it lacks in finesse and niceties or in legal rigor of the CC0, it
makes up for in simplicity: Do whatever the f*** you want with the code!
It's pretty hard to misconstrue what that means.  :)
2015-12-13 09:31:49 -08:00
T. Joseph Carter
0bd95253fe README.md minor Markdown syntax embettering 2015-12-10 09:11:32 -08:00
Ivan X
b5496b55aa Merge branch '1.3.0-dev' 2015-12-09 20:51:28 -05:00
Ivan X
9f397b1f9f minor text changes; substitute tilde for backticks 2015-12-09 20:44:36 -05:00
Ivan X
435857e3bb move /media/A2SHARED to /srv/A2SERVER 2015-12-09 20:39:09 -05:00
T. Joseph Carter
b0bb0e7b99 experimental: Doesn't belong in a release, delete 2015-12-08 19:36:54 -08:00
T. Joseph Carter
bb9e458a98 README.md: GFM supports ~~~ blocks, implement! 2015-12-06 18:18:07 -08:00
60 changed files with 4723 additions and 6438 deletions

13
LICENSE.md Normal file
View File

@@ -0,0 +1,13 @@
License for A2SERVER
====================
A2SERVER
Copyright (C) 2013-2015 Ivan Drucker <ivan@ivanx.com>
The A2SERVER scripts themselves are written primarily by Ivan Drucker and
released under the WTFPL version 2, which you may download from its web page
at <http://www.wtfpl.net/txt/copying/>. This is essentially a public domain
release, which doesn't extend to the other programs used by A2SERVER such as
netatalk or the various Linux tools it installs. These have their own license
terms and Copyrights.

View File

@@ -1,5 +1,6 @@
# 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
information about A2SERVER and how it all works. There's a lot there and it's
@@ -13,24 +14,91 @@ relatively modern piece of it. As such they should be preserved as they are.
## Developer note
To use the scripts on a server other than Ivan's, you'll want to export
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:
To use the scripts with a specific GitHub tag:
~~~ bash
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
~~~
```bash
wget -O a2server-setup ${A2SERVER_SCRIPT_URL}setup/index.txt; source a2server-setup
```
Or, to use the scripts on your own server, including your local machine:
A simple method installing from a local folder is to change to that sudirectory
and run the following. Then export A2SERVER_SCRIPT_URL to "http://localhost:8000/"
~~~ bash
export A2SERVER_SCRIPT_URL=http://yoururl.com/
~~~
```bash
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/

View File

@@ -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.

View File

@@ -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 /media/A2SHARED.
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/

View File

@@ -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 /media/A2SHARED. 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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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).

View File

@@ -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/

View File

@@ -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/

View File

@@ -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

View File

@@ -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/

View File

@@ -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 /media/A2SHARED 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

View File

@@ -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!

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,19 +0,0 @@
#!/bin/bash
# --- Setting up the share volume
# skip if we're already set up
if [[ -d /media/A2SHARED ]]; then
echo "A2SERVER: Shared disk is already prepared for use."
else
echo "A2SERVER: Preparing the shared files disk..."
sudo mkdir /media/A2SHARED
sudo chown $USER:$USER /media/A2SHARED
fi

View File

@@ -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

View File

@@ -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 /media/A2SHARED/GSFILES ]] || mkdir -p /media/A2SHARED/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 /media/A2SHARED/A2FILES ]] || mkdir -p /media/A2SHARED/A2FILES
if [[ ! -d /media/A2SHARED/A2FILES/.AppleDesktop ]]; then
cd /media/A2SHARED/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 /media/A2SHARED/ADTDISKS ]]; then
ln -s /usr/local/adtpro/disks /media/A2SHARED/ADTDISKS
fi
if [[ ! $(grep ADTDISKS /usr/local/etc/netatalk/AppleVolumes.default) ]]; then
sudo sed -i 's@^# End of File@/media/A2SHARED/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

View File

@@ -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="/media/A2SHARED/A2FILES"
imagesDir=$gsosDir/GSOS.INSTALLER/IMAGES
imageToolsDir=$gsosDir/GSOS.INSTALLER/IMAGE.TOOLS
netInstallDir=$gsosDir/GSOS.INSTALLER/NET.INSTALL
p8Dir="/media/A2SHARED/A2FILES"
diskToolsP8Dir=$p8Dir/DISK.TOOLS.P8
commDir="/media/A2SHARED/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 "/media/A2SHARED/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

View File

@@ -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 = /media/A2SHARED/$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

View File

@@ -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

View File

@@ -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="/media/A2SHARED/A2FILES"
GSFILES="/media/A2SHARED/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 /media/A2SHARED/GSFILES ]] || mkdir /media/A2SHARED/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 /media/A2SHARED/A2FILES ]] || mkdir /media/A2SHARED/A2FILES"
alias showalias="alias | cut -d= -f 1 | cut -d' ' -f2 | more"
#

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -1,882 +0,0 @@
#!/usr/bin/env python
"""cppo: Copy or catalog one or all files from a ProDOS raw disk image.
copy all files:
cppo [-ad|-e] imagefile target_directory
copy one file:
cppo [-ad|-e] imagefile /FULL/PRODOS/FILE/PATH target_path
catalog image:
cppo -cat imagefile
-ad : Create AppleDouble header files and preserve resource forks.
-e : Append ProDOS type and auxtype to filenames, and copy resource
forks, for adding to ShrinkIt archives with Nulib2
using its -e option.
Wildcard matching/globbing (*) is not supported.
No verification or validation of the disk image is performed.
(Compatible with Python 2.6 and later, including 3.x.)
"""
# cppo by Ivan X, ivan@ivanx.com, ivanx.com/appleii
# If anyone's looking at this, and feels it's not sufficiently Pythonic,
# I know that. It's pretty much a line-for-line conversion of the original
# Bash script. I did start a beautiful from-the-ground-up object-oriented
# version, then realized it would be faster to translate it ugly and quick.
# imports for python 3 code compatibility
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
import sys
import os
import time
import datetime
# Intentially fails on pre-2.6 so user can see what's wrong
b'ERROR: cppo requires Python 2.6 or later, including 3.x.'
class Globals(object):
pass
g = Globals()
g.imageData = b''
g.outFileData = bytearray(b'')
g.adFileData = bytearray(b'')
g.exFileData = bytearray(b'')
g.activeDirBlock = None
g.activeFileName = None
g.activeFileSize = None
g.activeFileBytesCopied = 0
g.resourceFork = 0
g.PDOSPATH = []
g.PDOSPATH_INDEX = 0
g.PDOSPATH_SEGMENT = None
g.DIRPATH = ""
g.targetName = None
g.targetDir = ""
g.ADdir = None
g.imageFile = None
g.AD = 0
g.EX = 0
g.DIR = 0
g.silent = 0
# functions
def pdosDateToUnixDate(arg1):
# input: ProDOS date/time bit sequence string in format:
# "yyyyyyymmmmddddd000hhhhh00mmmmmm" (ustr)
# output: seconds since Unix epoch (1-Jan-1970),
# or current date/time if no ProDOS date
year = (binToDec(slyce(arg1,0,7)) + 1900)
if (year < 1940): year += 100
month = binToDec(slyce(arg1,7,4))
day = binToDec(slyce(arg1,11,5))
hour = binToDec(slyce(arg1,19,5))
minute = binToDec(slyce(arg1,26,6))
# print(year, month, day, hour, minute)
td = (datetime.datetime(year, month, day, hour, minute) -
datetime.datetime(1970,1,1))
unixDate_naive = (td.days*24*60*60 + td.seconds)
td2 = (datetime.datetime.fromtimestamp(unixDate_naive) -
datetime.datetime.utcfromtimestamp(unixDate_naive))
utcoffset = (td2.days*24*60*60 + td2.seconds)
# print(unixDate_naive - utcoffset)
return (unixDate_naive - utcoffset) # local time zone with DST
def unixDateToADDate(arg1):
# input: seconds since Unix epoch (1-Jan-1970 00:00:00 GMT)
# output: seconds since Netatalk epoch (1-Jan-2000 00:00:00 GMT),
# in hex-ustr (big endian)
adDate = (arg1 - 946684800)
if (adDate < 0 ):
adDate += 4294967296 # to get negative hex number
adDateHex = to_hex(adDate).zfill(8).upper()
# print(arg1, adDate, adDateHex)
return adDateHex
# cppo support routines:
# arg1: directory block
# arg2: file index (if applicable)
# arg3: directory chunk # (if applicable)
#most of these not tested yet in Python
# returns byte position in disk image file
def getStartPos(arg1, arg2):
return ( (arg1 * 512) +
(39 * ((arg2 + (arg2 > 11)) % 13)) +
(4 if (arg2 > 11) else 43) )
def getStorageType(arg1, arg2):
start = getStartPos(arg1, arg2)
firstByte = readcharDec(g.imageData, start)
return (firstByte//16)
def getFileName(arg1, arg2):
start = getStartPos(arg1, arg2)
firstByte = readcharDec(g.imageData, start)
entryType = (firstByte//16)
nameLength = (firstByte - entryType*16)
return readchars(g.imageData, start+1, nameLength)
def getFileType(arg1, arg2):
start = getStartPos(arg1, arg2)
return readcharHex(g.imageData, start+16)
def getKeyPointer(arg1, arg2):
start = getStartPos(arg1, arg2)
return (readcharDec(g.imageData, start+17) +
readcharDec(g.imageData, start+18)*256)
def getFileLength(arg1, arg2):
start = getStartPos(arg1, arg2)
return (readcharDec(g.imageData, start+21) +
readcharDec(g.imageData, start+22)*256 +
readcharDec(g.imageData, start+23)*65536)
def getAuxType(arg1, arg2):
start = getStartPos(arg1, arg2)
return (readcharHex(g.imageData, start+32) +
readcharHex(g.imageData, start+31))
def getCreationDate(arg1, arg2):
#outputs prodos creation date/time as Unix time
# (seconds since Jan 1 1970 GMT)
#or None if there is none
start = getStartPos(arg1, arg2)
pdosDate = (hexToBin(readcharHex(g.imageData, start+25)) +
hexToBin(readcharHex(g.imageData, start+24)) +
hexToBin(readcharHex(g.imageData, start+27)) +
hexToBin(readcharHex(g.imageData, start+26)))
try:
rVal = pdosDateToUnixDate(pdosDate)
except Exception:
rVal = None
return rVal
def getModifiedDate(arg1, arg2):
#outputs prodos modified date/time as Unix time
# (seconds since Jan 1 1970 GMT)
#or None if there is none
start = getStartPos(arg1, arg2)
pdosDate = (hexToBin(readcharHex(g.imageData, start+34)) +
hexToBin(readcharHex(g.imageData, start+33)) +
hexToBin(readcharHex(g.imageData, start+36)) +
hexToBin(readcharHex(g.imageData, start+35)))
try:
rVal = pdosDateToUnixDate(pdosDate)
except Exception:
rVal = None
return rVal
def getVolumeName():
return getWorkingDirName(2)
def getWorkingDirName(arg1):
start = ( arg1 * 512 )
firstByte = readcharDec(g.imageData, start+4)
entryType = (firstByte//16)
nameLength = (firstByte - entryType*16)
return readchars(g.imageData, start+5, nameLength)
def getDirEntryCount(arg1):
start = ( arg1 * 512 )
return (readcharDec(g.imageData, start+37) +
readcharDec(g.imageData, start+38)*256)
def getDirNextChunkPointer(arg1):
start = ( arg1 * 512 )
return (readcharDec(g.imageData, start+2) +
readcharDec(g.imageData, start+3)*256)
# -- script begins in earnest here
def copyFile(arg1, arg2):
g.outFileData = bytearray(b'')
g.exFileData = bytearray(b'')
g.activeFileBytesCopied = 0
storageType = getStorageType(arg1, arg2)
keyPointer = getKeyPointer(arg1, arg2)
fileLen = getFileLength(arg1, arg2)
if (storageType == 1): #seedling
copyBlock(keyPointer, fileLen)
elif (storageType == 2): #sapling
processIndexBlock(keyPointer)
elif (storageType == 3): #tree
processMasterIndexBlock(keyPointer)
elif (storageType == 5): #extended (forked)
processForkedFile(keyPointer)
def copyBlock(arg1, arg2):
#arg1: block to copy
#arg2: bytes to write (should be 512,
# unless final block with less than 512 bytes)
#print(arg1 + " " + arg2 + " " + g.activeFileBytesCopied)
if (arg1 == 0):
outBytes = (b'\x00' * arg2)
else:
outBytes = slyce(g.imageData, arg1*512, arg2)
if (g.resourceFork > 0):
if g.AD:
g.adFileData[g.activeFileBytesCopied+741:
(g.activeFileBytesCopied+741 + arg2)] = outBytes
if g.EX:
g.exFileData[g.activeFileBytesCopied:
(g.activeFileBytesCopied + arg2)] = outBytes
else:
g.outFileData[g.activeFileBytesCopied:
(g.activeFileBytesCopied + arg2)] = outBytes
g.activeFileBytesCopied += arg2
def processDir(arg1, arg2=None, arg3=None, arg4=None, arg5=None):
# arg1: dirBlock
# arg2/3/4/5: for non-key chunks: entryCount, entry#,
# workingDirName, processedEntryCount
entryCount = None
e = None
pe = None
workingDirName = None
if arg2:
entryCount = arg2
e = arg3
workingDirName = arg4
pe = arg5
else:
e = 0
pe = 0
entryCount = getDirEntryCount(arg1)
workingDirName = getWorkingDirName(arg1).decode("L1")
g.DIRPATH = (g.DIRPATH + "/" + workingDirName)
if g.PDOSPATH_INDEX:
if (g.PDOSPATH_INDEX == 1):
if (("/" + g.PDOSPATH_SEGMENT) != g.DIRPATH):
print("ProDOS volume name does not match disk image.")
sys.exit(2)
else:
g.PDOSPATH_INDEX += 1
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
else:
print(g.DIRPATH)
while (pe < entryCount):
if (getStorageType(arg1, e) > 0):
processEntry(arg1, e)
pe += 1
e += 1
if not ((e + ( e>11 ) ) % 13):
processDir(getDirNextChunkPointer(arg1),
entryCount,
e,
workingDirName,
pe)
break
def processEntry(arg1, arg2):
'''
print(getFileName(arg1, arg2), getStorageType(arg1, arg2),
getFileType(arg1, arg2), getKeyPointer(arg1, arg2),
getFileLength(arg1, arg2), getAuxType(arg1, arg2),
getCreationDate(arg1, arg2), getModifiedDate(arg1, arg2))
'''
g.activeFileName = getFileName(arg1 ,arg2).decode("L1")
g.activeFileSize = getFileLength(arg1, arg2)
if ((not g.PDOSPATH_INDEX) or (g.activeFileName == g.PDOSPATH_SEGMENT)):
if (getStorageType(arg1, arg2) == 13): # if ProDOS directory
if not g.PDOSPATH_INDEX:
g.targetDir = (g.targetDir + "/" + g.activeFileName)
g.ADdir = (g.targetDir + "/.AppleDouble")
if not (g.DIR or os.path.isdir(g.targetDir)):
makedirs(g.targetDir)
if not (g.DIR or (not g.AD) or os.path.isdir(g.ADdir)):
makedirs(g.ADdir)
if g.PDOSPATH_SEGMENT:
g.PDOSPATH_INDEX += 1
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
processDir(getKeyPointer(arg1, arg2))
g.DIRPATH = g.DIRPATH.rsplit("/", 1)[0]
if not g.PDOSPATH_INDEX:
g.targetDir = g.targetDir.rsplit("/", 1)[0]
g.ADdir = (g.targetDir + "/.AppleDouble")
else: # if ProDOS file
if not g.PDOSPATH_INDEX:
print(" " + g.activeFileName)
if g.DIR:
return
if not g.targetName:
g.targetName = g.activeFileName
if g.EX:
eTargetName = (g.targetName + "#" +
getFileType(arg1, arg2).lower() +
getAuxType(arg1, arg2).lower())
touch(g.targetDir + "/" + g.targetName)
if g.AD: makeADfile()
copyFile(arg1, arg2)
saveFile((g.targetDir + "/" + g.targetName), g.outFileData)
creationDate = getCreationDate(arg1, arg2)
modifiedDate = getModifiedDate(arg1, arg2)
if (creationDate is None and modifiedDate is not None):
creationDate = modifiedDate
elif (creationDate is not None and modifiedDate is None):
modifiedDate = creationDate
elif (creationDate is None and modifiedDate is None):
creationDate = (datetime.datetime.today() -
datetime.datetime(1970,1,1)).days*24*60*60
modifiedDate = creationDate
if g.AD: # AppleDouble
# set dates
ADfilePath = (g.ADdir + "/" + g.targetName)
writecharsHex(g.adFileData,
637,
(unixDateToADDate(creationDate) +
unixDateToADDate(modifiedDate)))
writecharHex(g.adFileData, 645, "80")
writecharHex(g.adFileData, 649, "80")
#set type/creator
writechars(g.adFileData, 653, b'p')
writecharsHex(g.adFileData,
654,
(getFileType(arg1, arg2) +
getAuxType(arg1, arg2)))
writechars(g.adFileData, 657, b'pdos')
saveFile(ADfilePath, g.adFileData)
touch((g.targetDir + "/" + g.targetName), modifiedDate)
if g.EX: # extended name
os.rename((g.targetDir + "/" + g.targetName),
(g.targetDir + "/" + eTargetName))
if (len(g.exFileData) > 0):
saveFile((g.targetDir + "/" + eTargetName + "r"),
g.exFileData)
touch((g.targetDir + "/" + eTargetName + "r"),
modifiedDate)
if g.PDOSPATH_SEGMENT:
syncExit()
g.targetName = None
#else:
#print(g.activeFileName + " doesn't match " + g.PDOSPATH_SEGMENT)
def processForkedFile(arg1):
# finder info except type/creator
fInfoA_entryType = readcharDec(g.imageData, 9)
fInfoB_entryType = readcharDec(g.imageData, 27)
if (fInfoA_entryType == 1):
writechars(g.imageData, 661, readchars(g.imageData, 18, 8))
elif (fInfoA_entryType == 2):
writechars(g.imageData, 669, readchars(g.imageData, 10, 16))
if (fInfoB_entryType == 1):
writechars(g.imageData, 661, readchars(g.imageData, 36, 8))
elif (fInfoB_entryType == 2):
writechars(g.imageData, 669, readchars(g.imageData, 28, 16))
for f in [0, 256]:
g.resourceFork = f
g.activeFileBytesCopied = 0
forkStart = (arg1 * 512) # start of Forked File key block
# print("--" + forkStart)
forkStorageType = readcharDec(g.imageData, forkStart+f+0)
forkKeyPointer = (readcharDec(g.imageData, forkStart+f+1) +
readcharDec(g.imageData, forkStart+f+2)*256)
forkFileLen = (readcharDec(g.imageData, forkStart+f+5) +
readcharDec(g.imageData, forkStart+f+6)*256 +
readcharDec(g.imageData, forkStart+f+7)*256*256)
g.activeFileSize = forkFileLen
if (g.resourceFork > 0):
rsrcForkLenHex = (readcharHex(g.imageData, forkStart+f+7) +
readcharHex(g.imageData, forkStart+f+6) +
readcharHex(g.imageData, forkStart+f+5))
# print(">>>" + rsrcForkLenHex)
print(" [resource fork]")
if g.AD:
writecharsHex(g.adFileData, 35, rsrcForkLenHex)
else:
print(" [data fork]")
if (forkStorageType == 1): #seedling
copyBlock(forkKeyPointer, forkFileLen)
elif (forkStorageType == 2): #sapling
processIndexBlock(forkKeyPointer)
elif (forkStorageType == 3): #tree
processMasterIndexBlock(forkKeyPointer)
# print()
g.resourceFork = 0
def processMasterIndexBlock(arg1):
processIndexBlock(arg1, True)
def processIndexBlock(arg1, arg2=False):
#arg1: indexBlock
#arg2: if True, it's a Master Index Block
pos = 0
bytesRemaining = g.activeFileSize
while (g.activeFileBytesCopied < g.activeFileSize):
targetBlock = (readcharDec(g.imageData, arg1*512+pos) +
readcharDec(g.imageData, arg1*512+(pos+256))*256)
if arg2:
processIndexBlock(targetBlock)
else:
bytesRemaining = (g.activeFileSize - g.activeFileBytesCopied)
bs = (bytesRemaining if (bytesRemaining < 512) else 512)
copyBlock(targetBlock, bs)
pos += 1
if (pos > 255):
break # go to next entry in Master Index Block (tree)
def makeADfile():
if not g.AD: return
touch(g.ADdir + "/" + g.targetName)
g.adFileData = bytearray(b'\x00' * 741)
# ADv2 header
writecharsHex(g.adFileData, hexToDec("00"), "0005160700020000")
# number of entries
writecharsHex(g.adFileData, hexToDec("18"), "000D")
# Resource Fork
writecharsHex(g.adFileData, hexToDec("1A"), "00000002000002E500000000")
# Real Name
writecharsHex(g.adFileData, hexToDec("26"), "00000003000000B600000000")
# Comment
writecharsHex(g.adFileData, hexToDec("32"), "00000004000001B500000000")
# Dates Info
writecharsHex(g.adFileData, hexToDec("3E"), "000000080000027D00000010")
# Finder Info
writecharsHex(g.adFileData, hexToDec("4A"), "000000090000028D00000020")
# ProDOS file info
writecharsHex(g.adFileData, hexToDec("56"), "0000000B000002C100000008")
# AFP short name
writecharsHex(g.adFileData, hexToDec("62"), "0000000D000002B500000000")
# AFP File Info
writecharsHex(g.adFileData, hexToDec("6E"), "0000000E000002B100000004")
# AFP Directory ID
writecharsHex(g.adFileData, hexToDec("7A"), "0000000F000002AD00000004")
# dbd (second time) will create DEV, INO, SYN, SV~
def syncExit():
if (not g.silent and g.AD and os.path.isdir("/usr/local/etc/netatalk")):
print("File(s) have been copied to the target directory. " +
"If the directory")
print("is shared by Netatalk, please type 'afpsync' now.")
# saveFile(g.imageFile, g.imageData)
sys.exit(0)
def usage():
print(sys.modules[__name__].__doc__)
sys.exit(1)
# --- ID bashbyter functions (adapted)
def decToHex(arg1):
# converts single-byte decimal value to hexadecimal equivalent
# arg: decimal value from 0-255
# out: two-digit hex string from 00-FF
#exit: 21=invalid arg
if (arg1<0 or arg1>255): sys.exit(21)
return to_hex(arg1).upper()
def hexToDec(arg1):
# converts single-byte hexadecimal value to decimal equivalent
# arg: two-digit hex value from 00-FF
# out: decimal value
#exit: 21=invalid arg
if (len(arg1) != 2): return 21
return to_dec(arg1)
def hexToBin(arg1):
# converts single-byte hexadecimal value to binary string
# arg: two-digit hex value from 00-FF
# out: binary string value
#exit: 21=invalid arg
if (len(arg1) != 2): return 21
return to_bin(arg1).zfill(8)
def binToDec(arg1):
# converts single-byte binary string (8 bits) value to decimal
# warning: no error checking
# arg: binary string up to 8 bits
# out: decimal value
return to_dec([arg1])
def binToHex(arg1):
# converts single-byte binary string (8 bits) value to hex
# warning: no error checking
# arg: binary string up to 8 bits
# out: hex value
return to_hex(arg1).upper()
def charToDec(arg1):
# converts single char (of type bytes) to corresponding decimal value
# arg: one char (of type bytes)
# out: decimal value from 0-255
#exit: 21=invalid arg
if (len(arg1) != 1): return 21
return to_dec(arg1)
def charToHex(arg1):
# converts single char (of type bytes) to corresponding hex value
# arg: one char (of type bytes)
# out: hexadecimal value from 00-FF
#exit: 21=invalid arg
if (len(arg1) != 1): return 21
return to_hex(arg1).upper()
def decToChar(arg1):
# converts single-byte decimal value to equivalent char (of type bytes)
# arg: decimal number from 0-255
# out: one character
#exit: 21=invalid arg
if (arg1<0 or arg1>255): sys.exit(21)
return to_bytes(arg1)
def hexToChar(arg1):
# converts single-byte hex value to corresponding char (of type bytes)
# arg: two-digit hexadecimal number from 00-FF
# out: one character
#exit: 21=invalid arg
if (len(arg1) != 2): return 21
return to_bytes(arg1)
def readchars(arg1, arg2=0, arg3=0):
# read one or more characters from a bytes variable
# arg1: bytes or bytearray variable
# arg2: (optional) offset (# of bytes to skip before reading)
# arg3: (optional) # of chars to read (default is to end of bytes var)
# out: sequence of characters (bytes or bytearray)
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)):
sys.exit(21)
if (arg2<0): sys.exit(22)
if (arg3<0): sys.exit(23)
if (arg3 == 0):
arg3 = len(arg1)
return slyce(arg1, arg2, arg3)
def readcharDec(arg1, arg2=0):
# read one character from bytes var & convert to equivalent dec value
# arg1: bytes var
# arg2: (optional) offset (# of bytes to skip before reading)
# out: decimal value from 0-255
# exit: 21=invalid arg1, 22=invalid arg2
if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)):
sys.exit(21)
if (arg2<0): sys.exit(22)
return to_dec(slyce(arg1, arg2, 1))
def readcharHex(arg1, arg2=0):
# read one character from bytes var & convert to corresponding hex value
# arg1: bytes var
# arg2: (optional) offset (# of bytes to skip before reading)
# out: two-digit hex value from 00-FF
# exit: 21=invalid arg1, 22=invalid arg2
if not (isinstance(arg1, bytes) or isinstance(arg1, bytearray)):
sys.exit(21)
if (arg2<0): sys.exit(22)
return to_hex(slyce(arg1, arg2, 1))
def writechars(arg1, arg2, arg3):
# write one or more characters (bytes) to bytearray
# arg1: bytearray variable
# arg2: offset (# of bytes to skip before writing)
# arg3: sequence of bytes (or bytearray)
# out: nothing
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
if not isinstance(arg1, bytearray): sys.exit(21)
if (arg2<0): sys.exit(22)
if not (isinstance(arg3, bytes) or isinstance(arg3, bytearray)):
sys.exit(23)
arg1[arg2:arg2+len(arg3)] = arg3
def writecharDec(arg1, arg2, arg3):
# write corresponding char of single-byte decimal value into bytearray
# arg1: bytearray
# arg2: offset (# of bytes to skip before writing)
# arg3: decimal number from 0-255
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
# out: nothing
if not isinstance(arg1, bytearray): sys.exit(21)
if (arg2<0): sys.exit(22)
if not isnumber(arg3): sys.exit(23)
arg1[arg2:arg2+1] = to_bytes(arg3)
def writecharHex(arg1, arg2, arg3):
# write corresponding character of single-byte hex value into bytearray
# arg1: bytearray
# arg2: offset (# of bytes to skip before writing)
# arg3: two-digit hexadecimal number from 00-FF
# out: nothing
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
if not isinstance(arg1, bytearray): sys.exit(21)
if (arg2<0): sys.exit(22)
if not isinstance(arg3, type("".encode().decode())): sys.exit(23)
arg1[arg2:arg2+1] = to_bytes(arg3)
def writecharsHex(arg1, arg2, arg3):
# write corresponding characters of hex values into bytearray
# arg1: bytearray
# arg2: offset (# of bytes to skip before writing)
# arg3: string of two-digit hexadecimal numbers from 00-FF
# out: nothing
# exit: 21=invalid arg1, 22=invalid arg2, 23=invalid arg3
if not isinstance(arg1, bytearray): sys.exit(21)
if (arg2<0): sys.exit(22)
if not isinstance(arg3, type("".encode().decode())): sys.exit(23)
arg1[arg2:arg2+len(to_bytes(arg3))] = to_bytes(arg3)
#---- IvanX general purpose functions ----#
def slyce(val, start_pos=0, length=1, reverse=False):
"""returns slice of object (but not a slice object)
allows specifying length, and 3.x "bytes" consistency"""
the_slyce = val[start_pos:start_pos+length]
return (the_slyce[::-1] if reverse else the_slyce)
def to_hex(val):
"""convert bytes, decimal number, or [bin-ustr] to two-digit hex values
unlike hex(), accepts bytes; has no leading 0x or trailing L"""
from binascii import b2a_hex
if isinstance(val, list): # [bin-ustr]
val = int(val[0], 2)
if isinstance(val, bytes): # bytes
return b2a_hex(val).decode("L1")
elif isnumber(val):
# .encode().decode() always returns unicode in both P2 and P3
return (hex(val)[2:].split("L")[0]).encode("L1").decode("L1")
else:
raise Exception("to_hex() requires bytes, int/long, or [bin-ustr]")
def hex_slyce(val, start_pos=0, length=1, little_endian=False):
"""returns bytes slyce as hex-ustr"""
return to_hex(slyce(val, start_pos, length, little_endian))
def dec_slyce(val, start_pos=0, length=1, little_endian=False):
"""returns bytes slyce converted to decimal int/long"""
return to_dec(hex_slyce(val, start_pos, length, little_endian))
def bin_slyce(val, start_pos=0, length=1, little_endian=False):
"""returns bytes slyce converted to bin-ustr"""
return to_bin(hex_slyce(val, start_pos, length, little_endian))
def to_dec(val):
"""convert bytes, hex-ustr or [bin-ustr] to decimal int/long"""
if isinstance(val, list): # [bin-ustr]
return int(val[0], 2)
elif isinstance(val, bytes): # bytes
return int(to_hex(val), 16)
elif isinstance(val, type("".encode().decode())): # hex-ustr
return int(val, 16)
else:
raise Exception("to_dec() requires bytes, hex-ustr or [bin-ustr]")
def to_bin(val):
"""convert bytes, hex-ustr, or int/long to bin-ustr"""
if isinstance(val, bytes): # bytes
return (bin(to_dec(to_hex(val))))[2:].encode("L1").decode("L1")
elif isinstance(val, type("".encode().decode())): # hex-ustr
return (bin(int(val, 16)))[2:].encode("L1").decode("L1")
elif isnumber(val): # int/long
return (bin(val))[2:].encode("L1").decode("L1")
else:
raise Exception("to_bin() requires bytes, hex-ustr, or int/long")
def to_bytes(val):
"""converts hex-ustr, int/long, or [bin-ustr] to bytes"""
from binascii import a2b_hex
if isinstance(val, list): # [bin-ustr]
val = to_hex(val[0])
if isnumber(val): # int/long
val = to_hex(val)
if isinstance(val, type("".encode().decode())): # hex-ustr
return a2b_hex(bytes(val.encode("L1"))) # works on both P2 and P3
else:
raise Exception(
"to_bytes() requires hex-ustr, int/long, or [bin-ustr]")
def shift(items):
"""Shift list items to left, losing the first item.
in : list
out: list
"""
for i in range(0, (len(items)-1)):
items[i] = items[i+1]
del items[-1]
return items
def s(string):
"""Perform local variable substution, e.g. 'total: {num} items'"""
# http://stackoverflow.com/questions/2960772/
# putting-a-variable-inside-a-string-python
# http://stackoverflow.com/questions/6618795/
# get-locals-from-calling-namespace-in-python
import inspect
frame = inspect.currentframe()
try:
rVal = string.format(**frame.f_back.f_locals)
finally:
del frame
return rVal
def get_object_names(cls, include_subclasses=True):
object_names = []
for (this_object_name, this_object_id) in list(globals().items()):
if include_subclasses:
if isinstance(this_object_id, cls):
object_names.append(this_object_name)
else:
if type(this_object_id) is cls:
object_names.append(this_object_name)
return object_names
def touch(filePath, modTime=None):
# http://stackoverflow.com/questions/1158076/implement-touch-using-python
import os
if (os.name == "nt"):
if filePath[-1] == ".": filePath += "-"
filePath = filePath.replace("./", ".-/")
with open(filePath, "ab"):
os.utime(filePath, (None if (modTime is None) else (modTime, modTime)))
def mkdir(dirPath):
import os
if (os.name == "nt"):
if dirPath[-1] == ".": dirPath += "-"
dirPath = dirPath.replace("./", ".-/")
try:
os.mkdir(dirPath)
except FileExistsError:
pass
def makedirs(dirPath):
import os
if (os.name == "nt"):
if dirPath[-1] == ".": dirPath += "-"
dirPath = dirPath.replace("./", ".-/")
try:
os.makedirs(dirPath)
except FileExistsError:
pass
def loadFile(filePath):
import os
if (os.name == "nt"):
if filePath[-1] == ".": filePath += "-"
filePath = filePath.replace("./", ".-/")
with open(filePath, "rb") as imageHandle:
return imageHandle.read()
def saveFile(filePath, fileData):
import os
if (os.name == "nt"):
if filePath[-1] == ".": filePath += "-"
filePath = filePath.replace("./", ".-/")
with open(filePath, "wb") as imageHandle:
imageHandle.write(fileData)
def isnumber(number):
try: # make sure it's not a string
len(number)
return False
except TypeError:
pass
try:
int(number)
except ValueError:
return False
return True
#---- end IvanX general purpose functions ----#
# --- start
args = sys.argv
if (len(args) == 1):
usage()
if (args[1] == "-s"):
g.silent=1
args = args[1:] #shift
if (args[1] == "-ad"):
g.AD = 1
args = args[1:] #shift
if (args[1] == "-e"):
if g.AD: usage()
g.EX = 1
args = args[1:] #shift
if (args[1] == "-cat"):
g.DIR = 1
args = args[1:]
if not ((g.DIR and len(args) >= 2) or (len(args) >= 3)):
usage()
if ((len(args) == 4) and
(slyce(args[2],0,1) != "/") and
(slyce(args[2],0,1) != ":")):
usage()
g.imageFile = args[1]
if not os.path.isfile(g.imageFile):
print("Source " + g.imageFile + " was not found.")
sys.exit(2)
g.imageData = loadFile(g.imageFile)
if (len(args) == 4):
g.PDOSPATH = args[2].upper()
targetPath = args[3]
if os.path.isdir(targetPath):
g.targetDir = targetPath
else:
g.targetDir = targetPath.rsplit("/", 1)[0]
g.targetName = targetPath.rsplit("/", 1)[1]
if not os.path.isdir(g.targetDir):
print("Target directory not found.")
sys.exit(2)
else:
if not g.DIR:
if not os.path.isdir(args[2]):
print("Target directory not found.")
sys.exit(2)
g.activeDirBlock = 0
g.activeFileName = ""
g.activeFileSize = 0
g.activeFileBytesCopied = 0
g.resourceFork = 0
g.PDOSPATH_INDEX = 0
if (len(args) == 4):
g.PDOSPATH = g.PDOSPATH.replace(':', '/').split('/')
if not g.PDOSPATH[0]:
g.PDOSPATH_INDEX += 1
g.PDOSPATH_SEGMENT = g.PDOSPATH[g.PDOSPATH_INDEX]
g.ADdir = (g.targetDir + "/.AppleDouble")
if not ((not g.AD) or os.path.isdir(g.ADdir)):
mkdir(g.ADdir)
processDir(2)
print("ProDOS file not found within image file.")
sys.exit(2)
else:
if not g.DIR:
# print(args[0], args[1], args[2])
g.targetDir = (args[2] + "/" + getVolumeName().decode("L1"))
g.ADdir = (g.targetDir + "/.AppleDouble")
if not os.path.isdir(g.targetDir):
makedirs(g.targetDir)
if not ((not g.AD) or os.path.isdir(g.ADdir)):
makedirs(g.ADdir)
processDir(2)
if not g.DIR:
syncExit()

View File

@@ -1,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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,541 +0,0 @@
#! /usr/bin/env python
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=python:
from __future__ import print_function
import os, sys, subprocess
import tempfile
import hashlib
import shutil
import xml.etree.cElementTree as ET
quiet = False
verbose = True
disk7_sources = {
"file" : "Disk_7_of_7-Apple_II_Setup.sea.bin",
"digest" : "43fbc296ab66da84aadc275b80fd51ec4f7fe986",
"type" : "sea.bin",
"sources" : [
( "Apple", "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" ),
( "archive.org", "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" )
]
}
a2boot_files = [
{
"unix" : "Apple ::e Boot Blocks",
"hfsutils" : "Apple_--e_Boot_Blocks.bin",
"netatalk" : "Apple :2f:2fe Boot Blocks",
"digest" : "cada362ac2eca3ffa506e9b4e76650ba031e0035",
"patches" : (
[
"Cleartext password login bug",
(0x4d43, b"\xA8\xA2\x01\xBD\x80\x38\x99\xA0\x38\xC8\xE8\xE0\x09\x90\xF4"),
"ProDOS 8 patch: year table, splash date (6.0.3)",
(0x004f, b"\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5"),
(0x1b9f, b"\x12\x11\x0b\x10\x0f\x0e\x0d"),
],
"8cff6ef453533423b34b5b4fefd642441e2ee374",
),
},
{
"unix" : "Basic.System",
"hfsutils" : "Basic.System.bin",
"netatalk" : "Basic.System",
"digest" : "4d53424f1451cd2e874cf792dbdc8cc6735dcd36",
},
{
"unix" : "ProDOS16 Boot Blocks",
"hfsutils" : "ProDOS16_Boot_Blocks.bin",
"netatalk" : "ProDOS16 Boot Blocks",
"digest" : "fab829e82e6662ed6aab119ad18e16ded7d43cda",
},
{
"unix" : "ProDOS16 Image",
"hfsutils" : "ProDOS16_Image.bin",
"netatalk" : "ProDOS16 Image",
"digest" : "db4608067b9e7877f45eb557971c4d8c45b46be5",
"patches" : (
[
"Cleartext password login bug",
(0x5837, b"\xA8\xA2\x01\xBD\x80\x10\x99\xA0\x10\xC8\xE8\xE0\x09\x90\xF4"),
"Enable pressing \"8\" during GS/OS netboot to load ProDOS 8",
(0x0100, b"\x92"),
(0x0360, b"\x20\x7d\x14"),
(0x067d, b"\xad\x00\xc0\x29\xff\x00\xc9\xb8\x00\xd0\x06\xa9\x02\x00\x8d\x53\x14\xa9\x10\x0f\x60"),
"ProDOS 8 patch: year table, splash date (6.0.3)",
(0x0c26, b"\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5"),
(0x1b76, b"\x12\x11\x0b\x10\x0f\x0e\x0d"),
],
"1f0477030b7e9c809b0a2282896ca66033e7ca9f",
),
},
{
"unix" : "p8",
"hfsutils" : "p8.bin",
"netatalk" : "p8",
# 36c288a5272cf01e0a64eed16786258959118e0e P8 (02-Apr-93, a2setup)
# c99f69c8dbfe79f02c715162fb409aedf52d378a P8 (06-May-93, 6.0.1)
# Only splash date differs.
"digest" : "36c288a5272cf01e0a64eed16786258959118e0e",
"patches" : (
[
# May as well patch the splash as well. *shrug*
"ProDOS 8 patch: year table, splash date (6.0.3)",
(0x0026, b"\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5"),
(0x0f76, b"\x12\x11\x0b\x10\x0f\x0e\x0d"),
],
"ad1e6c8f653df428d13cb8ae5ce4f8425a52016b",
),
},
]
# True for Python 3.0 and later
PY3 = sys.version_info >= (3, 0)
if PY3:
stdin_input = input
import urllib.request as urlrequest
else:
stdin_input = raw_input
import urllib2 as urlrequest
def sha1sum_file (filename, blocksize=65536):
f = open(filename, "rb")
digest = hashlib.sha1()
buf = f.read(blocksize)
while len(buf) > 0:
digest.update(buf)
buf = f.read(blocksize)
f.close()
return digest.hexdigest()
def download_from_sources(fileinfo, output_dir):
output_path = os.path.join(output_dir, fileinfo["file"])
if not quiet:
print("Downloading %s" % (fileinfo["file"]))
for (source, url) in fileinfo["sources"]:
if not quiet:
print(" From %s..." % (source), end="")
try:
html = urlrequest.urlopen(url)
data = html.read()
f = open(output_path, "wb")
f.write(data)
f.close()
except:
if not quiet:
print(" download failed.")
if 'f' in locals():
if not f.isclosed():
f.close()
continue
digest = sha1sum_file(output_path)
if digest == fileinfo["digest"]:
if not quiet:
print(" successfully downloaded.")
return True
else:
if not quiet:
print(" failed (digest mismatch).")
if verbose:
print(" Expected: %s\n Received: %s"
% (fileinfo["digest"], digest))
return False
# Apple's GS/OS 6.0.1 images are stored in MacBinary-wrapped
# self-extracting disk image files. The Unarchiver's unar is able
# to unwrap the MacBinary wrapper for us, but we have to extract the
# disk image oursselves. Fortunately, it's uncompressed.
def extract_800k_sea_bin(archive_name, image_name, archive_dir):
if not quiet:
print("Extracting %s..." % (archive_name), end="")
archive_path = os.path.join(archive_dir, archive_name)
image_path = os.path.join(archive_dir, image_name)
if not os.path.isfile(archive_path):
if not quiet:
print(" not found.")
return False
# Extract the original filename from the file
# MacBinary II header is 128 bytes. The first byte is NUL, followed by a
# Pascal string of length 63 (so 64 bytes total) containing the encoded
# filename.
#
# Source: http://files.stairways.com/other/macbinaryii-standard-info.txt
# FIXME: We should eventually implement a full MacBinary reader.
try:
f = open(archive_path, "rb")
sea_name = f.read(65)
f.close()
if len(sea_name) < 65:
if not quiet:
print(" file too short.")
return False
if PY3:
sea_name = sea_name[2:2 + sea_name[1]].decode("mac_roman")
else:
sea_name = sea_name[2:2 + ord(sea_name[1])]
except:
if not quiet:
print(" error: cannot read expanded name")
if 'f' in locals():
if not f.isclosed():
f.close()
return False
try:
cmdline = ["unar", "-q", "-o", archive_dir, "-k", "skip", archive_path]
ret = subprocess.call(cmdline)
if ret != 0:
if not quiet:
print(" error: unar returned error %i" % (ret))
return False
except OSError as e:
if not quiet:
print(" error: running unar: %s" % (e))
return False
sea_path = os.path.join(archive_dir, sea_name)
if not os.path.isfile(sea_path):
if not quiet:
print(" error: \"%s\" was not extracted." % (sea_name))
return False
try:
# The image starts 84 bytes in, and is exactly 819200 bytes long
with open(sea_path, "rb") as src, open(image_path, "wb") as dst:
src.seek(84)
dst.write(src.read(819200))
if dst.tell() != 819200:
raise IOError()
extracted = True
except:
if not quiet:
print(" error: \"%s\" is not an 800k floppy image"
% (sea_name))
extracted = False
finally:
if not quiet:
print(" done.")
os.unlink(sea_path)
os.unlink(archive_path)
return extracted
def plist_keyvalue(plist_dict, key):
if plist_dict.tag != "dict":
raise ValueError("not a plist dict")
found = False
for elem in plist_dict:
if found:
return elem
if elem.tag == "key" and elem.text == key:
found = True
return None
def find_mountpoint(xmlstr):
plistroot = ET.fromstring(xmlstr)
if plistroot.tag != "plist":
raise ValueError("xmlstr is not an XML-format plist")
if plistroot[0].tag == "dict":
sys_entities = plist_keyvalue(plistroot[0], "system-entities")
if sys_entities.tag != "array":
raise ValueError("expected dict to contain an array")
for child in sys_entities:
if child.tag == "dict":
mountpoint = plist_keyvalue(child, "mount-point")
return mountpoint.text
else:
raise ValueError("system-entities should be an array of dict objects")
else:
raise ValueError("Root element is not a dict")
a2setup_platform = None
def a2setup_set_platform():
global a2setup_platform
a2setup_platform = os.uname()[0]
if a2setup_platform not in ["Linux", "Darwin"]:
a2setup_platform = "hfsutils"
elif a2setup_platform == "Linux":
use_sudo = False
if os.geteuid() != 0:
reply = stdin_input("""
You must have either root access or the hfsutils package to
access the disk image containing Apple // boot blocks. Do
you want to mount the image using the sudo command? [y] """)
if reply.startswith("y") or reply.startswith("Y") or reply == "":
use_sudo = True
print("""
Okay, if asked for a password, type your user password. It
will not be echoed when you type.""")
else:
a2setup_platform = "hfsutils"
def a2setup_mount(image_path):
mountpoint = None
if a2setup_platform == "Linux":
mountpoint = tempfile.mkdtemp(prefix = "tmp-hfsmount.")
mount_cmd = ["mount", "-t", "hfs", "-o", "ro,loop", image_path, mountpoint]
if use_sudo:
mount_cmd = ["sudo"] + mount_cmd
subprocess.call(mount_cmd)
elif a2setup_platform == "Darwin":
xmlstr = subprocess.check_output(["hdiutil", "attach", "-plist",
image_path])
mountpoint = find_mountpoint(xmlstr)
elif a2setup_platform == "hfsutils":
mountpoint = tempfile.mkdtemp(prefix = "tmp-hfsmount.")
sys_folder = os.path.join(mountpoint, "System Folder")
os.mkdir(sys_folder)
devnull = open(os.devnull, "wb")
subprocess.call(["hmount", image_path], stdout=devnull)
devnull.close()
subprocess.call(["hcopy", "Apple II Setup:System Folder:*", sys_folder])
subprocess.call(["humount", "Apple II Setup"])
return mountpoint
def a2setup_copyfile(bootfile, mountpoint, dest_dir, dest_fmt):
src_dir = os.path.join(mountpoint, "System Folder")
if a2setup_platform == "Linux" or a2setup_platform == "Darwin":
src_path = os.path.join(src_dir, bootfile["unix"])
elif a2setup_platform == "hfsutils":
src_path = os.path.join(src_dir, bootfile["hfsutils"])
dest_path = os.path.join(dest_dir, bootfile[dest_fmt])
try:
shutil.copyfile(src_path, dest_path)
except:
return False
return True
def a2setup_umount(mountpoint):
if a2setup_platform == "Linux":
umount_cmd = ["umount", mountpoint]
if use_sudo:
umount_cmd = ["sudo"] + umount_cmd
subprocess.call(umount_cmd)
os.rmdir(mountpoint)
elif a2setup_platform == "Darwin":
devnull = open(os.devnull, "wb")
subprocess.call(["hdiutil", "eject", mountpoint], stdout=devnull)
devnull.close()
elif a2setup_platform == "hfsutils":
sys_folder = os.path.join(mountpoint, "System Folder")
for f in os.listdir(sys_folder):
os.unlink(os.path.join(sys_folder, f))
os.rmdir(sys_folder)
os.rmdir(mountpoint)
def apply_patches(bootfile, dest_dir, dest_fmt):
if "patches" in bootfile:
(patches, digest) = bootfile["patches"]
patch_path = os.path.join(dest_dir, bootfile[dest_fmt])
dest_digest = sha1sum_file(patch_path)
if dest_digest == digest:
if not quiet:
print(" \"%s\" is already patched." % (bootfile[dest_fmt]))
return True
else:
if verbose:
print(" Patching %s..." % (bootfile[dest_fmt]))
elif not quiet:
print(" Patching %s..." % (bootfile[dest_fmt]), end="")
f = open(patch_path, "r+b")
for patch in patches:
if isinstance(patch, str):
if verbose:
print(" %s" % (patch))
else:
(offset, data) = patch
f.seek(offset)
f.write(data)
f.close()
# Verify...
dest_digest = sha1sum_file(patch_path)
if dest_digest == digest:
print(" patched.")
else:
print(" patch failed.\n Expected: %s\n Received: %s"
% (bootfile["patches"][1], dest_digest))
return False
return True
def install_bootblocks(dest_dir, dest_fmt):
if dest_fmt not in ["unix", "netatalk"]:
raise ValueError("Only basic UNIX and netatalk formats are supported for now")
if not quiet:
print("Installing Apple // boot blocks...")
if not os.path.isdir(dest_dir):
os.makedirs(dest_dir, mode=0o0755)
work_dir = tempfile.mkdtemp(prefix = "tmp-a2sv-bootblocks.")
a2setup_name = "A2SETUP.img"
if verbose:
print(" dest_fmt : %s\n dest_dir : %s\n work_dir : %s\n"
% (dest_fmt, dest_dir, work_dir))
a2setup_set_platform()
a2boot_needed = False
a2setup_extracted = False
a2boot_installed = False
for bootfile in a2boot_files:
dest_path = os.path.join(dest_dir, bootfile[dest_fmt])
if not os.path.isfile(dest_path):
a2boot_needed = True
break
else:
dest_digest = sha1sum_file(dest_path)
if dest_digest != bootfile["digest"]:
if "patches" not in bootfile or dest_digest != bootfile["patches"][1]:
a2boot_needed = True
break
if not a2boot_needed:
if not quiet:
print("Files already copied.")
a2boot_installed = True
else:
if download_from_sources(disk7_sources, work_dir):
if disk7_sources["type"] == "sea.bin":
a2setup_extracted = extract_800k_sea_bin(disk7_sources["file"],
a2setup_name, work_dir)
else:
# Placeholder for 6.0.4+ files packed some other way
pass
if a2setup_extracted:
a2setup_path = os.path.join(work_dir, a2setup_name)
mountpoint = a2setup_mount(a2setup_path)
src_dir = os.path.join(mountpoint, "System Folder")
if not quiet:
print("Copying files...", end="")
a2boot_installed = True
for bootfile in a2boot_files:
if not a2setup_copyfile(bootfile, mountpoint, dest_dir, dest_fmt):
a2boot_installed = False
if not quiet:
if a2boot_installed:
print(" success.")
else:
print(" error copying files")
a2setup_umount(mountpoint)
os.unlink(a2setup_path)
os.rmdir(work_dir)
if not a2boot_installed and not quiet:
print("Installation failed.")
return False
for bootfile in a2boot_files:
apply_patches(bootfile, dest_dir, dest_fmt)
return True
def do_install():
netboot_tmp = tempfile.mkdtemp(suffix = ".a2server-netboot")
print("You'll want to go and delete this directory:")
print(netboot_tmp)
os.chdir(netboot_tmp)
# If we need boot files:
# Download a disk image
# If it is one we need to unpack (.sea.bin):
# unar it
# extract the embedded image
# If we need to apply boot block patches:
# fix cleartext password bug in //e boot block
# fix cleartext password bug in IIgs boot block
# patch IIgs boot block to allow booting ProDOS 8
# If we don't have A2SERVER tools:
# Download the installer script
# Run the installer script
# Copy Basic.System to A2FILES for ProDOS 8
# If NETBOOT.P8 (battery ram set to boot into ProDOS 8) doesn't exist:
# Create it
# If NETBOOT.GSOS (battery ram set to boot into GSOS) doesn't exist:
# Create it
# Set GS/OS to boot SYSTEM/FINDER (registered user or guest)
# Set ProDOS 8 to boot BASIC.SYSTEM (guest)
# If SYSTEM/START.GS.OS doesn't exist in A2FILES:
# Ask if user wants to install GS/OS 6.0.1
# If they answer yes:
# create imagesDir
# create netInstallDir
# For each disk:
# Download the disk
# If it is one we need to unpack (.sea.bin):
# extract_800k_sea_bin it
# unpack the disk to netInstallDir
# XXX Re-enable this
#os.rmdir(netboot_tmp)
if __name__ == '__main__':
# bail out on automated netboot setup unless -b is also specified
# FIXME: This logic belongs in a2server-setup, not here
autoAnswerYes = os.path.isfile("/tmp/a2server-autoAnswerYes")
if autoAnswerYes and not os.path.isfile("/tmp/a2server-setupNetBoot"):
sys.exit(0)
# We need root to do this. If we don't have it, just rerun the command with
# sudo and be done with it.
#
# FIXME: Should we be doing this? A generic installer should not assume it's
# writing to a root-owned dir, nor care. Probably the reason to do it this way
# is as a proof of concept that it can be done this way in the main
# a2server-setup script, which of course means we don't actually need to change
# the password for the user.
#
# XXX Disabling this for development
"""
if os.geteuid() != 0:
args = sys.argv
args.insert(0, "sudo")
# At the very least, we should print the command line we"re running here
print ("Rerunning with sudo...")
ret = subprocess.call(args)
sys.exit(ret)
"""
install_bootblocks(os.path.join(os.getcwd(), "a2boot"), "netatalk")
#reply = stdin_input("""\nDo you want to set up A2SERVER to be able to boot Apple II\ncomputers over the network? [y] """)
#if reply.startswith("y") or reply.startswith("Y") or reply == "":
# do_install()

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
View 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
View 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

View File

@@ -78,7 +78,7 @@ if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; 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
wget -qO /tmp/appletalk.ko.gz ${A2SERVER_SCRIPT_URL}files/appletalk-$kernelRelease.ko.gz
if [[ $? -eq 0 ]]; then
# if we found a prebuilt one on a2server site, so install it
gunzip -f /tmp/appletalk.ko.gz

View File

@@ -3,18 +3,29 @@
# --- Setting up the share volume
# 1.3.0: move /media/A2SHARED (pre-1.3.0) to /srv/A2SERVER
if [[ -d /media/A2SHARED ]]; then
echo "A2SERVER: Moving /media/A2SHARED to /srv/A2SERVER..."
sudo /etc/init.d/netatalk stop &> /dev/null
sudo /etc/init.d/samba stop &> /dev/null
[[ ! -d /srv ]] && sudo mkdir -p /srv
sudo mv /media/A2SHARED /srv/A2SERVER
sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /usr/local/etc/netatalk/AppleVolumes.default
[[ -f /etc/samba/smbd.conf ]] && sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /etc/samba/smbd.conf
fi
# skip if we're already set up
if [[ -d /media/A2SHARED ]]; then
if [[ -d /srv/A2SERVER ]]; then
echo "A2SERVER: Shared disk is already prepared for use."
echo "A2SERVER: Shared volume is already prepared for use."
else
echo "A2SERVER: Preparing the shared files disk..."
echo "A2SERVER: Preparing the shared files volume..."
sudo mkdir /media/A2SHARED
sudo mkdir -p /srv/A2SERVER
sudo chown $USER:$USER /media/A2SHARED
sudo chown $USER:$USER /srv/A2SERVER
fi

View File

@@ -7,32 +7,65 @@
# Ensure URL we'll use ends in a /
case "$A2SERVER_SCRIPT_URL" in
*/) 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
case "$A2SERVER_BINARY_URL" in
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;;
esac
useExternalURL=1
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
debianVersion=$(cat /etc/debian_version 2> /dev/null)
isRpi=
[[ -f /usr/bin/raspi-config ]] && isRpi=1
arch=
if [[ -f /usr/bin/raspi-config ]]; then
isRpi=1
arch='rpi'
elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then
uname_m="$(uname -m)"
if [[ $uname_m == "i686" ]]; then
arch='debian_x86'
elif [[ $uname_m == "x86_64" ]]; then
arch='debian_x64'
fi
fi
isDebian=
[[ ( -f /etc/debian_version ) && ( $(cut -c 1 < /etc/debian_version) -ge "7" ) && ( $(uname -m) == "i686" ) ]] && isDebian=1
isJessie=
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "8." ) ]] && isJessie=1
debianName=
if [[ $debianVersion ]]; then
debianMajor=$(cut -d . -f 1 <<< $debianVersion)
if [[ $debianMajor == "9" ]]; then
debianName="stretch"
elif [[ $debianMajor == "8" ]]; then
debianName="jessie"
elif [[ $debianMajor == "7" ]]; then
debianName="wheezy"
else
debianName="unknown"
fi
fi
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..."
cd /tmp
if [[ $isRpi ]]; then
wget -qO- "http://appleii.ivanx.com/a2server/files/nulib2-rpi.tgz" | sudo tar Pzx
elif [[ $isDebian ]]; then
wget -qO- "http://appleii.ivanx.com/a2server/files/nulib2-debian7_x86.tgz" | sudo tar Pzx
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${binaryURL}precompiled/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
fi
if ! command -v nulib2 > /dev/null; then
if ! hash nulib2 &> /dev/null; then
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
@@ -40,25 +73,35 @@ if ! command -v nulib2 > /dev/null; then
touch /tmp/a2server-packageReposUpdated
fi
sudo apt-get -y install build-essential
sudo apt-get -y install zlib1g-dev
# Dependencies: build-dep for nulib
sudo apt-get -y install build-essential 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*
rm -rf /tmp/nulib2 &> /dev/null
mkdir /tmp/nulib2
cd /tmp/nulib2
if [[ $useExternalURL ]]; then
wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7efb4d37fedf807416c16d74d51d893ea48a.zip"
unzip nulib2-3.1.0a2.zip 2> /dev/null
rm nulib2-3.1.0a2.zip &> /dev/null
fi
if [ ! -d nulib2* ]; then
wget -q -O nulib2-3.1.0a2.zip "${binaryURL}external/source/nulib2-3.1.0a2.zip"
unzip nulib2-3.1.0a2.zip 2> /dev/null
rm nulib2-3.1.0a2.zip &> /dev/null
fi
cd nulib2*
cd nufxlib
./configure
make
sudo make install
cd ../nulib2*
cd ../nulib2
./configure
make
sudo make install
cd
rm -rf /tmp/nulib
rm -rf /tmp/nulib2
fi
else
@@ -68,7 +111,7 @@ fi
# download and install The Unarchiver, for expanding Apple disk images
# 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..."
@@ -78,34 +121,39 @@ if ! command -v unar > /dev/null; then
touch /tmp/a2server-packageReposUpdated
fi
if [[ $isJessie ]]; then
sudo apt-get install -y unar
# jessie and later: Just use the unar package
if [[ $debianMajor -ge 8 ]]; then
sudo apt-get -y install unar
sudo apt-get clean
fi
if ! command -v unar > /dev/null; then
if [[ $isRpi || $isDebian ]]; then
if ! hash unar &> /dev/null; then
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
# Dependencies: for unar
sudo apt-get -y install libgnustep-base1.22
sudo apt-get clean
if [[ $isRpi ]]; then
wget -qO- "http://appleii.ivanx.com/a2server/files/unar-rpi_wheezy.tgz" | sudo tar Pzx
elif [[ $isDebian ]]; then
wget -qO- "http://appleii.ivanx.com/a2server/files/unar-debian7_x86.tgz" | sudo tar Pzx
fi
{ wget -qO- "${binaryURL}precompiled/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
fi
# If all else fails, compile from source.
if ! command -v unar >/dev/null; 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
if ! hash unar &> /dev/null; then
# Dependencies: build-deps for unar
sudo apt-get -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip
sudo apt-get clean
rm -rf /tmp/unar &> /dev/null
mkdir /tmp/unar
cd /tmp/unar
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
if [[ $useExternalURL ]]; then
wget -O unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip
unzip -o unar-1.8.1.zip &> /dev/null
fi
if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob
wget -O unar-1.8.1.zip ${binaryURL}external/source/unar-1.8.1.zip
unzip -o unar-1.8.1.zip &> /dev/null
fi
cd *Unarchiver*/XADMaster
make -f Makefile.linux
sudo mv lsar unar /usr/local/bin
cd ../Extra
@@ -119,9 +167,17 @@ else
echo "A2SERVER: The Unarchiver has already been installed."
fi
if ! command -v unzip >/dev/null; then
if ! hash unzip &> /dev/null; then
echo "A2SERVER: Installing unzip..."
sudo apt-get -y install unzip
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
# Dependencies: unzip
sudo apt-get -y install unzip
sudo apt-get clean
else
echo "A2SERVER: unzip has already been installed."
fi
@@ -138,15 +194,20 @@ sudo wget -q -O /usr/local/bin/cppo "${scriptURL}scripts/tools/cppo.txt"
sudo chmod ugo+x /usr/local/bin/cppo
sudo wget -q -O /usr/local/etc/a2server-help.txt "${scriptURL}scripts/tools/a2server-help.txt"
sudo wget -q -O /usr/local/etc/a2server-aliases "${scriptURL}scripts/tools/a2server-aliases.txt"
sudo wget -q -O /usr/local/etc/a2serverrc "${scriptURL}scripts/tools/a2serverrc.txt"
grep a2server-aliases /etc/bash.bashrc > /dev/null || \
echo "source /usr/local/etc/a2server-aliases" | sudo tee -a /etc/bash.bashrc > /dev/null
# 1.3.0: a2serverrc is now called from /etc/bash.bashrc,
# which in turn calls a2server-aliases
grep 'a2server-aliases' /etc/bash.bashrc > /dev/null && \
sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc
grep 'a2serverrc' /etc/bash.bashrc > /dev/null || \
echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc > /dev/null
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
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

View File

@@ -16,21 +16,57 @@
# Ensure URL we'll use ends in a /
case "$A2SERVER_SCRIPT_URL" in
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://appleii.ivanx.com/a2server}/" ;;
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
esac
case "$A2SERVER_BINARY_URL" in
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;;
esac
useExternalURL=1
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
debianVersion=$(cat /etc/debian_version 2> /dev/null)
isRpi=
[[ -f /usr/bin/raspi-config ]] && isRpi=1
arch=
if [[ -f /usr/bin/raspi-config ]]; then
isRpi=1
arch='rpi'
elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then
uname_m="$(uname -m)"
if [[ $uname_m == "i686" ]]; then
arch='debian_x86'
elif [[ $uname_m == "x86_64" ]]; then
arch='debian_x64'
fi
fi
isDebian_x86=
[[ ( -f /etc/debian_version ) && ( $(cut -c 1 < /etc/debian_version) -ge 7 ) && ( $(uname -m) == "i686" ) ]] && isDebian_x86=1
debianName=
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
isJessie=
[[ ( -f /etc/debian_version ) && ( $(cut -c 1-2 < /etc/debian_version) == "8." ) ]] && isJessie=1
# 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
if [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(cat /usr/local/etc/A2SERVER-version) >= 101 )); then
if [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) >= 101 )); then
echo "A2SERVER: Netatalk is already installed."
@@ -38,8 +74,11 @@ 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
# stop Netatalk and samba if running (during upgrade)
if [[ $(ps --no-headers -C afpd) ]]; then
sudo /etc/init.d/netatalk stop &> /dev/null
sudo /etc/init.d/samba stop &> /dev/null
fi
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
@@ -47,61 +86,68 @@ else
touch /tmp/a2server-packageReposUpdated
fi
# not being used as of 1.2.9, but it's available if full URL to .deb package is supplied
getOldPackage () {
for url in $@; do
pkgFile=${url##*/}
pkgName=${pkgFile%%_*}
if ! dpkg -l $pkgName 2> /dev/null | grep -q '^ii'; then
wget -qO /tmp/${url##*/} "$url"
sudo dpkg -i /tmp/${url##*/}
if [[ $useExternalURL ]]; then
wget -qO "/tmp/${url##*/}" "$url"
fi
if [[ $? -ne 0 || ! -f "/tmp/${url##*/}" ]]; then
wget -qO "/tmp/${url##*/}" "${binaryURL}external/deb/${url##*/}"
fi
sudo dpkg -i "/tmp/${url##*/}"
sudo apt-get clean
rm /tmp/${url##*/}
rm "/tmp/${url##*/}"
fi
done
}
compileFromSource=1
urls=
while [[ $isRpi || $isDebian_x86 ]]; do
while [[ $arch ]]; do
# Install runtime libraries needed by Netatalk
if [[ $isJessie ]]; then
if [[ $isRpi ]]; then
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/d/db/libdb5.1_5.1.29-5_armhf.deb"
elif [[ $isDebian_x86 ]]; then
getOldPackage "http://ftp.debian.org/debian/pool/main/d/db/libdb5.1_5.1.29-5_i386.deb"
fi
elif [[ $(apt-cache search '^libdb4.8$') ]]; then
sudo apt-get -y install libdb4.8
elif [[ $(apt-cache search '^libdb5.1$') ]]; then
if [[ $(apt-cache search '^libdb5.1$') ]]; then # Wheezy
# Dependencies: netatalk 2.2.4
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
break
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
sudo apt-get -y install libssl1.0.0
elif [[ $(apt-cache search '^libssl0.9.8$') ]]; then
sudo apt-get -y install libssl0.9.8
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
break
fi
if [[ $isJessie ]]; then
if [[ $isRpi ]]; then
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/libg/libgcrypt11/libgcrypt11_1.5.0-5+deb7u3_armhf.deb"
elif [[ $isDebian_x86 ]]; then
getOldPackage "http://ftp.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11_1.5.0-5+deb7u3_i386.deb"
fi
elif [[ $(apt-cache search '^libgcrypt11$') ]]; then
if [[ $(apt-cache search '^libgcrypt11$') ]]; then # Wheezy
# Dependencies: netatalk 2.2.4
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
break
fi
# install Netatalk
if [[ $isRpi ]]; then
{ wget -qO- /tmp/netatalk.tgz "http://appleii.ivanx.com/a2server/files/netatalk224-rpi_wheezy.tgz" | sudo tar Pzx; } 2> /dev/null
elif [[ $isDebian_x86 ]]; then
{ wget -qO- /tmp/netatalk.tgz "http://appleii.ivanx.com/a2server/files/netatalk224-debian7_x86.tgz" | sudo tar Pzx; } 2> /dev/null
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${binaryURL}precompiled/netatalk226-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null
fi
sudo mandb &> /dev/null
@@ -111,36 +157,60 @@ else
done
if [[ $compileFromSource ]]; then
# Install development libraries needed by Netatalk
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install build-essential
sudo apt-get -y install libssl-dev
if [[ $isJessie ]]; then
if [[ $isRpi ]]; then
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/d/db/libdb5.1-dev_5.1.29-5_armhf.deb"
elif [[ $isDebian_x86 ]]; then
getOldPackage "http://ftp.us.debian.org/debian/pool/main/d/db/libdb5.1-dev_5.1.29-5_i386.deb"
if [[ $(dpkg -l | grep libssl-dev | tr -s ' ' | cut -d ' ' -f 3 | cut -c 1-3) == "1.1" ]]; then
echo "A2SERVER: WARNING: libssl-dev 1.1 is already installed; removing."
sudo apt-get -y purge libssl-dev
sudo apt -y autoremove
fi
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
elif [[ $(apt-cache search '^libdb4.8-dev$') ]]; then
sudo apt-get -y install libdb4.8-dev
elif [[ $(apt-cache search '^libdb5.1-dev$') ]]; then
fi
if [[ $(apt-cache search '^libdb5.1-dev$') ]]; then # Wheezy
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libdb5.1-dev
elif [[ $(apt-cache search '^libdb5.3-dev$') ]]; then # Jessie, Stretch, Buster
# Dependencies: build-deps for netatalk 2.2.4
sudo apt-get -y install libdb5.3-dev
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
sudo apt-get -y install libdb-dev
fi
if [[ $isJessie ]]; then
sudo apt-get -y install libgpg-error-dev
if [[ $isRpi ]]; then
getOldPackage "http://mirrordirector.raspbian.org/raspbian/pool/main/libg/libgcrypt11/libgcrypt11-dev_1.5.0-5+deb7u3_armhf.deb"
elif [[ $isDebian_x86 ]]; then
getOldPackage "http://ftp.debian.org/debian/pool/main/libg/libgcrypt11/libgcrypt11-dev_1.5.0-5+deb7u3_i386.deb"
fi
elif [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then
if [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then # Stretch, Jessie or Wheezy
# Dependencies: build-deps for netatalk 2.2.4
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
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
sudo apt-get -y install $(apt-cache search '^libgcrypt.*dev$' | sort -r | head -1 | cut -d ' ' -f 1)
fi
sudo apt-get clean
# get Netatalk
@@ -148,8 +218,14 @@ else
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
if [[ $useExternalURL ]]; then
wget -qO netatalk-2.2.4.tar.gz "http://downloads.sourceforge.net/project/netatalk/netatalk/2.2.4/netatalk-2.2.4.tar.gz"
tar zxf netatalk-2.2.4.tar.gz &> /dev/null
fi
if [[ ! -d netatalk-2.2.4 ]]; then
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
fi
cd netatalk-2.2.4
# Patch the source so file dates are preserved during a GS/OS folder copy,
@@ -158,10 +234,10 @@ else
# 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
@@ -172,7 +248,41 @@ else
# to remove the Netatalk source code (optional), type:
cd
rm -rf /tmp/netatalk
fi
fi
fi
# --- Install MacIPgw
if ! hash macipgw &> /dev/null; then
echo "A2SERVER: Installing TCP over AppleTalk (MacIP)..."
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${binaryURL}precompiled/macipgw-${arch}.tgz" | sudo tar Pzx; } 2> /dev/null
fi
if ! hash macipgw &> /dev/null; then
wd="$PWD"
sudo apt-get -y install build-essential
rm -rf /tmp/macipgw &> /dev/null
mkdir /tmp/macipgw
cd /tmp/macipgw
if [[ $useExternalURL ]]; then
wget -qO macipgw.zip "https://github.com/zero2sixd/macipgw/archive/2a5f6a7521a627e46b18468d44f4306fb0a7b7ab.zip"
unzip macipgw.zip 2> /dev/null
rm macipgw.zip &> /dev/null
fi
if [ ! -d macipgw* ]; then
wget -qO macipgw.zip "${binaryURL}external/source/macipgw.zip"
unzip macipgw.zip 2> /dev/null
rm macipgw.zip &> /dev/null
fi
cd macipgw*
make
sudo make install
cd "$wd"
rm -rf /tmp/macipgw
fi
else
echo "A2SERVER: TCP over AppleTalk (MacIP) has already been installed."
fi
# --- Configuring Netatalk
@@ -182,7 +292,7 @@ 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 http://appleii.ivanx.com/a2server/files/netatalk-init.d-clean.txt
sudo wget -qO /etc/init.d/netatalk ${binaryURL}netatalk-init.d-clean.txt
fi
# make the Netatalk startup script work correctly
@@ -192,7 +302,16 @@ sudo sed -i 's/bin\/sh/bin\/bash/' /etc/init.d/netatalk
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
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
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
if ! grep -q -i 'macipgw' /etc/init.d/netatalk; then
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
fi
# enable network boot support in netatalk
@@ -231,12 +350,12 @@ sudo sed -i 's/^~/#share1\n\n#share2/' \
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
# 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
# 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
echo -e 'eth0 -router -phase 2 -net 1 -zone "A2SERVER"' | sudo tee -a /usr/local/etc/netatalk/atalkd.conf > /dev/null
fi
# Raspberry Pi
@@ -255,8 +374,8 @@ fi
# /usr/local/etc/netatalk/AppleVolumes.default
# 1.3.0: if GSFILES is being shared, make directory if not there
if grep -q '^/media/A2SHARED/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then
[[ -d /media/A2SHARED/GSFILES ]] || mkdir -p /media/A2SHARED/GSFILES;
if grep -q '^/srv/A2SERVER/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then
[[ -d /srv/A2SERVER/GSFILES ]] || mkdir -p /srv/A2SERVER/GSFILES;
fi
# prior to 1.3.0:
@@ -268,19 +387,22 @@ fi
# see if shared already uses ciopfs (case-insensitive file system), and convert if not
# restore known GS/OS file paths to mixed case
# set up ciopfs (case insensitive file system) for share
if [[ -d /media/A2SHARED/A2FILES && ! -d /media/A2SHARED/.a2files ]]; then
if [[ -d /srv/A2SERVER/A2FILES && ! -d /srv/A2SERVER/.a2files ]]; then
echo "A2SERVER: Converting A2FILES to support mixed case..."
sudo /etc/init.d/netatalk stop &> /dev/null
if ! command -v getfattr &> /dev/null; then
sudo /etc/init.d/samba stop &> /dev/null
if ! hash getfattr &> /dev/null; then
# Dependency: for ciopfs conversion (setfattr)
sudo apt-get -y install attr &> /dev/null
sudo apt-get clean
fi
rm /media/A2SHARED/A2FILES/.APPLEDESKTOP 2> /dev/null
rm /srv/A2SERVER/A2FILES/.APPLEDESKTOP 2> /dev/null
mkdir -p /tmp/netboot
a2FilesList="$(wget -qO- http://ivanx.com/a2server/files/A2FILES-list.txt)"
find /media/A2SHARED/A2FILES -name '*' | tail -n +2 | tac | while read -d $'\n' thisFile; do
wget -qO /tmp/A2FILES-list.txt ${binaryURL}A2FILES-list.txt
find /srv/A2SERVER/A2FILES -name '*' | tail -n +2 | tac > /tmp/filelist.txt
while read thisFile; do
mixedCase="${thisFile##*/}"
gsosPath=$(grep -i "^${thisFile}$" <<< "$a2FilesList")
gsosPath=$(grep -i -m 1 "^${thisFile}$" /tmp/A2FILES-list.txt)
[[ $gsosPath ]] && mixedCase="${gsosPath##*/}"
sudo setfattr -n "user.filename" -v "$mixedCase" "$thisFile"
if [[ ${thisFile##*/} != $mixedCase ]]; then
@@ -288,24 +410,26 @@ if [[ -d /media/A2SHARED/A2FILES && ! -d /media/A2SHARED/.a2files ]]; then
else
echo -e " processing $thisFile\n"
fi
sudo mv "$thisFile" "${thisFile%/*}"/"$(tr [:upper:] [:lower:] <<< $mixedCase)" 2> /dev/null
done
mv /media/A2SHARED/A2FILES /media/A2SHARED/.a2files
mkdir /media/A2SHARED/A2FILES
sudo sed -i 's/casefold:toupper //' /usr/local/etc/netatalk/AppleVolumes.default
sudo sed -i 's/^VOLCASEFOLD:.*/VOLCASEFOLD:/' /media/A2SHARED/.a2files/.appledesktop/.volinfo
sudo mv "$thisFile" "${thisFile%/*}/${mixedCase,,}" 2> /dev/null
done < /tmp/filelist.txt
mv /srv/A2SERVER/A2FILES /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/^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
# 1.3.0: remove GSFILES if empty
if grep -q '^/media/A2SHARED/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then
if grep -q '^/srv/A2SERVER/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then
gsFilesContents=
if [[ -d /media/A2SHARED/GSFILES ]]; then
gsFilesContents="$(find /media/A2SHARED/GSFILES -not -path '*/\.*' | grep -v '^/media/A2SHARED/GSFILES$' | grep -v '^/media/A2SHARED/GSFILES/Network Trash Folder$' | grep -v '^/media/A2SHARED/GSFILES/Temporary Items$')"
if [[ -d /srv/A2SERVER/GSFILES ]]; then
gsFilesContents="$(find /srv/A2SERVER/GSFILES -not -path '*/\.*' | grep -v '^/srv/A2SERVER/GSFILES$' | grep -v '^/srv/A2SERVER/GSFILES/Network Trash Folder$' | grep -v '^/srv/A2SERVER/GSFILES/Temporary Items$')"
if [[ ! $gsFilesContents ]]; then
echo "A2SERVER: Removing empty GSFILES shared volume..."
sudo /etc/init.d/netatalk stop &> /dev/null
sudo sed -i 's|^/media/A2SHARED/GSFILES.*$|#share1|' /usr/local/etc/netatalk/AppleVolumes.default
sudo rm -r /media/A2SHARED/GSFILES
sudo /etc/init.d/samba stop &> /dev/null
sudo sed -i 's|^/srv/A2SERVER/GSFILES.*$|#share1|' /usr/local/etc/netatalk/AppleVolumes.default
sudo rm -r /srv/A2SERVER/GSFILES
else
echo "A2SERVER: GSFILES shared volume has files, leaving as is."
fi
@@ -314,20 +438,20 @@ fi
# set up A2FILES case-insensitive share (for ProDOS 8 files, and GS/OS system)
sudo sed -i \
's/^#share2/\/media\/A2SHARED\/A2FILES\ A2FILES options:prodos\ ea:ad/' \
/usr/local/etc/netatalk/AppleVolumes.default
[[ -d /media/A2SHARED/A2FILES ]] || mkdir -p /media/A2SHARED/A2FILES
[[ -d /media/A2SHARED/.a2files ]] || mkdir -p /media/A2SHARED/.a2files
's/^#share2/\/srv\/A2SERVER\/A2FILES\ A2FILES options:prodos\ ea:ad/' \
/usr/local/etc/netatalk/AppleVolumes.default
[[ -d /srv/A2SERVER/A2FILES ]] || mkdir -p /srv/A2SERVER/A2FILES
[[ -d /srv/A2SERVER/.a2files ]] || mkdir -p /srv/A2SERVER/.a2files
# set up ciopfs
if ! command -v ciopfs > /dev/null; then
if ! hash ciopfs &> /dev/null; then
echo "A2SERVER: Installing ciopfs (case insensitive file system)..."
cd /tmp
# Dependency: For ciopfs
sudo apt-get -y install fuse libglib2.0-0 libattr1 libfuse2
if [[ $isRpi ]]; then
wget -qO- "http://appleii.ivanx.com/a2server/files/ciopfs-rpi.tgz" | sudo tar Pzx
elif [[ $isDebian_x86 ]]; then
wget -qO- "http://appleii.ivanx.com/a2server/files/ciopfs-debian7_x86.tgz" | sudo tar Pzx
if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then
{ wget -qO- "${binaryURL}precompiled/ciopfs-${arch}.tgz" | sudo tar Pzx; } &> /dev/null
fi
if [[ -f /etc/fuse.conf ]] && sudo grep -q user_allow_other /etc/fuse.conf; then
sudo sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
@@ -335,21 +459,34 @@ if ! command -v ciopfs > /dev/null; then
echo "user_allow_other" | sudo tee /etc/fuse.conf > /dev/null
fi
if ! command -v ciopfs > /dev/null; then
if ! hash ciopfs &> /dev/null; 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 libfuse-dev libglib2.0-dev libattr1-dev
# Dependency: build-dep for ciopfs
sudo apt-get -y install build-essential libfuse-dev libglib2.0-dev libattr1-dev
sudo apt-get -y clean
cd /tmp
rm -rf /tmp/ciopfs &> /dev/null
mkdir /tmp/ciopfs
cd /tmp/ciopfs
wget -q -O ciopfs-0.4.tar.gz http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz
tar zxf ciopfs-0.4.tar.gz
if [[ $useExternalURL ]]; then
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
rm ciopfs-0.4.tar.gz &> /dev/null
fi
if [ ! -f ciopfs*/ciopfs.c ]; then # single brackets required for glob
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
rm ciopfs-0.4.tar.gz &> ?dev/null
fi
cd ciopfs*
make
sudo mv ciopfs /usr/local/bin
@@ -357,34 +494,36 @@ if ! command -v ciopfs > /dev/null; then
rm -rf /tmp/ciopfs
fi
if ! grep -q '^ciopfs' /etc/fstab; then
echo "ciopfs#/media/A2SHARED/.a2files /media/A2SHARED/A2FILES fuse allow_other 0 0" | sudo tee -a /etc/fstab > /dev/null
echo "ciopfs#/srv/A2SERVER/.a2files /srv/A2SERVER/A2FILES fuse allow_other 0 0" | sudo tee -a /etc/fstab > /dev/null
fi
if ! mount | grep '^ciopfs.*A2FILES'; then
sudo ciopfs /media/A2SHARED/.a2files /media/A2SHARED/A2FILES -o allow_other
sudo ciopfs /srv/A2SERVER/.a2files /srv/A2SERVER/A2FILES -o allow_other
fi
else
echo "A2SERVER: ciopfs (case insensitive file system) has already been installed."
fi
if [[ ! -d /media/A2SHARED/A2FILES/.AppleDesktop ]]; then
cd /media/A2SHARED/A2FILES
if [[ ! -d /srv/A2SERVER/A2FILES/.AppleDesktop ]]; then
cd /srv/A2SERVER/A2FILES
mkdir .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 /media/A2SHARED/ADTDISKS ]]; then
ln -s /usr/local/adtpro/disks /media/A2SHARED/ADTDISKS
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@/media/A2SHARED/ADTDISKS ADTDISKS ea:ad\n\n# End of File@' /usr/local/etc/netatalk/AppleVolumes.default
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
# prepare shared volumes for use
afpsync -v < /dev/null
# --- Setting up users
@@ -398,17 +537,14 @@ if [[ -f /usr/local/etc/netatalk/afppasswd ]]; then
else
echo
echo "A2SERVER: Setting up AFP password 'apple2' for Apple II and Mac clients."
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/^\(${USER}\).*$/\1: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.)
# the afppasswd -a to make Netatalk randnum logins for other Linux users.)
fi
@@ -416,24 +552,25 @@ fi
# 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/')
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/')
kernelMajorMinor=$(cut -d '.' -f 1-2 <<< $kernelRelease)
# 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 [[ $kernelMajor -eq 3 && $kernelMinor -ge 12 && $kernelMinor -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 [[ ! ( $isRpi && $kernelMinor -eq 12 && $kernelPatch -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."
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."
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
@@ -442,6 +579,102 @@ if [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRel
fi
fi
# if IPDDP module exists (e.g. Debian, but not Raspbian),
# AppleTalk kernel module has been compiled to support it and can't work with MacIP
if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]]; then
sudo /etc/init.d/netatalk stop &> /dev/null
sudo rmmod ipddp 2> /dev/null
sudo rmmod appletalk 2> /dev/null
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
if [[ ! $compileFromSource && ${arch%_*} == "debian" ]]; then
echo "A2SERVER: Fetching AppleTalk kernel module for Debian..."
wget -qO /tmp/appletalk.tgz ${binaryURL}precompiled/appletalk-$kernelRelease-${arch}.tgz
if [[ $? -eq 0 ]]; then
# if we found a prebuilt one on a2server site, install it and load it
sudo tar Pxf /tmp/appletalk.tgz &> /dev/null
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 &> /dev/null
else
echo "A2SERVER: failed to load AppleTalk kernel module"
# if we didn't load it successfully, remove it
sudo rm /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko 2> /dev/null
fi
else # download failed, so premade kernel not found, remove empty file
rm /tmp/appletalk.tgz 2>/dev/null
fi
fi
if ! lsmod | grep -q appletalk; then
# we don't have a prebuilt AppleTalk module, try to build from source
if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then
# prepare for installing packages
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
# kernel module compile adapted from from: http://askubuntu.com/a/338403/288003
for i in 1; do
echo "A2SERVER: Building AppleTalk kernel module..."
[[ -f /boot/config-$kernelRelease ]] || 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 libelf-dev # required as of kernel 4.14.12, apparently
cd /usr/src
kernelSrc=$(find linux-source-${kernelMajorMinor}*)
if [[ ${kernelSrc##*.} == "xz" ]]; then
{ xzcat $kernelSrc | sudo tar x; } &> /dev/null
elif [[ ${kernelSrc##*.} == "bz2" ]]; then
sudo tar jxf $kernelSrc &> /dev/null
elif [[ ${kernelSrc##*.} == "gz" || ${kernelSrc##*.} == "tgz" ]]; then
sudo tar zxf $kernelSrc &> /dev/null
fi
cd linux-source-$kernelMajorMinor
sudo make mrproper
sudo cp ../linux-headers-$kernelRelease/Module.symvers .
yes '' | sudo make oldconfig
sudo sed -i 's:^.*IPDDP.*$:# CONFIG_IPDDP is not set:gI' .config # disable IPDDP in kernel config
sudo sed -i '$!N; /^\(# CONFIG_IPDDP is not set\)\n\1$/!P; D' .config # delete repeated entries
sudo make prepare
sudo make modules_prepare
sudo make SUBDIRS=scripts/mod
sudo make SUBDIRS=net/appletalk modules
sudo cp net/appletalk/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk
sudo depmod
sudo modprobe appletalk
sudo rm -r /lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko
sudo rmdir /lib/modules/$kernelRelease/kernel/drivers/net/appletalk 2> /dev/null
# clean up
cd
sudo rm /usr/src/$kernelSrc
sudo rm -r /usr/src/linux-source-$kernelMajorMinor
sudo apt-get -y purge linux-source-$kernelMajorMinor
sudo apt -y autoremove
done
fi
if [[ $(lsmod | grep appletalk) ]]; then
# if it loaded, make permanent and restart netatalk
sudo rm /lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko 2> /dev/null
sudo sed -i 's:^.*IPDDP.*$:# CONFIG_IPDDP is not set:gI' /boot/config-$kernelRelease
sudo sed -i '$!N; /^\(# CONFIG_IPDDP is not set\)\n\1$/!P; D' /boot/config-$kernelRelease
sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk; sudo /etc/init.d/netatalk restart &> /dev/null
else
# if we didn't load it successfully, put back the one that was there
echo "A2SERVER: Unable to replace AppleTalk module, replacing original."
sudo mv /tmp/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk 2> /dev/null
sudo depmod
touch /tmp/noMacIP # to notify at end of install
fi
fi
# --- Start Netatalk (if not running)
bground=
@@ -474,11 +707,11 @@ if [[ ( ! $(ps aux | grep [a]talkd) ) && ( $isRpi ) ]]; then
# 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 http://appleii.ivanx.com/a2server/files/appletalk-$kernelRelease.ko.gz
echo "A2SERVER: Installing AppleTalk kernel module for Raspbian..."
wget -qO /tmp/appletalk.ko.gz ${binaryURL}appletalk-$kernelRelease-rpi.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
gunzip -f /tmp/appletalk.ko.gz &> /dev/null
sudo mkdir -p /lib/modules/$kernelRelease/kernel/net/appletalk
sudo mv /tmp/appletalk.ko /lib/modules/$kernelRelease/kernel/net/appletalk
sudo depmod
@@ -539,7 +772,10 @@ if [[ ! $(dpkg -l avahi-daemon 2> /dev/null | grep ^ii) || ! $(dpkg -l libnss-md
sudo apt-get -y update
touch /tmp/a2server-packageReposUpdated
fi
# Dependency: Bonjour for netatalk
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

File diff suppressed because it is too large Load Diff

View File

@@ -28,8 +28,10 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then
touch /tmp/a2server-packageReposUpdated
fi
# Dependency: samba for Windows/modern Macs
# FIXME: Figure out when smbpasswd moved and adjust this as necessary
sudo apt-get -y install samba
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
fi
@@ -46,13 +48,19 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then
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 \
# remove GSFILES if no longer serving it
if ! grep ^/srv/A2SERVER/GSFILES /usr/local/etc/netatalk/AppleVolumes.default; then
sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*\[#\n[#' /etc/samba/smb.conf
sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*$#\n#' /etc/samba/smb.conf
fi
grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | cut -d" " -f2 \
| while read sharename; do
if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then
echo "A2SERVER: $sharename is already set up for Windows file sharing."
else
echo "[$sharename]" | sudo tee -a /etc/samba/smb.conf > /dev/null
echo " path = /media/A2SHARED/$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

View File

@@ -14,7 +14,7 @@ password="your password"
[[ $isRaspberryPw ]] && password="'raspberry'"
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 { lspci 2> /dev/null | grep -q VirtualBox; }; then

180
scripts/clock.patch.py Executable file
View 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:])

233
scripts/raspbian-update.txt Normal file
View File

@@ -0,0 +1,233 @@
#!/bin/bash
# raspbian-update
# updates Raspbian to latest version, including NOOBS if installed
[[ -f /usr/bin/raspi-config ]] && isRpi=1 || isRpi=
if [[ ! $isRpi ]]; then
echo "This ain't a Raspberry Pi."
[[ $0 == "-bash" ]] && return 1 || exit 1
fi
skipRepoUpdate=
autoYes=
updateA2Cloud=
updateA2Server=
while [[ $1 ]]; do
if [[ $1 == "-r" ]]; then
shift
skipRepoUpdate="-r"
elif [[ $1 == "-y" ]]; then
shift
autoYes="-y"
elif [[ $1 == "-n" ]]; then
shift
noobsOnly="-n"
elif [[ $1 == "a2cloud" ]]; then
shift
updateA2Cloud=1
elif [[ $1 == "a2server" ]]; then
shift
updateA2Server=1
elif [[ $1 ]]; then
echo "options:"
echo "-y: auto-answer yes to all prompts and don't prompt for restart"
echo "-r: don't update package repositories"
echo "-n: update NOOBS only; don't update Raspbian"
echo "a2cloud : update A2CLOUD when complete"
echo "a2server: update A2SERVER when complete"
[[ $0 == "-bash" ]] && return 1 || exit 1
fi
done
noobs=
readarray -t partitions < <(sudo fdisk -l | grep '^/dev')
if [[ \
${partitions[0]:0:14} == "/dev/mmcblk0p1" && ${partitions[0]:57:2} == " e" &&
${partitions[1]:0:14} == "/dev/mmcblk0p2" && ${partitions[1]:57:2} == "85" &&
${partitions[2]:0:14} == "/dev/mmcblk0p3" && ${partitions[2]:57:2} == "83" &&
${partitions[3]:0:14} == "/dev/mmcblk0p5" && ${partitions[3]:57:2} == " c" &&
${partitions[4]:0:14} == "/dev/mmcblk0p6" && ${partitions[4]:57:2} == "83" ]]; then
noobs=" and the NOOBS install manager"
fi
if [[ ! $autoYes ]]; then
echo
echo "You are about to update your SD card to the latest version of the"
echo "Raspbian operating system${noobs}."
echo
echo "This may take an hour or more, and will require restarting when complete."
echo "You might want a backup before continuing in case it doesn't go as planned."
echo
echo -n "Update Raspbian? "
read
if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then
[[ $0 == "-bash" ]] && return 2 || exit 2
fi
fi
origDir="$PWD"
cd /tmp
if [[ ! $skipRepoUpdate ]]; then
echo "Updating package repositories..."
sudo apt-get -y update > /dev/null
else
echo "Not updating package repositories..."
echo
fi
if [[ ! $noobsOnly ]]; then
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
freeSpace=$(df / | tail -1 | awk '{ print $4 }')
if (( $freeSpace < 400000 )); then
if dpkg -l | grep -q wolfram-engine; then
if [[ ! $autoYes ]]; then
echo "In order to create enough space on your SD card to upgrade,"
echo "the Wolfram Language and Mathematica software packages must be removed."
echo "If you don't know what these are, this won't affect you at all."
echo
echo -n "Remove Wolfram software? "
read
if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then
[[ $0 == "-bash" ]] && return 2 || exit 2
fi
sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null
sudo apt-get -y purge wolfram-engine
else
echo "Removing Wolfram software due to space constraints..."
sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null
sudo apt-get -y purge wolfram-engine
fi
else
echo "You don't have enough free space on your SD card to upgrade."
echo "Sorry, man. Delete some stuff or get a bigger card."
[[ $0 == "-bash" ]] && return 1 || exit 1
fi
fi
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
dpkg -l | grep -q a2pi && sudo apt-get -y --force-yes install a2pi
dpkg -l | grep -q apple2user && sudo apt-get -y --force-yes install apple2user gsport
if dpkg -l | grep -q wolfram-engine; then
sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null
if [[ $freeSpace -lt 750000 && $(apt-get -s install wolfram-engine | grep upgraded) ]]; then
sudo apt-get -y purge wolfram-engine
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
fi
sudo apt-get -y install wolfram-engine
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
fi
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
sudo apt-get -y install raspberrypi-ui-mods
{ cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null
fi
if [[ $noobs ]]; then
echo "Updating NOOBS..."
# update Partition 3
mkdir -p /tmp/p3
sudo mount /dev/mmcblk0p3 /tmp/p3
sudo rm -rf /tmp/p3/os/* 2> /dev/null
if grep -q 'Raspple II' /tmp/p3/installed_os.json; then
echo "Downloading Raspple II lite..."
noobsUrl="ivanx.com/rasppleii/files/RasppleII_lite.zip"
noobsOSurl="ivanx.com/rasppleii/noobs-os"
distDir="Raspple_II"
sudo mkdir -p /tmp/p3/os/$distDir
sudo sed -i 's:/Raspbian:/Raspple_II:' /tmp/p3/installed_os.json
sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspple_II.png
{ wget -qO- $noobsOSurl/slidesAB.tar | sudo tar -C /tmp/p3/os/$distDir -x; } &> /dev/null
else
echo "Downloading NOOBS lite..."
noobsRoot="downloads.raspberrypi.org/NOOBS_lite/images/"
noobsDir=$(wget -qO- $noobsRoot | grep '^<tr><td' | tail -1 | grep -P -o 'href=".*?"' | cut -c 6- | tr -d '"')
noobsUrl=$noobsRoot$noobsDir$(wget -qO- $noobsRoot$noobsDir | grep -P -o 'href=".*.zip"' | cut -c 6- | tr -d '"')
noobsOSurl="downloads.raspberrypi.org/raspbian"
distDir="Raspbian"
sudo mkdir -p /tmp/p3/os/$distDir
sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspbian.png
{ wget -qO- $noobsOSurl/marketing.tar | sudo tar -C /tmp/p3/os/$distDir -x; } &> /dev/null
fi
sudo rm -rf /tmp/p3/cache 2> /dev/null
releaseDate=$(wget -qO- $noobsOSurl/os.json | grep 'release_date' | cut -f 4 -d '"')
sudo sed -i 's/"release_date".*$/"release_date" : "'$releaseDate'"/' /tmp/p3/installed_os.json
sudo sed -i 's/keyboard_layout=gb/keyboard_layout=us/' /tmp/p3/noobs.conf
sudo sed -i 's:/mnt/:/settings/:' /tmp/p3/installed_os.json
sudo sed -i 's@"icon".*,@"icon" : "/settings/os/'$distDir'/icon.png",@' /tmp/p3/installed_os.json
sudo cp /tmp/p3/icon.png /tmp/p3/os/$distDir
sudo wget -qO /tmp/p3/os/$distDir/os.json $noobsOSurl/os.json
sudo wget -qO /tmp/p3/os/$distDir/partition_setup.sh $noobsOSurl/partition_setup.sh
sudo wget -qO /tmp/p3/os/$distDir/partitions.json $noobsOSurl/partitions.json
sudo umount /tmp/p3
rmdir /tmp/p3
# update Partition 1
mkdir -p /tmp/p1
sudo mount /dev/mmcblk0p1 /tmp/p1
wget -qO /tmp/noobs_lite.zip $noobsUrl
sudo rm -rf /tmp/p1/*
sudo unzip -d /tmp/p1 /tmp/noobs_lite.zip
sudo sed -i 's/^runinstaller //' /tmp/p1/recovery.cmdline
sudo sed -i 's/silentinstall//' /tmp/p1/recovery.cmdline
grep -q 'keyboard=us' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 keyboard=us/' /tmp/p1/recovery.cmdline
grep -q 'disablesafemode' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 disablesafemode/' /tmp/p1/recovery.cmdline
sudo umount /tmp/p1
rmdir /tmp/p1
sudo sed -i 's/\(Raspple II release.*[^u]$\)/\1u/' /etc/issue
fi
echo
echo "*** Raspbian update completed. ***"
echo
cd /tmp
if [[ $updateA2Cloud ]]; then
wget -qO /tmp/a2cloud-setup ivanx.com/a2cloud/setup/
source /tmp/a2cloud-setup -y -r noSetGroups
if acmd -g /usr/share/gsport/disks/GSport\ Internet\ Starter\ Kit.2mg SYSTEM/FONTS/SIS.4.10 &> /dev/null; then
wget -qO /tmp/ua2.txt ivanx.com/rasppleii/files/a/ua2.txt
source /tmp/ua2.txt
fi
echo
echo "*** A2CLOUD update completed. ***"
echo
fi
cd /tmp
if [[ $updateA2Server ]]; then
wget -q -O /tmp/a2server-setup ivanx.com/a2server/setup/
if ps aux | grep -q [s]mbd; then
source /tmp/a2server-setup -y -r -w
else
source /tmp/a2server-setup -y -r
fi
echo
echo "*** A2SERVER update completed. ***"
echo
fi
cd "$origDir"
if [[ ! $autoYes ]]; then
echo
echo
echo "Your system has been updated and needs to reboot to use its new software."
echo
echo -n "Reboot now (recommended)? "
read
if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
sudo shutdown -r now
fi
else
echo "*** raspbian-update completed. ***"
sudo shutdown -r now
fi

View File

@@ -2,17 +2,17 @@
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
alias a2server-help="more /usr/local/etc/a2server-help.txt"
alias a2server-setup="wget -q -O /tmp/a2server-setup ${A2SERVER_SCRIPT_URL:-http://appleii.ivanx.com/a2server}$([[ "$A2SERVER_SCRIPT_URL" == */ ]] || echo -n "/")setup/ || { 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-update="wget -q -O /tmp/a2server-update ${A2SERVER_SCRIPT_URL:-http://appleii.ivanx.com/a2server}$([[ "$A2SERVER_SCRIPT_URL" == */ ]] || echo -n "/")update/ || { 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-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 raspbian-update='wget -qO /tmp/raspbian-update ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}scripts/raspbian-update.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/raspbian-update'
alias rasppleii-update='raspbian-update a2cloud a2server'
alias welcome-message-edit='sudo nano /etc/motd'
@@ -24,8 +24,8 @@ 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-start="sudo /etc/init.d/netatalk start; bonjour-on; grep -q 'ATALKD_RUN=yes' /etc/default/netatalk"
alias netatalk-restart="sudo /etc/init.d/netatalk restart; bonjour-on; grep -q 'ATALKD_RUN=yes' /etc/default/netatalk"
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'
@@ -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 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-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/^\([^#].*\) -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'
@@ -47,8 +47,8 @@ alias appletalk-on='sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/n
NETATALK="/usr/local/etc/netatalk"
A2FILES="/media/A2SHARED/A2FILES"
GSFILES="/media/A2SHARED/GSFILES"
A2FILES="/srv/A2SERVER/A2FILES"
GSFILES="/srv/A2SERVER/GSFILES"
alias netboot-gsos="mkatinit -gs -d -f"
alias netboot-gsos-guest="mkatinit -gs -d -f guest"
@@ -69,8 +69,8 @@ alias samba-stop='sudo /etc/init.d/samba stop'
alias samba-start='sudo /etc/init.d/samba start'
alias samba-restart='sudo /etc/init.d/samba restart'
alias a2files-share="sudo sed -i 's/^#share2/\/media\/A2SHARED\/A2FILES\ A2FILES options:prodos ea:ad/' /usr/local/etc/netatalk/AppleVolumes.default; [[ -d /media/A2SHARED/A2FILES ]] || mkdir /media/A2SHARED/A2FILES"
alias a2files-unshare="sudo sed -i 's/^\/media\/A2SHARED\/A2FILES.*$/#share2/' /usr/local/etc/netatalk/AppleVolumes.default"
alias a2files-share="sudo sed -i 's/^#share2/\/srv\/A2SERVER\/A2FILES\ A2FILES options:prodos ea:ad/' /usr/local/etc/netatalk/AppleVolumes.default; [[ -d /srv/A2SERVER/A2FILES ]] || mkdir /srv/A2SERVER/A2FILES"
alias a2files-unshare="sudo sed -i 's/^\/srv\/A2SERVER\/A2FILES.*$/#share2/' /usr/local/etc/netatalk/AppleVolumes.default"
alias showalias="alias | cut -d= -f 1 | cut -d' ' -f2 | more"

6
scripts/tools/a2serverrc.txt Executable file
View File

@@ -0,0 +1,6 @@
#! /bin/bash
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
export A2SERVER_SCRIPT_URL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}"
export A2SERVER_BINARY_URL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files/}"
source /usr/local/etc/a2server-aliases

View File

@@ -11,7 +11,7 @@
#
# -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
# all paths in /srv/A2SERVER which appear in
# /usr/local/etc/netatalk/AppleVolumes.default are synced.
processPath () {
@@ -43,7 +43,6 @@ processPath () {
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
@@ -63,7 +62,6 @@ processPath () {
$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
@@ -108,7 +106,7 @@ else
# (as opposed to defaulting to casefold:toupper previously)
processPath 1
else
grep ^/media /usr/local/etc/netatalk/AppleVolumes.default | \
grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \
while read line; do
[[ $(echo $line | grep toupper) ]]; nocasefold=$?
sharepath=$(echo $line | cut -d" " -f1)

View File

@@ -158,7 +158,7 @@ readchars () {
&& ( $3 -ge 0 ) ]] || return 23; }
# args are valid
dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \
2> /dev/null
2> /dev/null | tr -d ' \0'
}
readcharDec () {
@@ -175,7 +175,7 @@ readcharDec () {
&& ( $2 -ge 0 ) ]] || return 22; }
# args are valid
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; }
echo -n "${charX:0:1}" | od -t u1 | \
head -1 | sed 's/[0\ ]*//' | tr -d ' \n'
@@ -195,7 +195,7 @@ readcharHex () {
&& ( $2 -ge 0 ) ]] || return 22; }
# args are valid
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; }
printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \
head -1 | sed 's/[0\ ]*//' | tr -d ' \n')

File diff suppressed because it is too large Load Diff

View File

@@ -49,7 +49,7 @@ else
if [[ $1 ]]; then
sharepath=$(readlink -m $1)
else
sharepath=$(grep ^/media /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1)
sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1)
fi
volinfo=$sharepath/.AppleDesktop/.volinfo

File diff suppressed because one or more lines are too long

View File

@@ -1,44 +1,61 @@
#! /bin/bash
# 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
# netatalk configured for Apple II use on Debian or Raspbian.
# more info is at http://appleii.ivanx.com/a2server
# more info is at http://ivanx.com/a2server
# to download and execute, type:
# wget appleii.ivanx.com/a2server/setup; source setup
# wget ivanx.com/a2server/setup; source setup
a2serverVersion="127"
a2serverVersion="153"
# Ensure URL we'll use ends in a /
case "$A2SERVER_SCRIPT_URL" in
*/) 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
case "$A2SERVER_BINARY_URL" in
*/) binaryURL="$A2SERVER_BINARY_URL" ;;
*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;;
esac
useExternalURL=1
[[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL=
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
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
echo "A2SERVER version available: $a2serverVersion"
echo "A2SERVER version installed: $(cat /usr/local/etc/A2SERVER-version)"
installedVersion=
if [ -f /usr/local/etc/A2SERVER-version ]; then
installedVersion="$(cat /usr/local/etc/A2SERVER-version)"
fi
echo "A2SERVER version available: $a2serverVersion"
echo "A2SERVER version installed: ${installedVersion:=None}"
echo
[[ $scriptURL != *"ivanx.com"* && $scriptURL != *"raw.githubusercontent.com/RasppleII/a2server"* ]] && echo "Using script URL: $scriptURL"
[[ $binaryURL != *"ivanx.com"* ]] && echo "Using binary URL: $binaryURL"
[[ ! $useExternalURL ]] && echo -e "Not using external URLs. Downloads must be available from:\n ${binaryURL}external/appleii/\n ${binaryURL}external/source/\n (See the A2SERVER developer page for more information.)"
skipRepoUpdate=
autoAnswerYes=
installAll=
setupNetBoot=
setupWindowsSharing=
updateRasppleII=
compileAlways=
rm /tmp/a2server-* 2> /dev/null
while [[ $1 ]]; do
if [[ $1 == "-r" ]]; then
shift
skipRepoUpdate="-r"
touch /tmp/a2server-packageReposUpdated
elif [[ $1 == "-i" ]]; then
shift
installAll="-i"
elif [[ $1 == "-y" ]]; then
shift
autoAnswerYes="-y"
@@ -51,39 +68,28 @@ while [[ $1 ]]; do
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
elif [[ $1 == "-c" ]]; then
shift
updateRasppleII=1
compileAlways="-c"
touch /tmp/a2server-compileAlways
elif [[ $1 == "-v" ]]; then
shift
if [[ ! -f /usr/local/etc/A2SERVER-version ]]; then
echo "A2SERVER version available: $a2serverVersion"
echo "A2SERVER version installed: none"
fi
# Version was already printed
[[ $0 == "-bash" ]] && return 1 || exit 1
elif [[ $1 ]]; then
echo "options:"
echo "-v: display installed and available versions, then exit"
echo "-i: reinstall A2SERVER software (but not Apple II software)"
echo "-y: auto-answer yes to all prompts"
echo "-r: don't update package repositories"
echo "-b: auto-setup network boot (use with -y)"
echo "-w: auto-setup Windows file sharing (use with -y)"
if [[ $isRpi ]]; then
echo "-os: update Raspbian OS, A2CLOUD, A2SERVER, and Apple II Pi"
fi
echo "-c: compile non-package items, rather than downloading binaries"
[[ $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 "http://appleii.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
if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 110 )); }; then
echo
echo "WARNING: The current A2SERVER installer scripts haven't been tested for"
echo "updating the earlier version of A2SERVER that you have. A fresh install"
@@ -94,29 +100,49 @@ fi
a2server_update=0
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
if [[ $isRpi ]]; then #supported Raspbian? (16-Feb-15, 20-Jun-14, 09-Jan-14, etc)
fwhash=$(zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 'as of' | awk '{print $NF}')
fwsupported="-8aca5762- -462f3e3f476f7b6- -c32bc633039cd9- -9d34d0475f9-
-d4f5315cfac4e- -6f4a90c8cb8817f- -5dd9b4962e- -17c8799375-
-960832a6c2590635216c296b6ee0bebf67b21d50-"
[[ "$fwsupported" == *-$fwhash-* ]] && unsupportedOS=0
[[ ($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)" == "7.3" || "$(lsb_release -rs 2> /dev/null)" == "7.6" || "$(lsb_release -rs 2> /dev/null)" == "7.8" ]]; then # tested Debian?
unsupportedOS=0
-960832a6c2590635216c296b6ee0bebf67b21d50-
-2a329e0c7d8ea19c085bac5633aa4fccee0f21be-
-b2420fc150ae4616f5d9ec24bdaedc630586a529-"
[[ "$fwsupported" == *-$fwhash-* ]] && unsupportedOS=
# [[ ($fwhash == "8aca5762") || ($fwhash == "462f3e3f476f7b6") || ($fwhash == "c32bc633039cd9") || ($fwhash == "9d34d0475f9") || ($fwhash == "d4f5315cfac4e") || ($fwhash == "6f4a90c8cb8817f") || ($fwhash == "5dd9b4962e") || ($fwhash == "17c8799375") ]] && unsupportedOS=
elif [[ $isDebian ]]; then # supported Debian?
debianVersion=$(cat /etc/debian_version)
debianSupported="-10.4- -9.2- -8.2- -7.9- -7.8- -7.6- -7.3-"
[[ $debianSupported == *-$debianVersion-* ]] && unsupportedOS=
fi
if (( unsupportedOS )); then
if [[ $unsupportedOS && $isRpi ]]; 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."
echo "A2SERVER and its installer scripts have been tested on Raspbian Buster,"
echo "Stretch, Jessie, and Wheezy, though not this specific firmware version"
echo "(${fwhash:0:7}). Just FYI."
unsupportedOS=
elif [[ $unsupportedOS && $isDebian ]]; then
echo
echo "A2SERVER and its installer scripts have been tested on Debian 7/8/9/10,"
echo "though not this specific point release ($debianVersion). Just FYI."
unsupportedOS=
fi
if [[ $unsupportedOS ]]; then
echo
echo "WARNING: A2SERVER and its installer scripts have only been tested on"
echo "Debian and Raspbian. Continuing is probably fine, but might not be."
echo "Theoretical worst case would be your operating system no longer works"
echo "properly or data is lost, so consider backing up first."
fi
doSetup=1
if [[ ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then
if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then
echo
echo "Setting up A2SERVER will take up to 60 minutes, during which"
echo "you'll see a bunch of stuff spit out across the screen."
@@ -132,7 +158,7 @@ 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 "For details, visit http://ivanx.com/a2server."
echo
if [[ ! $autoAnswerYes ]]; then
echo -n "Continue? "
@@ -142,34 +168,38 @@ if (( $doSetup )); then
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
checkPw=1
while [[ $checkPw ]] ; do
userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':')
[[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw=
[[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw=
password="your password"
[[ $isApple2Pw ]] && password="apple2"
[[ $isRaspberryPw ]] && password="raspberry"
checkPw=
[[ $isRpi ]] && a2server="your Raspberry Pi" || a2server="A2SERVER"
if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2SERVER-version ]]; then
if [[ ! $autoAnswerYes ]]; then
echo
echo "To ensure that all client computers are able to connect to"
echo "${a2server} using the same password, you probably want"
echo "to change your user password to 'apple2'."
echo
echo -n "Do you want to change the password for user '$USER' to 'apple2' now? "
read
fi
if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then
echo "A2SERVER: changing password for user '$USER' to 'apple2'..."
echo "$USER:apple2" | sudo chpasswd
checkPw=1
fi
fi
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
done
echo
echo "During this installation, enter ${password} if prompted for passwords."
echo "During this installation, enter '${password}' if prompted for passwords."
echo
sudo true
@@ -197,6 +227,16 @@ if (( $doSetup )); then
echo "A2SERVER: Scripts have been downloaded. Installing..."
if [[ $installAll ]]; then
sudo rm /usr/local/etc/A2SERVER-version 2> /dev/null
sudo rm /usr/local/bin/nulib2 2> /dev/null
sudo rm /usr/local/bin/unar 2> /dev/null
sudo rm /usr/local/sbin/macipgw 2> /dev/null
sudo rm /usr/local/bin/ciopfs 2> /dev/null
sudo rm /usr/local/etc/netatalk/afppasswd 2> /dev/null
sudo rm /usr/local/etc/netatalk/a2boot/p8 /usr/local/etc/netatalk/a2boot/ProDOS16\ Image 2> /dev/null
fi
/tmp/1.storage
rm /tmp/1.storage
/tmp/2.tools
@@ -212,11 +252,11 @@ if (( $doSetup )); then
rm /tmp/a2server-packageReposUpdated &> /dev/null
if [[ ! -f /usr/local/etc/A2SERVER-version ]] \
|| (( $(cat /usr/local/etc/A2SERVER-version) < "$a2serverVersion" )); then
|| (( $(head -c 3 /usr/local/etc/A2SERVER-version) < ${a2serverVersion:0:3} )); then
echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null
fi
source /usr/local/etc/a2server-aliases
source /usr/local/etc/a2serverrc
# get Kernel release (e.g. 3.6.11+) and version (e.g. #557)
kernelRelease=$(uname -r)
@@ -230,7 +270,20 @@ if (( $doSetup )); then
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
if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then
echo
echo "You can network boot GS/OS."
echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)"
echo "to Your Card, and slot 7 to AppleTalk, and Startup Slot to 7 or Scan."
echo "On a ROM 3 IIgs, set slot 1 or 2, and Startup Slot, to AppleTalk."
fi
if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then
echo
echo "You can network boot ProDOS 8. On an Apple IIe, put your Workstation Card"
echo "in a slot above your disk controller card, or type PR#X with open-apple"
echo "held down, with X being the slot of your Workstation Card."
echo 'On a IIgs, press "8" during the initial procession of periods.'
fi
echo
echo "A2SERVER setup is complete! Go connect from your Apple II!"
echo
@@ -266,9 +319,18 @@ if (( $doSetup )); then
echo "by typing 'appletalk-on'."
echo
fi
if [[ -f /tmp/noMacIP ]]; then
echo
echo "MacIP connections may be unavailable. If you know how, try"
echo "recompiling the AppleTalk kernel module with IPDDP options disabled."
echo
rm /tmp/noMacIP
fi
if [[ -f /tmp/singleUser ]]; then
if [[ ! $autoAnswerYes ]]; then
echo
echo "Your Raspberry Pi was started in single-user mode in order to"
echo -n "fix a problem. You should restart to operate normally. Restart now? "
read
@@ -279,6 +341,7 @@ if (( $doSetup )); then
echo "A2SERVER: Preparing to restart..."
while :; do sleep 60; done
fi
rm /tmp/singleUser
echo
fi
@@ -291,8 +354,5 @@ 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 /tmp/a2server-* 2> /dev/null
rm setup &> /dev/null

120
update/devhistory.txt Normal file
View 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

View File

@@ -1,7 +1,13 @@
#! /bin/bash
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
currentVersion=127
# Ensure URL we'll use ends in a /
case "$A2SERVER_SCRIPT_URL" in
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;;
esac
currentVersion=$(wget -qO- "${scriptURL}setup/index.txt" | grep '^a2serverVersion' | cut -d '"' -f 2)
if [[ -f /usr/local/etc/A2SERVER-version ]]; then
installedVersion=$(cat /usr/local/etc/A2SERVER-version)
@@ -9,12 +15,6 @@ else
installedVersion=100
fi
# Ensure URL we'll use ends in a /
case "$A2SERVER_SCRIPT_URL" in
*/) scriptURL="$A2SERVER_SCRIPT_URL" ;;
*) scriptURL="${A2SERVER_SCRIPT_URL:-http://appleii.ivanx.com/a2server}/" ;;
esac
autoAnswerYes=
for arg in $@; do
if [[ $arg == "-y" ]]; then
@@ -37,9 +37,8 @@ else
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 "${scriptURL}setup"; source /tmp/setup "$@"
wget -q -O /tmp/setup "${scriptURL}setup/index.txt"; source /tmp/setup -i "$@"
fi
unset currentVersion 2> /dev/null

View File

@@ -48,34 +48,41 @@
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
appleii.ivanx.com/a2server for development purposes
[not released]
1.2.5: Nov 2015: netboot install option for GS/OS 6.0.2/3; install HFS.FST
during netboot install
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.6: Nov 2015: full, ready to use install of Spectrum
[unannounced; released briefly, then withdrawn]
1.2.5+:Nov 2015: Merged Ivan's 1.2.5 release, removed support for Ubuntu for
now (see RasppleII/a2server#11), patched ProDOS 8 in boot
files for current year table, install unar from a package if
it exists.
[not released]
1.5.0: Jan 2016: mixed case filenames for A2FILES; remove GSFILES if empty;
install Marinetti 3.0b8 with internet access via MacIP;
fully install Spectrum, SAFE2, SAM2, SNAP, MountIt; install
DOS3.3 and TEACH; remove Ubuntu support; move/media/A2SHARED/*
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
[released briefly, then withdrawn]
1.5.1: Jan 2016: fixed GitHub URLs to prevent https errors during installation
(thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html);
bug fixes and minor text changes
1.2.6+:Nov 2015: merged Ivan's 1.2.6
[not released]
1.5.1r2: Oct 2017: corrected version number
1.5.2: Nov 2017: support for Debian/Raspbian Stretch; fixes minor bugs during
install; enable SSH server if disabled on Raspberry Pi; fixes
changed download links for GS/OS communication software
1.5.3a2: July 2020: initial support for Debian/Raspbian Buster
1.2.7: Dec 2015: codebase unified; preliminary Jessie support; case insensitive
file system for A2FILES; removes GSFILES if empty; DOS3.3.FST
and TEACH are installed with netboot installation; minor bug
fixes and tweaks
[not released]
Big thanks to: Anthony Martino, Henry Courbis, Joseph Carter, Jason King,
Andy McFadden, Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, David Schmidt,
David Schmenk, Ewen Wannop, Andrew Roughan, Antoine Vignau, Martin Haye,
Ken Gagne, Peter Neubauer, James Littlejohn, Ninjaforce; the creators of
Netatalk, The Unarchiver, ciopfs, macipgw; and the entire Apple II community.
Redistribution of Spectrum, SAFE2, SAM2, SNAP by permission of Ewen Wannop.
Thanks for using A2SERVER!