mirror of
				https://github.com/RasppleII/a2server.git
				synced 2025-10-30 23:16:08 +00:00 
			
		
		
		
	Compare commits
	
		
			49 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 33d1d058ba | ||
|  | c7d64f692c | ||
|  | aaea9245de | ||
|  | 7079684744 | ||
|  | 5e709f0e2e | ||
|  | e9c53fae66 | ||
|  | 2b52ad8429 | ||
|  | 9382387000 | ||
|  | 20bf50bc98 | ||
|  | 7aae31fda7 | ||
|  | 82183ad909 | ||
|  | 923a86899e | ||
|  | cb7b429927 | ||
|  | 106555bc95 | ||
|  | 099eccd9da | ||
|  | 14058b1990 | ||
|  | 456ed6e721 | ||
|  | 04974d7e03 | ||
|  | 45c00cb920 | ||
|  | a939111f6a | ||
|  | 02ebf26cf2 | ||
|  | 14a9adf673 | ||
|  | 15027e8423 | ||
|  | 4cba6ff2c0 | ||
|  | 23a8d1ca0d | ||
|  | a263603985 | ||
|  | 8eabd3768d | ||
|  | 3cd48ab4b3 | ||
|  | a4ab0c3d26 | ||
|  | ce2ac0d02d | ||
|  | 080242d969 | ||
|  | af9ebdc4da | ||
|  | a7ff9544bc | ||
|  | 0299a65e45 | ||
|  | 0a893dc8fd | ||
|  | 95fc0ef629 | ||
|  | e131b8de40 | ||
|  | 85d30152f2 | ||
|  | b60fd31d60 | ||
|  | 3a405377db | ||
|  | 1a3cae37d3 | ||
|  | ae89fef8b4 | ||
|  | 94d17f56cc | ||
|  | ee4078ab23 | ||
|  | 530b8d57f5 | ||
|  | 202d5e6321 | ||
|  | 8897610d95 | ||
|  | 27d40503be | ||
|  | 1c8acba1ae | 
							
								
								
									
										0
									
								
								.a2server_source
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								.a2server_source
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										14
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | # This is the topmost .editorconfig file | ||||||
|  | root = true | ||||||
|  |  | ||||||
|  | [*] | ||||||
|  | end_of_line = lf | ||||||
|  | insert_final_newline = true | ||||||
|  | trim_trailing_whitespace = true | ||||||
|  |  | ||||||
|  | [*.md] | ||||||
|  | trim_trailing_whitespace = false | ||||||
|  |  | ||||||
|  | [*.sh] | ||||||
|  | indent_style = tab | ||||||
|  | indent_size = 4 | ||||||
							
								
								
									
										121
									
								
								COPYING_CC0.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								COPYING_CC0.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | Creative Commons Legal Code | ||||||
|  |  | ||||||
|  | CC0 1.0 Universal | ||||||
|  |  | ||||||
|  |     CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE | ||||||
|  |     LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN | ||||||
|  |     ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS | ||||||
|  |     INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES | ||||||
|  |     REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS | ||||||
|  |     PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM | ||||||
|  |     THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED | ||||||
|  |     HEREUNDER. | ||||||
|  |  | ||||||
|  | Statement of Purpose | ||||||
|  |  | ||||||
|  | The laws of most jurisdictions throughout the world automatically confer | ||||||
|  | exclusive Copyright and Related Rights (defined below) upon the creator | ||||||
|  | and subsequent owner(s) (each and all, an "owner") of an original work of | ||||||
|  | authorship and/or a database (each, a "Work"). | ||||||
|  |  | ||||||
|  | Certain owners wish to permanently relinquish those rights to a Work for | ||||||
|  | the purpose of contributing to a commons of creative, cultural and | ||||||
|  | scientific works ("Commons") that the public can reliably and without fear | ||||||
|  | of later claims of infringement build upon, modify, incorporate in other | ||||||
|  | works, reuse and redistribute as freely as possible in any form whatsoever | ||||||
|  | and for any purposes, including without limitation commercial purposes. | ||||||
|  | These owners may contribute to the Commons to promote the ideal of a free | ||||||
|  | culture and the further production of creative, cultural and scientific | ||||||
|  | works, or to gain reputation or greater distribution for their Work in | ||||||
|  | part through the use and efforts of others. | ||||||
|  |  | ||||||
|  | For these and/or other purposes and motivations, and without any | ||||||
|  | expectation of additional consideration or compensation, the person | ||||||
|  | associating CC0 with a Work (the "Affirmer"), to the extent that he or she | ||||||
|  | is an owner of Copyright and Related Rights in the Work, voluntarily | ||||||
|  | elects to apply CC0 to the Work and publicly distribute the Work under its | ||||||
|  | terms, with knowledge of his or her Copyright and Related Rights in the | ||||||
|  | Work and the meaning and intended legal effect of CC0 on those rights. | ||||||
|  |  | ||||||
|  | 1. Copyright and Related Rights. A Work made available under CC0 may be | ||||||
|  | protected by copyright and related or neighboring rights ("Copyright and | ||||||
|  | Related Rights"). Copyright and Related Rights include, but are not | ||||||
|  | limited to, the following: | ||||||
|  |  | ||||||
|  |   i. the right to reproduce, adapt, distribute, perform, display, | ||||||
|  |      communicate, and translate a Work; | ||||||
|  |  ii. moral rights retained by the original author(s) and/or performer(s); | ||||||
|  | iii. publicity and privacy rights pertaining to a person's image or | ||||||
|  |      likeness depicted in a Work; | ||||||
|  |  iv. rights protecting against unfair competition in regards to a Work, | ||||||
|  |      subject to the limitations in paragraph 4(a), below; | ||||||
|  |   v. rights protecting the extraction, dissemination, use and reuse of data | ||||||
|  |      in a Work; | ||||||
|  |  vi. database rights (such as those arising under Directive 96/9/EC of the | ||||||
|  |      European Parliament and of the Council of 11 March 1996 on the legal | ||||||
|  |      protection of databases, and under any national implementation | ||||||
|  |      thereof, including any amended or successor version of such | ||||||
|  |      directive); and | ||||||
|  | vii. other similar, equivalent or corresponding rights throughout the | ||||||
|  |      world based on applicable law or treaty, and any national | ||||||
|  |      implementations thereof. | ||||||
|  |  | ||||||
|  | 2. Waiver. To the greatest extent permitted by, but not in contravention | ||||||
|  | of, applicable law, Affirmer hereby overtly, fully, permanently, | ||||||
|  | irrevocably and unconditionally waives, abandons, and surrenders all of | ||||||
|  | Affirmer's Copyright and Related Rights and associated claims and causes | ||||||
|  | of action, whether now known or unknown (including existing as well as | ||||||
|  | future claims and causes of action), in the Work (i) in all territories | ||||||
|  | worldwide, (ii) for the maximum duration provided by applicable law or | ||||||
|  | treaty (including future time extensions), (iii) in any current or future | ||||||
|  | medium and for any number of copies, and (iv) for any purpose whatsoever, | ||||||
|  | including without limitation commercial, advertising or promotional | ||||||
|  | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each | ||||||
|  | member of the public at large and to the detriment of Affirmer's heirs and | ||||||
|  | successors, fully intending that such Waiver shall not be subject to | ||||||
|  | revocation, rescission, cancellation, termination, or any other legal or | ||||||
|  | equitable action to disrupt the quiet enjoyment of the Work by the public | ||||||
|  | as contemplated by Affirmer's express Statement of Purpose. | ||||||
|  |  | ||||||
|  | 3. Public License Fallback. Should any part of the Waiver for any reason | ||||||
|  | be judged legally invalid or ineffective under applicable law, then the | ||||||
|  | Waiver shall be preserved to the maximum extent permitted taking into | ||||||
|  | account Affirmer's express Statement of Purpose. In addition, to the | ||||||
|  | extent the Waiver is so judged Affirmer hereby grants to each affected | ||||||
|  | person a royalty-free, non transferable, non sublicensable, non exclusive, | ||||||
|  | irrevocable and unconditional license to exercise Affirmer's Copyright and | ||||||
|  | Related Rights in the Work (i) in all territories worldwide, (ii) for the | ||||||
|  | maximum duration provided by applicable law or treaty (including future | ||||||
|  | time extensions), (iii) in any current or future medium and for any number | ||||||
|  | of copies, and (iv) for any purpose whatsoever, including without | ||||||
|  | limitation commercial, advertising or promotional purposes (the | ||||||
|  | "License"). The License shall be deemed effective as of the date CC0 was | ||||||
|  | applied by Affirmer to the Work. Should any part of the License for any | ||||||
|  | reason be judged legally invalid or ineffective under applicable law, such | ||||||
|  | partial invalidity or ineffectiveness shall not invalidate the remainder | ||||||
|  | of the License, and in such case Affirmer hereby affirms that he or she | ||||||
|  | will not (i) exercise any of his or her remaining Copyright and Related | ||||||
|  | Rights in the Work or (ii) assert any associated claims and causes of | ||||||
|  | action with respect to the Work, in either case contrary to Affirmer's | ||||||
|  | express Statement of Purpose. | ||||||
|  |  | ||||||
|  | 4. Limitations and Disclaimers. | ||||||
|  |  | ||||||
|  |  a. No trademark or patent rights held by Affirmer are waived, abandoned, | ||||||
|  |     surrendered, licensed or otherwise affected by this document. | ||||||
|  |  b. Affirmer offers the Work as-is and makes no representations or | ||||||
|  |     warranties of any kind concerning the Work, express, implied, | ||||||
|  |     statutory or otherwise, including without limitation warranties of | ||||||
|  |     title, merchantability, fitness for a particular purpose, non | ||||||
|  |     infringement, or the absence of latent or other defects, accuracy, or | ||||||
|  |     the present or absence of errors, whether or not discoverable, all to | ||||||
|  |     the greatest extent permissible under applicable law. | ||||||
|  |  c. Affirmer disclaims responsibility for clearing rights of other persons | ||||||
|  |     that may apply to the Work or any use thereof, including without | ||||||
|  |     limitation any person's Copyright and Related Rights in the Work. | ||||||
|  |     Further, Affirmer disclaims responsibility for obtaining any necessary | ||||||
|  |     consents, permissions or other rights required for any use of the | ||||||
|  |     Work. | ||||||
|  |  d. Affirmer understands and acknowledges that Creative Commons is not a | ||||||
|  |     party to this document and has no duty or obligation with respect to | ||||||
|  |     this CC0 or use of the Work. | ||||||
							
								
								
									
										91
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,6 +1,5 @@ | |||||||
| # A2SERVER | # A2SERVER | ||||||
| AppleTalk server for Apple // computers developed by Ivan Drucker, with | AppleTalk server for Apple // computers developed by Ivan Drucker | ||||||
| substantial rework and by T. Joseph Carter |  | ||||||
|  |  | ||||||
| Documentation here is sparse for the moment; see [Ivan's site]() for | Documentation here is sparse for the moment; see [Ivan's site]() for | ||||||
| information about A2SERVER and how it all works.  There's a lot there and it's | information about A2SERVER and how it all works.  There's a lot there and it's | ||||||
| @@ -14,91 +13,7 @@ relatively modern piece of it.  As such they should be preserved as they are. | |||||||
|  |  | ||||||
| ## Developer note | ## Developer note | ||||||
|  |  | ||||||
| To use the scripts with a specific GitHub tag: | This section used to describe how to run these scripts directly.  That's | ||||||
| ~~~ bash | changing.  Watch this space. | ||||||
| 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 |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| Or, to use the scripts on your own server, including your local machine: |  | ||||||
|  |  | ||||||
| ~~~ bash |  | ||||||
| export A2SERVER_SCRIPT_URL=http://yoururl.com/ |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| To prevent needing to recompile various packages from source code during |  | ||||||
| installation, a number of precompiled binary files are downloaded for Raspbian, |  | ||||||
| Debian-x86, and Debian-amd64. If you wish to host these on your own server: |  | ||||||
|  |  | ||||||
| ~~~ bash |  | ||||||
| export A2SERVER_BINARY_URL=http://yoururl.com/files/ |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| You do not need to use a subdirectory called "files", or the same server, but |  | ||||||
| that's the normal arrangement. The precompiled packages are available here: |  | ||||||
| `http://ivanx.com/a2server/files/dist/a2serverbinaries.tar.gz` |  | ||||||
|  |  | ||||||
| Several Apple II third-party binaries are downloaded during installation, as |  | ||||||
| well as third-party source code if precompiled binaries are unavailable or |  | ||||||
| you don't wish to use them. If you want these external dependencies locally |  | ||||||
| during development, they need to go into a folder called "external" in |  | ||||||
| the binaries URL, and that needs to contain folders called "appleii" and |  | ||||||
| "source". To download all of these external packages, download and run the |  | ||||||
| shell script at |  | ||||||
| `http://ivanx.com/a2server/files/dist/getexternal.sh`. |  | ||||||
|  |  | ||||||
| Once you have those: |  | ||||||
|  |  | ||||||
| ~~~ bash |  | ||||||
| export A2SERVER_NO_EXTERNAL=1 |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| You may want to put the above exports into `~/.bashrc` or `~/.bash_profile`. |  | ||||||
|  |  | ||||||
| If you want to host scripts locally installed on your own machine or another |  | ||||||
| computer on your LAN, type the following, and export "http://localhost:8000/" |  | ||||||
| or "http://lan.ip.address:8000/" for the above URL's. |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| python -m SimpleHTTPServer |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| Once you're set, you can then run the following snippet to install A2SERVER: |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| wget -O setup ${A2SERVER_SCRIPT_URL}setup/index.txt; source setup |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Offline install: |  | ||||||
|  |  | ||||||
| Using locally hosted binaries and external dependencies, it's possible to |  | ||||||
| install completely offline if dependent packages have been installed. |  | ||||||
|  |  | ||||||
| If precompiled binaries are available, on Wheezy: |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| sudo apt-get -y install unzip libgnustep-base1.22 libdb5.1 libgcrypt11 libssl1.0.0 attr fuse libglib2.0-0 libattr1 libfuse2 |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| If precompiled binaries are available, on Jessie: |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| sudo apt-get -y install unzip unar libdb5.3 libgcrypt20 libssl1.0.0 attr fuse libglib2.0-0 libattr1 libfuse2 |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| If precompiled binaries are not available, on Wheezy: |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| sudo apt-get -y install unzip build-essential zlib1g-dev libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev libdb5.1-dev libgcrypt11-dev libglib2.0-dev libattr1-dev libfuse-dev |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
| If precompiled binaries are not available, on Jessie: |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| sudo apt-get -y install unzip unar build-essential zlib1g-dev unzip libssl-dev libdb5.3-dev libgcrypt11-dev libglib2.0-dev libattr1-dev libfuse-dev |  | ||||||
| ~~~ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [Ivan's site]: http://appleii.ivanx.com/a2server/ | [Ivan's site]: http://appleii.ivanx.com/a2server/ | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								files/dist/getexternal.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								files/dist/getexternal.sh
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| if ! hash wget; then | if ! hash wget; then | ||||||
| 	echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew." | 	echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew." | ||||||
|   | |||||||
							
								
								
									
										114
									
								
								fix/fix.txt
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								fix/fix.txt
									
									
									
									
									
								
							| @@ -1,114 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
|  |  | ||||||
| echo |  | ||||||
| echo "A2SERVER fix: This utility will make a Raspberry Pi SD card boot if it" |  | ||||||
| echo "kernel panics (crashes) on startup after updating its operating system" |  | ||||||
| echo "while A2SERVER is installed." |  | ||||||
| echo |  | ||||||
| echo -n "Continue? " |  | ||||||
| read |  | ||||||
| doFix= |  | ||||||
| if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then |  | ||||||
|     while true; do |  | ||||||
|         echo |  | ||||||
|         echo "If attached, remove the Raspberry Pi's SD card from this computer." |  | ||||||
|         echo -n "Press return to continue..."; read; echo |  | ||||||
|  |  | ||||||
|         ls -1 /dev/sd? > /tmp/sd1 2> /dev/null |  | ||||||
|  |  | ||||||
|         echo "Insert the Raspberry Pi's SD card into this computer, using a USB" |  | ||||||
|         echo "reader if you don't have an SD slot. If this is a virtual machine," |  | ||||||
|         echo "make sure you select the reader or SD slot from its USB menu." |  | ||||||
|         echo -n "Press return to continue..."; read; echo |  | ||||||
|  |  | ||||||
|         ls -1 /dev/sd? > /tmp/sd2 2> /dev/null |  | ||||||
|          |  | ||||||
|         # if exactly one drive has been inserted, exit loop |  | ||||||
|         if { ! diff /tmp/sd1 /tmp/sd2 &> /dev/null; }; then |  | ||||||
|             # files are different, get dev name |  | ||||||
|             if [[ $(wc -c /tmp/sd1 | cut -f 1 -d ' ') -eq 0 ]]; then |  | ||||||
|                 if [[ $(wc -l /tmp/sd2 | cut -f 1 -d ' ') -eq 1 ]]; then |  | ||||||
|                     devName=$(cat /tmp/sd2) |  | ||||||
|                     break |  | ||||||
|                 else |  | ||||||
|                     echo "More than one volume seems to have appeared. Trying again..." |  | ||||||
|                     echo |  | ||||||
|                 fi |  | ||||||
|             else |  | ||||||
|                 devName=$(grep -v "$(cat /tmp/sd1)" /tmp/sd2) |  | ||||||
|                 if [[ $(wc -l <<< $devName) -eq 1 ]]; then |  | ||||||
|                     break |  | ||||||
|                 else |  | ||||||
|                     echo "More than one volume seems to have appeared. Trying again..." |  | ||||||
|                     echo |  | ||||||
|                 fi |  | ||||||
|             fi |  | ||||||
|         else |  | ||||||
|             echo "No SD card found. Trying again..." |  | ||||||
|             echo |  | ||||||
|         fi |  | ||||||
|          |  | ||||||
|     done |  | ||||||
|      |  | ||||||
|     mkdir -p /tmp/sd |  | ||||||
|     sudo mount ${devName}6 /tmp/sd |  | ||||||
|  |  | ||||||
|     raspbianDate=$(date -d "$(zcat /tmp/sd/usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 ' --' | rev | cut -f 1-6 -d ' ' | rev)" +%s) |  | ||||||
|     doFix= |  | ||||||
|     if [[ $raspbianDate -lt 1403204265 ]]; then |  | ||||||
|         echo "This doesn't appear to be a version of Raspbian that requires fixing." |  | ||||||
|         echo -n "Are you sure you want to continue? " |  | ||||||
|         read |  | ||||||
|         if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then |  | ||||||
|             doFix=1 |  | ||||||
|         fi |  | ||||||
|     else |  | ||||||
|         doFix=1 |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [[ $doFix ]]; then |  | ||||||
|         while read kernelRelease; do |  | ||||||
|             kernelReplaced= |  | ||||||
|             kernelMajorRelease=$(cut -d '.' -f 1  <<< $kernelRelease) |  | ||||||
|             kernelMinorRelease=$(cut -d '.' -f 2  <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/') |  | ||||||
|             kernelPatchRelease=$(cut -d '.' -f 3- <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/') |  | ||||||
|             # if kernel 3.12 below 3.12.25+, delete defective AppleTalk kernel |  | ||||||
|             if [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -eq 12 && $kernelPatchRelease -lt 25 ]]; then |  | ||||||
|                 if [[ -f /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then |  | ||||||
|                     if [[ $(sha1sum /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d ' ') != "ecb239fc084c36de93f6926e7749b80f6024f269" ]]; then |  | ||||||
|                         echo "Removing defective AppleTalk module from kernel $kernelRelease..." |  | ||||||
|                         sudo rm -rf /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk 2> /dev/null |  | ||||||
|                         wget -qO /tmp/appletalk.ko.gz ${A2SERVER_SCRIPT_URL}files/appletalk-$kernelRelease.ko.gz |  | ||||||
|                         if [[ $? -eq 0 ]]; then |  | ||||||
|                             # if we found a prebuilt one on a2server site, so install it |  | ||||||
|                             gunzip -f /tmp/appletalk.ko.gz |  | ||||||
|                             sudo mkdir -p /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk |  | ||||||
|                             sudo mv /tmp/appletalk.ko /tmp/sd/lib/modules/$kernelRelease/kernel/net/appletalk |  | ||||||
|                             echo "Installed fixed AppleTalk module for kernel $kernelRelease." |  | ||||||
|                             kernelReplaced=1 |  | ||||||
|                         fi |  | ||||||
|                     fi |  | ||||||
|                 fi |  | ||||||
|             fi |  | ||||||
|         done <<< "$(ls -1 /tmp/sd/lib/modules | sort -V)" |  | ||||||
|         sudo umount /tmp/sd |  | ||||||
|          |  | ||||||
|         echo kern:$kernelReplaced |  | ||||||
|         if [[ $kernelReplaced ]]; then |  | ||||||
|             echo |  | ||||||
|             echo "All set. Remove your SD card, put it back in your Pi, and boot it." |  | ||||||
|             echo |  | ||||||
|             echo "You should be able to connect from your Apple II, but if you can't," |  | ||||||
|             echo "log in to your Pi and type 'a2server-setup' to complete the fix." |  | ||||||
|         else |  | ||||||
|             echo |  | ||||||
|             echo "Okey doke. Half done. Remove your SD card, and put it back in your Pi." |  | ||||||
|             echo "After it boots, log in and type 'a2server-setup' to complete the fix." |  | ||||||
|         fi         |  | ||||||
|         echo "See the A2SERVER web site at http://ivanx.com/a2server for more help." |  | ||||||
|         echo "(You can type 'sudo shutdown -h now' if you're done on this machine.)" |  | ||||||
|         echo |  | ||||||
|     fi |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| rm fix &> /dev/null |  | ||||||
							
								
								
									
										28
									
								
								install.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								install.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # install.sh - a2server main installation script | ||||||
|  | # | ||||||
|  | # To the extent possible under law, T. Joseph Carter and Ivan Drucker have | ||||||
|  | # waived all copyright and related or neighboring rights to the a2server | ||||||
|  | # scripts themselves.  Software used or installed by these scripts is subject | ||||||
|  | # to other licenses.  This work is published from the United States. | ||||||
|  |  | ||||||
|  | a2serverVersion="1.9.0" | ||||||
|  | a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/master" | ||||||
|  |  | ||||||
|  | # Find the path of our source directory | ||||||
|  | a2sSource="$( dirname "${BASH_SOURCE[0]}" )" | ||||||
|  | echo $a2source | ||||||
|  | pushd $a2sSource >/dev/null | ||||||
|  | a2sSource="$PWD" | ||||||
|  | popd >/dev/null | ||||||
|  | if [[ ! -f "$a2sSource/.a2server_source" ]]; then | ||||||
|  | 	printf "\na2server: cannot find a2server source directory in $a2sSource.\n\n" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Run the legacy setup script for anything not yet ported | ||||||
|  | if [[ -e "${a2sSource}/setup/ivan.sh" ]]; then | ||||||
|  | 	"${a2sSource}/setup/ivan.sh" "$@" | ||||||
|  | fi | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # --- Setting up the share volume | # --- Setting up the share volume | ||||||
|  |  | ||||||
| @@ -11,21 +11,15 @@ if [[ -d /media/A2SHARED ]]; then | |||||||
| 	[[ ! -d /srv ]] && sudo mkdir -p /srv | 	[[ ! -d /srv ]] && sudo mkdir -p /srv | ||||||
| 	sudo mv /media/A2SHARED /srv/A2SERVER | 	sudo mv /media/A2SHARED /srv/A2SERVER | ||||||
| 	sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /usr/local/etc/netatalk/AppleVolumes.default | 	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 | 	if [[ -f /etc/samba/smbd.conf ]]; then | ||||||
|      | 		sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /etc/samba/smbd.conf | ||||||
|  | 	fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # skip if we're already set up | if [[ ! -d /srv/A2SERVER ]]; then | ||||||
| if [[ -d /srv/A2SERVER ]]; then |  | ||||||
|  |  | ||||||
|     echo "A2SERVER: Shared volume is already prepared for use." |  | ||||||
|  |  | ||||||
| else |  | ||||||
|  |  | ||||||
| 	echo "A2SERVER: Preparing the shared files volume..." | 	echo "A2SERVER: Preparing the shared files volume..." | ||||||
|  |  | ||||||
| 	sudo mkdir -p /srv/A2SERVER | 	sudo mkdir -p /srv/A2SERVER | ||||||
|  |  | ||||||
| 	sudo chown $USER:$USER /srv/A2SERVER | 	sudo chown $USER:$USER /srv/A2SERVER | ||||||
|  | else | ||||||
|  | 	echo "A2SERVER: Shared volume is already prepared for use." | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -1,54 +1,49 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # download and install a2server tools: | # download and install a2server tools: | ||||||
| # mkatinit, mkvolinfo, afptype, afpsync, aliases, nulib2 | # mkatinit, mkvolinfo, afptype, afpsync, aliases, nulib2 | ||||||
|  |  | ||||||
| # Ensure URL we'll use ends in a / | a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/master" | ||||||
| case "$A2SERVER_SCRIPT_URL" in | a2sBinaryURL="http://blocksfree.com/downloads" | ||||||
| 	*/) scriptURL="$A2SERVER_SCRIPT_URL" ;; |  | ||||||
| 	*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | # Find the path of our source directory | ||||||
| esac | a2sSource="$( dirname "${BASH_SOURCE[0]}" )/.." | ||||||
| case "$A2SERVER_BINARY_URL" in | pushd $a2sSource >/dev/null | ||||||
| 	*/) binaryURL="$A2SERVER_BINARY_URL" ;; | a2sSource="$PWD" | ||||||
| 	*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;; | popd >/dev/null | ||||||
| esac | if [[ ! -f "$a2sSource/.a2server_source" ]]; then | ||||||
|  | 	printf "\na2server: cannot find a2server source directory in $a2sSource.\n\n" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| useExternalURL=1 | useExternalURL=1 | ||||||
| [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | ||||||
|  |  | ||||||
| debianVersion=$(cat /etc/debian_version 2> /dev/null) | debianVersion="$(lsb_release -rs)" | ||||||
| isRpi= | isRpi= | ||||||
| arch= | arch= | ||||||
| if [[ -f /usr/bin/raspi-config ]]; then | if [[ -f /usr/bin/raspi-config ]]; then | ||||||
| 	isRpi=1 | 	isRpi=1 | ||||||
| 	arch='rpi' | 	arch='rpi' | ||||||
| elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then | elif [[ "$(lsb_release -ds)" = Debian* ]]; then | ||||||
|  | 	if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then | ||||||
| 		uname_m="$(uname -m)" | 		uname_m="$(uname -m)" | ||||||
| 		if [[ $uname_m == "i686" ]]; then | 		if [[ $uname_m == "i686" ]]; then | ||||||
| 			arch='debian_x86' | 			arch='debian_x86' | ||||||
| 		elif [[ $uname_m == "x86_64" ]]; then | 		elif [[ $uname_m == "x86_64" ]]; then | ||||||
| 			arch='debian_x64' | 			arch='debian_x64' | ||||||
| 		fi | 		fi | ||||||
| fi |  | ||||||
|  |  | ||||||
| debianName= |  | ||||||
| if [[ $debianVersion ]]; then |  | ||||||
|     debianMajor=$(cut -d . -f 1 <<< $debianVersion) |  | ||||||
|     if [[ $debianMajor == "9" ]]; then |  | ||||||
|         debianName="stretch" |  | ||||||
|     elif [[ $debianMajor == "8" ]]; then |  | ||||||
|         debianName="jessie" |  | ||||||
|     elif [[ $debianMajor == "7" ]]; then |  | ||||||
|         debianName="wheezy" |  | ||||||
|     else |  | ||||||
|         debianName="unknown" |  | ||||||
| 	fi | 	fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | debianName=$(lsb_release -cs) | ||||||
|  |  | ||||||
| echo "A2SERVER: Installing A2SERVER tools..." | echo "A2SERVER: Installing A2SERVER tools..." | ||||||
|  |  | ||||||
| # delete older nulib2 which doesn't correctly handle zero-length forks in GSHK-created archives | # delete older nulib2 which doesn't correctly handle zero-length forks in GSHK-created archives | ||||||
| if hash nulib2 &> /dev/null; then | if hash nulib2 &> /dev/null; then | ||||||
|  | 	# FIXME make this sed more robust | ||||||
| 	nulib2version=$(nulib2 | sed -n 2p | sed 's|^.*v\([0-9]\)\.\([0-9]\)\.\([0-9]\).*$|\1\2\3|' 2> /dev/null) | 	nulib2version=$(nulib2 | sed -n 2p | sed 's|^.*v\([0-9]\)\.\([0-9]\)\.\([0-9]\).*$|\1\2\3|' 2> /dev/null) | ||||||
| 	if (( $nulib2version < 310 )); then | 	if (( $nulib2version < 310 )); then | ||||||
| 		sudo apt-get -y purge nulib2 &> /dev/null | 		sudo apt-get -y purge nulib2 &> /dev/null | ||||||
| @@ -62,7 +57,7 @@ if ! hash nulib2 &> /dev/null; then | |||||||
|  |  | ||||||
| 	cd /tmp | 	cd /tmp | ||||||
| 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||||
|         { wget -qO- "${binaryURL}precompiled/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null | 		{ wget -qO- "${a2sBinaryURL}/picopkg/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| 	if ! hash nulib2 &> /dev/null; then | 	if ! hash nulib2 &> /dev/null; then | ||||||
| @@ -82,12 +77,15 @@ if ! hash nulib2 &> /dev/null; then | |||||||
| 		mkdir /tmp/nulib2 | 		mkdir /tmp/nulib2 | ||||||
| 		cd /tmp/nulib2 | 		cd /tmp/nulib2 | ||||||
| 		if [[ $useExternalURL ]]; then | 		if [[ $useExternalURL ]]; then | ||||||
|             wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7efb4d37fedf807416c16d74d51d893ea48a.zip" | 			# nulib2 does not have this tagged so we use github's auto-zipball feature | ||||||
|  | 			# note: topdir is nulib2-<full hash> | ||||||
|  | 			# note2: .tar.gz also works | ||||||
|  | 			wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7ef.zip" | ||||||
| 			unzip nulib2-3.1.0a2.zip 2> /dev/null | 			unzip nulib2-3.1.0a2.zip 2> /dev/null | ||||||
| 			rm nulib2-3.1.0a2.zip &> /dev/null | 			rm nulib2-3.1.0a2.zip &> /dev/null | ||||||
| 		fi | 		fi | ||||||
| 		if [ ! -d nulib2* ]; then | 		if [ ! -d nulib2* ]; then | ||||||
|             wget -q -O nulib2-3.1.0a2.zip "${binaryURL}external/source/nulib2-3.1.0a2.zip" | 			wget -q -O nulib2-3.1.0a2.zip "${a2sBinaryURL}/source/nulib2-3.1.0a2.zip" | ||||||
| 			unzip nulib2-3.1.0a2.zip 2> /dev/null | 			unzip nulib2-3.1.0a2.zip 2> /dev/null | ||||||
| 			rm nulib2-3.1.0a2.zip &> /dev/null | 			rm nulib2-3.1.0a2.zip &> /dev/null | ||||||
| 		fi | 		fi | ||||||
| @@ -122,7 +120,7 @@ if ! hash unar &> /dev/null; then | |||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| 	# jessie and later: Just use the unar package | 	# jessie and later: Just use the unar package | ||||||
|     if [[ $debianMajor -ge 8 ]]; then | 	if [[ "$debianName" != "wheezy" ]]; then | ||||||
| 		sudo apt-get -y install unar | 		sudo apt-get -y install unar | ||||||
| 		sudo apt-get clean | 		sudo apt-get clean | ||||||
| 	fi | 	fi | ||||||
| @@ -132,7 +130,7 @@ if ! hash unar &> /dev/null; then | |||||||
| 			# Dependencies: for unar | 			# Dependencies: for unar | ||||||
| 			sudo apt-get -y install libgnustep-base1.22 | 			sudo apt-get -y install libgnustep-base1.22 | ||||||
| 			sudo apt-get clean | 			sudo apt-get clean | ||||||
|             { wget -qO- "${binaryURL}precompiled/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null | 			{ wget -qO- "${a2sBinaryURL}/picopkg/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null | ||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
| 		# If all else fails, compile from source. | 		# If all else fails, compile from source. | ||||||
| @@ -146,11 +144,11 @@ if ! hash unar &> /dev/null; then | |||||||
| 			mkdir /tmp/unar | 			mkdir /tmp/unar | ||||||
| 			cd /tmp/unar | 			cd /tmp/unar | ||||||
| 			if [[ $useExternalURL ]]; then | 			if [[ $useExternalURL ]]; then | ||||||
|                 wget -O unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip | 				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 | 				unzip -o unar-1.8.1.zip &> /dev/null | ||||||
| 			fi | 			fi | ||||||
| 			if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob | 			if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob | ||||||
|                 wget -O unar-1.8.1.zip ${binaryURL}external/source/unar-1.8.1.zip | 				wget -O unar-1.8.1.zip "${a2sBinaryURL}/source/unar-1.8.1.zip" | ||||||
| 				unzip -o unar-1.8.1.zip &> /dev/null | 				unzip -o unar-1.8.1.zip &> /dev/null | ||||||
| 			fi | 			fi | ||||||
| 			cd *Unarchiver*/XADMaster | 			cd *Unarchiver*/XADMaster | ||||||
| @@ -182,32 +180,35 @@ else | |||||||
| 	echo "A2SERVER: unzip has already been installed." | 	echo "A2SERVER: unzip has already been installed." | ||||||
| fi | fi | ||||||
|  |  | ||||||
| sudo wget -q -O /usr/local/bin/afpsync "${scriptURL}scripts/tools/afpsync.txt" | a2sTools="afpsync afptype mkatinit mkvolinfo cppo debupdate" | ||||||
| sudo chmod ugo+x /usr/local/bin/afpsync | a2sHelp="a2server-help.txt" | ||||||
| sudo wget -q -O /usr/local/bin/afptype "${scriptURL}scripts/tools/afptype.txt" | a2sConfScripts="a2server-aliases a2serverrc" | ||||||
| sudo chmod ugo+x /usr/local/bin/afptype | for _tool in $a2sTools; do | ||||||
| sudo wget -q -O /usr/local/bin/mkatinit "${scriptURL}scripts/tools/mkatinit.txt" | 	sudo install -m 755 "$a2sSource/scripts/tools/$_tool" "/usr/local/bin/$_tool" | ||||||
| sudo chmod ugo+x /usr/local/bin/mkatinit | done | ||||||
| sudo wget -q -O /usr/local/bin/mkvolinfo "${scriptURL}scripts/tools/mkvolinfo.txt" | for _help in $a2sHelp; do | ||||||
| sudo chmod ugo+x /usr/local/bin/mkvolinfo | 	sudo install -m 644 "$a2sSource/scripts/tools/$_help" "/usr/local/etc/$_help" | ||||||
| sudo wget -q -O /usr/local/bin/cppo "${scriptURL}scripts/tools/cppo.txt" | done | ||||||
| sudo chmod ugo+x /usr/local/bin/cppo | for _confscript in $a2sConfScripts; do | ||||||
| sudo wget -q -O /usr/local/etc/a2server-help.txt "${scriptURL}scripts/tools/a2server-help.txt" | 	sudo install -m 755 "$a2sSource/scripts/tools/$_confscript" "/usr/local/etc/$_tool" | ||||||
| sudo wget -q -O /usr/local/etc/a2server-aliases "${scriptURL}scripts/tools/a2server-aliases.txt" | done | ||||||
| sudo wget -q -O /usr/local/etc/a2serverrc "${scriptURL}scripts/tools/a2serverrc.txt" |  | ||||||
|  |  | ||||||
| # 1.3.0: a2serverrc is now called from /etc/bash.bashrc, | # 1.3.0: a2serverrc is now called from /etc/bash.bashrc, | ||||||
| #   which in turn calls a2server-aliases | #   which in turn calls a2server-aliases | ||||||
| grep 'a2server-aliases' /etc/bash.bashrc > /dev/null && \ | if grep 'a2server-aliases' /etc/bash.bashrc >/dev/null; then | ||||||
| sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc | 	sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc | ||||||
| grep 'a2serverrc' /etc/bash.bashrc > /dev/null || \ | fi | ||||||
| echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc > /dev/null | if ! grep 'a2serverrc' /etc/bash.bashrc >/dev/null; then | ||||||
|  | 	echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc >/dev/null | ||||||
|  | fi | ||||||
|  |  | ||||||
| motd="/etc/motd" | motd="/etc/motd" | ||||||
| if [[ ! $(grep A2SERVER $motd) ]]; then | if [[ ! $(grep A2SERVER $motd) ]]; then | ||||||
|     echo | sudo tee -a $motd > /dev/null | 	sudo tee -a $motd >/dev/null <<EOF | ||||||
|     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 | Type 'system-shutdown' to turn off A2SERVER. | ||||||
|     echo "Type 'a2server-help' for a list of other commands." | sudo tee -a $motd > /dev/null | Type 'a2server-setup' to configure network boot. | ||||||
|     echo | sudo tee -a $motd > /dev/null | Type 'a2server-help' for a list of other commands. | ||||||
|  |  | ||||||
|  | EOF | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # A2SERVER -- a virtual machine for sharing files to Apple II clients | # A2SERVER -- a virtual machine for sharing files to Apple II clients | ||||||
| # by Ivan X, ivan@ivanx.com | # by Ivan X, ivan@ivanx.com | ||||||
| @@ -10,70 +10,46 @@ | |||||||
| # at comp.sys.apple2 for the work they've done and insight they've | # at comp.sys.apple2 for the work they've done and insight they've | ||||||
| # offered which made it possible to put this together. | # offered which made it possible to put this together. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # --- Installing netatalk | # --- Installing netatalk | ||||||
|  |  | ||||||
| # Ensure URL we'll use ends in a / | a2sBinaryURL="http://blocksfree.com/downloads" | ||||||
| case "$A2SERVER_SCRIPT_URL" in |  | ||||||
|     */) scriptURL="$A2SERVER_SCRIPT_URL" ;; |  | ||||||
|     *) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; |  | ||||||
| esac |  | ||||||
| case "$A2SERVER_BINARY_URL" in |  | ||||||
|     */) binaryURL="$A2SERVER_BINARY_URL" ;; |  | ||||||
|     *) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;; |  | ||||||
| esac |  | ||||||
| useExternalURL=1 | useExternalURL=1 | ||||||
| [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | ||||||
|  |  | ||||||
| debianVersion=$(cat /etc/debian_version 2> /dev/null) | debianVersion="$(lsb_release -rs)" | ||||||
| isRpi= | isRpi= | ||||||
| arch= | arch= | ||||||
| if [[ -f /usr/bin/raspi-config ]]; then | if [[ -f /usr/bin/raspi-config ]]; then | ||||||
| 	isRpi=1 | 	isRpi=1 | ||||||
| 	arch='rpi' | 	arch='rpi' | ||||||
| elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then | elif [[ "$(lsb_release -ds)" = Debian* ]]; then | ||||||
|  | 	if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then | ||||||
| 		uname_m="$(uname -m)" | 		uname_m="$(uname -m)" | ||||||
| 		if [[ $uname_m == "i686" ]]; then | 		if [[ $uname_m == "i686" ]]; then | ||||||
| 			arch='debian_x86' | 			arch='debian_x86' | ||||||
| 		elif [[ $uname_m == "x86_64" ]]; then | 		elif [[ $uname_m == "x86_64" ]]; then | ||||||
| 			arch='debian_x64' | 			arch='debian_x64' | ||||||
| 		fi | 		fi | ||||||
| fi |  | ||||||
|  |  | ||||||
| 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 | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | debianName=$(lsb_release -cs) | ||||||
|  |  | ||||||
| # enable SSH (disabled by default in Raspbian from late 2016 onward) | # enable SSH (disabled by default in Raspbian from late 2016 onward) | ||||||
| if [[ $isRpi && $debianMajor -ge 8 ]] && ! ps aux | grep -q '[s]shd'; then | if [[ $isRpi ]] && ! ps aux | grep -q '[s]shd'; then | ||||||
| 	echo "A2SERVER: Enabling ssh access..." | 	echo "A2SERVER: Enabling ssh access..." | ||||||
| 	sudo systemctl enable ssh &> /dev/null && sudo systemctl start ssh &> /dev/null | 	sudo systemctl enable ssh &> /dev/null && sudo systemctl start ssh &> /dev/null | ||||||
| else | else | ||||||
| 	echo "A2SERVER: ssh access is already enabled." | 	echo "A2SERVER: ssh access is already enabled." | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # skip this if already done | if [[ -f /usr/local/etc/A2SERVER-version ]]; then | ||||||
| if [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) >= 101 )); then | 	read a2sVersion </usr/local/etc/A2SERVER-version | ||||||
|  | fi | ||||||
|     echo "A2SERVER: Netatalk is already installed." | # If A2SERVER 101 or greater is installed, we already did this and can skip it. | ||||||
|      | if [[ "$a2sVersion" != *.*.* && "$a2sVersion" -lt 101 ]]; then | ||||||
| else |  | ||||||
|  |  | ||||||
| 	echo "A2SERVER: Installing Netatalk (this will take a while)..." | 	echo "A2SERVER: Installing Netatalk (this will take a while)..." | ||||||
|      |  | ||||||
| 	# stop Netatalk and samba if running (during upgrade) | 	# stop Netatalk and samba if running (during upgrade) | ||||||
| 	if [[ $(ps --no-headers -C afpd) ]]; then | 	if [[ $(ps --no-headers -C afpd) ]]; then | ||||||
| 		sudo /etc/init.d/netatalk stop &> /dev/null | 		sudo /etc/init.d/netatalk stop &> /dev/null | ||||||
| @@ -86,25 +62,6 @@ else | |||||||
| 		touch /tmp/a2server-packageReposUpdated | 		touch /tmp/a2server-packageReposUpdated | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
|     # not being used as of 1.2.9, but it's available if full URL to .deb package is supplied |  | ||||||
|     getOldPackage () {  |  | ||||||
|         for url in $@; do |  | ||||||
|             pkgFile=${url##*/} |  | ||||||
|             pkgName=${pkgFile%%_*} |  | ||||||
|             if ! dpkg -l $pkgName 2> /dev/null | grep -q '^ii'; then |  | ||||||
|                 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##*/}" |  | ||||||
|             fi |  | ||||||
|         done |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| 	compileFromSource=1 | 	compileFromSource=1 | ||||||
| 	urls= | 	urls= | ||||||
| 	while [[ $arch ]]; do | 	while [[ $arch ]]; do | ||||||
| @@ -124,13 +81,6 @@ else | |||||||
| 		elif [[ $(apt-cache search '^libssl1.0.2$') ]]; then # Stretch | 		elif [[ $(apt-cache search '^libssl1.0.2$') ]]; then # Stretch | ||||||
| 			# Dependencies: netatalk 2.2.4 | 			# Dependencies: netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libssl1.0.2 | 			sudo apt-get -y install libssl1.0.2 | ||||||
|         elif [[ $(apt-cache search '^libssl1.1$') ]]; then # Buster |  | ||||||
|             # Dependencies: netatalk 2.2.4 |  | ||||||
|             echo "deb http://deb.debian.org/debian/ oldstable main" | sudo tee -a /etc/apt/sources.list > /dev/null |  | ||||||
|             sudo apt-get -y update |  | ||||||
|             sudo apt-get -y install libssl1.0.2 |  | ||||||
|             sudo sed -i '$d' /etc/apt/sources.list |  | ||||||
|             sudo apt-get -y update |  | ||||||
| 		else | 		else | ||||||
| 			break | 			break | ||||||
| 		fi | 		fi | ||||||
| @@ -138,7 +88,7 @@ else | |||||||
| 		if [[ $(apt-cache search '^libgcrypt11$') ]]; then # Wheezy | 		if [[ $(apt-cache search '^libgcrypt11$') ]]; then # Wheezy | ||||||
| 			# Dependencies: netatalk 2.2.4 | 			# Dependencies: netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libgcrypt11 | 			sudo apt-get -y install libgcrypt11 | ||||||
|         elif [[ $(apt-cache search '^libgcrypt20$') ]]; then # Jessie, Stretch, Buster | 		elif [[ $(apt-cache search '^libgcrypt20$') ]]; then # Jessie or Stretch | ||||||
| 			# Dependencies: netatalk 2.2.4 | 			# Dependencies: netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libgcrypt20 | 			sudo apt-get -y install libgcrypt20 | ||||||
| 		else | 		else | ||||||
| @@ -147,7 +97,7 @@ else | |||||||
|  |  | ||||||
| 		# install Netatalk | 		# install Netatalk | ||||||
| 		if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | 		if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||||
|             { wget -qO- "${binaryURL}precompiled/netatalk226-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null | 			{ wget -qO- "${a2sBinaryURL}/picopkg/netatalk224-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null | ||||||
| 		fi | 		fi | ||||||
| 		sudo mandb &> /dev/null | 		sudo mandb &> /dev/null | ||||||
|  |  | ||||||
| @@ -157,36 +107,24 @@ else | |||||||
| 	done | 	done | ||||||
|  |  | ||||||
| 	if [[ $compileFromSource ]]; then | 	if [[ $compileFromSource ]]; then | ||||||
|      |  | ||||||
| 		# Dependencies: build-deps for netatalk 2.2.4 | 		# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 		sudo apt-get -y install build-essential | 		sudo apt-get -y install build-essential | ||||||
|          |  | ||||||
|         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 | 		if [[ $(apt-cache search '^libssl1.0-dev$') ]]; then # Stretch | ||||||
|  | 			if [[ $(dpkg -l | grep libssl-dev | tr -s ' ' | cut -d ' ' -f 3 | cut -c 1-3) == "1.1" ]]; then | ||||||
|  | 				echo "A2SERVER: WARNING: libssl-dev will be removed to install libssl1.0-dev" | ||||||
|  | 			fi | ||||||
|  | 			# Note the libssl1.0-dev package will go away; we need a 1.1 patch | ||||||
| 			# Dependencies: build-deps for netatalk 2.2.4 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
|             sudo apt-get -y install libssl1.0-dev | 			sudo apt-get -y install libssl1.0-dev libssl-dev- | ||||||
|         else # Jessie or Wheezy (libssl-dev 1.0.x) or Buster (absent) | 		else # probably Jessie or Wheezy | ||||||
|             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 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libssl-dev | 			sudo apt-get -y install libssl-dev | ||||||
| 		fi | 		fi | ||||||
|         fi |  | ||||||
|  |  | ||||||
| 		if [[ $(apt-cache search '^libdb5.1-dev$') ]]; then # Wheezy | 		if [[ $(apt-cache search '^libdb5.1-dev$') ]]; then # Wheezy | ||||||
| 			# Dependencies: build-deps for netatalk 2.2.4 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libdb5.1-dev | 			sudo apt-get -y install libdb5.1-dev | ||||||
|         elif [[ $(apt-cache search '^libdb5.3-dev$') ]]; then # Jessie, Stretch, Buster | 		elif [[ $(apt-cache search '^libdb5.3-dev$') ]]; then # Jessie or Stretch | ||||||
| 			# Dependencies: build-deps for netatalk 2.2.4 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libdb5.3-dev | 			sudo apt-get -y install libdb5.3-dev | ||||||
| 		else | 		else | ||||||
| @@ -194,23 +132,14 @@ else | |||||||
| 			# Dependencies: build-deps for netatalk 2.2.4 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libdb-dev | 			sudo apt-get -y install libdb-dev | ||||||
| 		fi | 		fi | ||||||
|          | 		if [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then # Wheezy, Jessie, Stretch | ||||||
|         if [[ $(apt-cache search '^libgcrypt11-dev$') ]]; then # Stretch, Jessie or Wheezy |  | ||||||
| 			# Dependencies: build-deps for netatalk 2.2.4 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install libgcrypt11-dev | 			sudo apt-get -y install libgcrypt11-dev | ||||||
|         elif [[ $(apt-cache search '^libgcrypt20-dev$') ]]; then # Buster |  | ||||||
|             # Dependencies: build-deps for netatalk 2.2.4 |  | ||||||
|             echo "deb http://deb.debian.org/debian/ oldstable main" | sudo tee -a /etc/apt/sources.list > /dev/null |  | ||||||
|             sudo apt-get -y update |  | ||||||
|             sudo apt-get -y install libgcrypt11-dev             |  | ||||||
|             sudo sed -i '$d' /etc/apt/sources.list |  | ||||||
|             sudo apt-get -y update |  | ||||||
| 		else | 		else | ||||||
| 			echo "A2SERVER: WARNING: unknown version of libgcrypt-dev is being installed." | 			echo "A2SERVER: WARNING: unknown version of libgcrypt-dev is being installed." | ||||||
| 			# Dependencies: build-deps for netatalk 2.2.4 | 			# Dependencies: build-deps for netatalk 2.2.4 | ||||||
| 			sudo apt-get -y install $(apt-cache search '^libgcrypt.*dev$' | sort -r | head -1 | cut -d ' ' -f 1) | 			sudo apt-get -y install $(apt-cache search '^libgcrypt.*dev$' | sort -r | head -1 | cut -d ' ' -f 1) | ||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
| 		sudo apt-get clean | 		sudo apt-get clean | ||||||
|  |  | ||||||
| 		# get Netatalk | 		# get Netatalk | ||||||
| @@ -223,7 +152,7 @@ else | |||||||
| 			tar zxf netatalk-2.2.4.tar.gz &> /dev/null | 			tar zxf netatalk-2.2.4.tar.gz &> /dev/null | ||||||
| 		fi | 		fi | ||||||
| 		if [[ ! -d netatalk-2.2.4 ]]; then | 		if [[ ! -d netatalk-2.2.4 ]]; then | ||||||
|             wget -O netatalk-2.2.4.tar.gz "${binaryURL}external/source/netatalk-2.2.4.tar.gz" | 			wget -O netatalk-2.2.4.tar.gz "${a2sBinaryURL}/source/netatalk-2.2.4.tar.gz" | ||||||
| 			tar zxf netatalk-2.2.4.tar.gz &> /dev/null | 			tar zxf netatalk-2.2.4.tar.gz &> /dev/null | ||||||
| 		fi | 		fi | ||||||
| 		cd netatalk-2.2.4 | 		cd netatalk-2.2.4 | ||||||
| @@ -232,6 +161,7 @@ else | |||||||
| 		#	and the AsanteTalk bridge consistently starts up in AppleTalk Phase 2 | 		#	and the AsanteTalk bridge consistently starts up in AppleTalk Phase 2 | ||||||
| 		#	and the Dayna bridge doesn't crash GS/OS | 		#	and the Dayna bridge doesn't crash GS/OS | ||||||
| 		# props to Steven Hirsch for these | 		# props to Steven Hirsch for these | ||||||
|  | 		# FIXME do this as a patch file | ||||||
| 		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 ':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 | 		sed -i 's/rtmp->rt_iface == iface/rtmp->rt_iface != iface/g' etc/atalkd/main.c | ||||||
|  |  | ||||||
| @@ -239,7 +169,9 @@ else | |||||||
| 		./configure --enable-debian --enable-ddp --enable-a2boot | 		./configure --enable-debian --enable-ddp --enable-a2boot | ||||||
|  |  | ||||||
| 		# uninstall Netatalk if already installed | 		# uninstall Netatalk if already installed | ||||||
|         [[ -f /usr/local/sbin/afpd ]] && sudo make uninstall | 		if [[ -f /usr/local/sbin/afpd ]]; then | ||||||
|  | 			sudo make uninstall | ||||||
|  | 		fi | ||||||
|  |  | ||||||
| 		# compile and install Netatalk | 		# compile and install Netatalk | ||||||
| 		make | 		make | ||||||
| @@ -249,14 +181,17 @@ else | |||||||
| 		cd | 		cd | ||||||
| 		rm -rf /tmp/netatalk | 		rm -rf /tmp/netatalk | ||||||
| 	fi | 	fi | ||||||
|  | else | ||||||
|  | 	echo "A2SERVER: Netatalk is already installed." | ||||||
| fi | fi | ||||||
|  | unset a2sVersion | ||||||
|  |  | ||||||
| # --- Install MacIPgw | # --- Install MacIPgw | ||||||
| if ! hash macipgw &> /dev/null; then | if ! hash macipgw &>/dev/null; then | ||||||
| 	echo "A2SERVER: Installing TCP over AppleTalk (MacIP)..." | 	echo "A2SERVER: Installing TCP over AppleTalk (MacIP)..." | ||||||
|  |  | ||||||
| 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||||
|         { wget -qO- "${binaryURL}precompiled/macipgw-${arch}.tgz" | sudo tar Pzx; } 2> /dev/null | 		{ wget -qO- "${a2sBinaryURL}/picopkg/macipgw-${arch}.tgz" | sudo tar Pzx; } 2> /dev/null | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| 	if ! hash macipgw &> /dev/null; then | 	if ! hash macipgw &> /dev/null; then | ||||||
| @@ -265,17 +200,20 @@ if ! hash macipgw &> /dev/null; then | |||||||
| 		rm -rf /tmp/macipgw &> /dev/null | 		rm -rf /tmp/macipgw &> /dev/null | ||||||
| 		mkdir /tmp/macipgw | 		mkdir /tmp/macipgw | ||||||
| 		cd /tmp/macipgw | 		cd /tmp/macipgw | ||||||
|  | 		# macipgw has no releases, so use the hash of HEAD to auto-generate a zipball | ||||||
|  | 		# note: topdir will be macipgw-<full hash>, EEK! | ||||||
|  | 		# note: .tar.gz also works | ||||||
| 		if [[ $useExternalURL ]]; then | 		if [[ $useExternalURL ]]; then | ||||||
|             wget -qO macipgw.zip "https://github.com/zero2sixd/macipgw/archive/2a5f6a7521a627e46b18468d44f4306fb0a7b7ab.zip" | 			wget -qO macipgw.zip "https://github.com/zero2sixd/macipgw/archive/4f77c09.zip" | ||||||
| 			unzip macipgw.zip 2> /dev/null | 			unzip macipgw.zip 2> /dev/null | ||||||
| 			rm macipgw.zip &> /dev/null | 			rm macipgw.zip &> /dev/null | ||||||
| 		fi | 		fi | ||||||
|         if [ ! -d macipgw* ]; then | 		if [[ ! -d macipgw-* ]]; then | ||||||
|             wget -qO macipgw.zip "${binaryURL}external/source/macipgw.zip" | 			wget -qO macipgw.zip "${a2sBinaryURL}/source/macipgw-4f77c09.zip" | ||||||
| 			unzip macipgw.zip 2> /dev/null | 			unzip macipgw.zip 2> /dev/null | ||||||
| 			rm macipgw.zip &> /dev/null | 			rm macipgw.zip &> /dev/null | ||||||
| 		fi | 		fi | ||||||
|         cd macipgw* | 		cd macipgw-* | ||||||
| 		make | 		make | ||||||
| 		sudo make install | 		sudo make install | ||||||
| 		cd "$wd" | 		cd "$wd" | ||||||
| @@ -292,7 +230,7 @@ echo "A2SERVER: Configuring Netatalk..." | |||||||
| # if missing Netatalk startup file, download a fresh one | # if missing Netatalk startup file, download a fresh one | ||||||
| if [ ! -f /etc/init.d/netatalk ]; then | if [ ! -f /etc/init.d/netatalk ]; then | ||||||
| 	echo "A2SERVER: Downloading new Netatalk startup script..." | 	echo "A2SERVER: Downloading new Netatalk startup script..." | ||||||
|     sudo wget -qO /etc/init.d/netatalk ${binaryURL}netatalk-init.d-clean.txt | 	sudo wget -qO /etc/init.d/netatalk "${a2sBinaryURL}/a2server/netatalk-init.d-clean.txt" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # make the Netatalk startup script work correctly | # make the Netatalk startup script work correctly | ||||||
| @@ -301,6 +239,7 @@ sudo sed -i 's/bin\/sh/bin\/bash/' /etc/init.d/netatalk | |||||||
| # enable AppleTalk networking support in Netatalk, and run in background | # 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/#ATALKD_RUN=no/ATALKD_RUN=yes/' /etc/default/netatalk | ||||||
| sudo sed -i 's/#ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk | sudo sed -i 's/#ATALK_BGROUND=no/ATALK_BGROUND=yes/' /etc/default/netatalk | ||||||
|  | # FIXME do this as a patch file | ||||||
| if [[ ! $(grep 'kernelRelease' /etc/init.d/netatalk) ]]; then | if [[ ! $(grep 'kernelRelease' /etc/init.d/netatalk) ]]; then | ||||||
| 	sudo sed -i 's@\(\tif \[ x\"$ATALKD_RUN\)@\n\t# check for valid AppleTalk kernel module\n\t[[ $ATALKD_RUN == "yes" ]] \&\& { kernelRelease=$(uname -r); kernelMajor=$(cut -d "." -f 1  <<< $kernelRelease); kernelMinor=$(cut -d "." -f 2  <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); kernelPatch=$(cut -d "." -f 3- <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); [[ ( $kernelMajor -eq 3 \&\& $kernelMinor -ge 12 \&\& $kernelMinor -le 15 ) \&\& ( ! ( -f /usr/bin/raspi-config \&\& $kernelMinor -eq 12 \&\& $kernelPatch -ge 25 ) ) \&\& ( ( ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ) || $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d " ") != "ecb239fc084c36de93f6926e7749b80f6024f269" ) ]] \&\& { ATALKD_RUN=no; echo "[AppleTalk networking is not available.]" 1>\&2; } }\n\n\1@' /etc/init.d/netatalk | 	sudo sed -i 's@\(\tif \[ x\"$ATALKD_RUN\)@\n\t# check for valid AppleTalk kernel module\n\t[[ $ATALKD_RUN == "yes" ]] \&\& { kernelRelease=$(uname -r); kernelMajor=$(cut -d "." -f 1  <<< $kernelRelease); kernelMinor=$(cut -d "." -f 2  <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); kernelPatch=$(cut -d "." -f 3- <<< $kernelRelease | sed '"'"'s/\\(^[0-9]*\\)[^0-9].*$/\\1/'"'"'); [[ ( $kernelMajor -eq 3 \&\& $kernelMinor -ge 12 \&\& $kernelMinor -le 15 ) \&\& ( ! ( -f /usr/bin/raspi-config \&\& $kernelMinor -eq 12 \&\& $kernelPatch -ge 25 ) ) \&\& ( ( ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ) || $(sha1sum /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko | cut -f 1 -d " ") != "ecb239fc084c36de93f6926e7749b80f6024f269" ) ]] \&\& { ATALKD_RUN=no; echo "[AppleTalk networking is not available.]" 1>\&2; } }\n\n\1@' /etc/init.d/netatalk | ||||||
| fi | fi | ||||||
| @@ -310,6 +249,7 @@ sudo sed -i 's/-n "Restarting Netatalk Daemons (this will take a while)"/"Restar | |||||||
|  |  | ||||||
| # enable MacIPgw support after launching atalkd | # enable MacIPgw support after launching atalkd | ||||||
| if ! grep -q -i 'macipgw' /etc/init.d/netatalk; then | if ! grep -q -i 'macipgw' /etc/init.d/netatalk; then | ||||||
|  | 	# FIXME do this as a patch file | ||||||
| 	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 ':a;N;$!ba;s@\(echo -n " atalkd"\)\(.*# prepare\)@\1\n\n\t\t# start MacIPgw (TCP over AppleTalk) service\n\t\tps aux | grep -q "[m]acipgw" \&\& sudo killall macipgw 2> /dev/null || :\n\t\tatalkd_interface=$(grep "^[^ #]" /etc/netatalk/atalkd.conf | tail -1 | cut -d " " -f 1)\n\t\tsysctl -w net.ipv4.ip_forward=1 > /dev/null\n\t\tmacipgw -n 8.8.8.8 192.168.151.0 255.255.255.0\n\t\t/sbin/iptables -t nat -A POSTROUTING -o ${atalkd_interface} -j MASQUERADE\n\t\t/sbin/iptables -A FORWARD -i ${atalkd_interface} -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n\t\t/sbin/iptables -A FORWARD -i tun1 -o ${atalkd_interface} -j ACCEPT\n\n\t\techo -n " macipgw"\n\2@' /etc/init.d/netatalk | ||||||
| 	sudo sed -i 's@\(start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd.*$\)@\1\n					  echo -n " macipgw"\n			  sudo killall macipgw 2> /dev/null@' /etc/init.d/netatalk | 	sudo sed -i 's@\(start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd.*$\)@\1\n					  echo -n " macipgw"\n			  sudo killall macipgw 2> /dev/null@' /etc/init.d/netatalk | ||||||
| fi | fi | ||||||
| @@ -334,12 +274,13 @@ sudo sed -i "s/#AFPD_GUEST=nobody/AFPD_GUEST=$USER/" /etc/default/netatalk | |||||||
| if [[ ! $(grep '^- -ddp.*uams_randnum.so' /usr/local/etc/netatalk/afpd.conf) ]]; then | if [[ ! $(grep '^- -ddp.*uams_randnum.so' /usr/local/etc/netatalk/afpd.conf) ]]; then | ||||||
| 	# set up to allow Guest, Cleartext, RandNum, DHX, and DHX2 login | 	# 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 | 	# 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," | 	dhx= | ||||||
|     echo -n -e \ | 	if [[ ! -f /usr/bin/raspi-config ]]; then | ||||||
|     "- -ddp -tcp -uamlist uams_guest.so,uams_clrtxt.so,uams_randnum.so" \ | 		dhx="uams_dhx.so," | ||||||
|     | sudo tee -a /usr/local/etc/netatalk/afpd.conf > /dev/null | 	fi | ||||||
|     echo -e ",${dhx}uams_dhx2.so" \ | 	sudo tee -a /usr/local/etc/netatalk/afpd.conf >/dev/null <<EOF | ||||||
|     | sudo tee -a /usr/local/etc/netatalk/afpd.conf > /dev/null | - -ddp -tcp -uamlist uams_guest.so,uams_clrtxt.so,uams_randnum.so",${dhx}uams_dhx2.so | ||||||
|  | EOF | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # replace home folder share and end of file mark with share placeholders | # replace home folder share and end of file mark with share placeholders | ||||||
| @@ -350,7 +291,6 @@ sudo sed -i 's/^~/#share1\n\n#share2/' \ | |||||||
| sudo sed -i 's/^:DEFAULT/#:DEFAULT/' \ | sudo sed -i 's/^:DEFAULT/#:DEFAULT/' \ | ||||||
| /usr/local/etc/netatalk/AppleVolumes.default | /usr/local/etc/netatalk/AppleVolumes.default | ||||||
|  |  | ||||||
| # if [[ ! $(grep ^eth0 /usr/local/etc/netatalk/atalkd.conf) && ! $(grep ^wlan0 /usr/local/etc/netatalk/atalkd.conf) ]]; then |  | ||||||
| if [[ $(tac /usr/local/etc/netatalk/atalkd.conf | sed '/./,$!d' | head -1 | cut -c 1) == "#" ]]; then | if [[ $(tac /usr/local/etc/netatalk/atalkd.conf | sed '/./,$!d' | head -1 | cut -c 1) == "#" ]]; then | ||||||
| 	# enable netatalk on the default network interface | 	# enable netatalk on the default network interface | ||||||
| 	# needs -router and -zone to prevent GS/OS AppleShare CDEV crash when used | 	# needs -router and -zone to prevent GS/OS AppleShare CDEV crash when used | ||||||
| @@ -362,6 +302,7 @@ fi | |||||||
| if [[ $isRpi ]]; then | if [[ $isRpi ]]; then | ||||||
| 	# blink LED upon netatalk startup | 	# blink LED upon netatalk startup | ||||||
| 	if [[ ! $(grep 'led0' /etc/init.d/netatalk) ]]; then | 	if [[ ! $(grep 'led0' /etc/init.d/netatalk) ]]; then | ||||||
|  | 		# FIXME Do this ... readably. | ||||||
| 		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 | 		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 | 	fi | ||||||
| fi | fi | ||||||
| @@ -375,7 +316,7 @@ fi | |||||||
|  |  | ||||||
| # 1.3.0: if GSFILES is being shared, make directory if not there | # 1.3.0: if GSFILES is being shared, make directory if not there | ||||||
| if grep -q '^/srv/A2SERVER/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then | if grep -q '^/srv/A2SERVER/GSFILES' /usr/local/etc/netatalk/AppleVolumes.default; then | ||||||
|     [[ -d /srv/A2SERVER/GSFILES ]] || mkdir -p /srv/A2SERVER/GSFILES; | 	mkdir -p /srv/A2SERVER/GSFILES | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # prior to 1.3.0: | # prior to 1.3.0: | ||||||
| @@ -398,7 +339,7 @@ if [[ -d /srv/A2SERVER/A2FILES && ! -d /srv/A2SERVER/.a2files ]]; then | |||||||
| 	fi | 	fi | ||||||
| 	rm /srv/A2SERVER/A2FILES/.APPLEDESKTOP 2> /dev/null | 	rm /srv/A2SERVER/A2FILES/.APPLEDESKTOP 2> /dev/null | ||||||
| 	mkdir -p /tmp/netboot | 	mkdir -p /tmp/netboot | ||||||
|     wget -qO /tmp/A2FILES-list.txt ${binaryURL}A2FILES-list.txt | 	wget -qO /tmp/A2FILES-list.txt "${a2sBinaryURL}/a2server/A2FILES-list.txt" | ||||||
| 	find /srv/A2SERVER/A2FILES -name '*' | tail -n +2 | tac > /tmp/filelist.txt | 	find /srv/A2SERVER/A2FILES -name '*' | tail -n +2 | tac > /tmp/filelist.txt | ||||||
| 	while read thisFile; do | 	while read thisFile; do | ||||||
| 		mixedCase="${thisFile##*/}" | 		mixedCase="${thisFile##*/}" | ||||||
| @@ -440,8 +381,8 @@ fi | |||||||
| sudo sed -i \ | sudo sed -i \ | ||||||
| 	's/^#share2/\/srv\/A2SERVER\/A2FILES\ A2FILES options:prodos\ ea:ad/' \ | 	's/^#share2/\/srv\/A2SERVER\/A2FILES\ A2FILES options:prodos\ ea:ad/' \ | ||||||
| 		/usr/local/etc/netatalk/AppleVolumes.default | 		/usr/local/etc/netatalk/AppleVolumes.default | ||||||
| [[ -d /srv/A2SERVER/A2FILES ]] || mkdir -p /srv/A2SERVER/A2FILES | mkdir -p /srv/A2SERVER/A2FILES | ||||||
| [[ -d /srv/A2SERVER/.a2files ]] || mkdir -p /srv/A2SERVER/.a2files | mkdir -p /srv/A2SERVER/.a2files | ||||||
|  |  | ||||||
| # set up ciopfs | # set up ciopfs | ||||||
| if ! hash ciopfs &> /dev/null; then | if ! hash ciopfs &> /dev/null; then | ||||||
| @@ -451,7 +392,7 @@ if ! hash ciopfs &> /dev/null; then | |||||||
| 	# Dependency: For ciopfs | 	# Dependency: For ciopfs | ||||||
| 	sudo apt-get -y install fuse libglib2.0-0 libattr1 libfuse2 | 	sudo apt-get -y install fuse libglib2.0-0 libattr1 libfuse2 | ||||||
| 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||||
|         { wget -qO- "${binaryURL}precompiled/ciopfs-${arch}.tgz" | sudo tar Pzx; } &> /dev/null | 		{ wget -qO- "${a2sBinaryURL}/pickpkg/ciopfs-${arch}.tgz" | sudo tar Pzx; } &> /dev/null | ||||||
| 	fi | 	fi | ||||||
| 	if [[ -f /etc/fuse.conf ]] && sudo grep -q user_allow_other /etc/fuse.conf; then | 	if [[ -f /etc/fuse.conf ]] && sudo grep -q user_allow_other /etc/fuse.conf; then | ||||||
| 		sudo sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf | 		sudo sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf | ||||||
| @@ -475,17 +416,15 @@ if ! hash ciopfs &> /dev/null; then | |||||||
| 		mkdir /tmp/ciopfs | 		mkdir /tmp/ciopfs | ||||||
| 		cd /tmp/ciopfs | 		cd /tmp/ciopfs | ||||||
| 		if [[ $useExternalURL ]]; then | 		if [[ $useExternalURL ]]; then | ||||||
|             wget -q -O ciopfs-0.4.tar.gz http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz | 			wget -q -O ciopfs-0.4.tar.gz "http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz" | ||||||
| 			if (( $? != 0 )); then | 			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 | 				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 | 			fi | ||||||
| 			tar zxf ciopfs-0.4.tar.gz &> /dev/null | 			tar zxf ciopfs-0.4.tar.gz &> /dev/null | ||||||
|             rm ciopfs-0.4.tar.gz &> /dev/null |  | ||||||
| 		fi | 		fi | ||||||
| 		if [ ! -f ciopfs*/ciopfs.c ]; then # single brackets required for glob | 		if [ ! -f ciopfs*/ciopfs.c ]; then # single brackets required for glob | ||||||
|             wget -q -O ciopfs-0.4.tar.gz ${binaryURL}external/source/ciopfs-0.4.tar.gz | 			wget -q -O ciopfs-0.4.tar.gz "${a2sBinaryURL}/source/ciopfs-0.4.tar.gz" | ||||||
| 			tar zxf ciopfs-0.4.tar.gz &> /dev/null | 			tar zxf ciopfs-0.4.tar.gz &> /dev/null | ||||||
|             rm ciopfs-0.4.tar.gz &> ?dev/null |  | ||||||
| 		fi | 		fi | ||||||
| 		cd ciopfs* | 		cd ciopfs* | ||||||
| 		make | 		make | ||||||
| @@ -494,6 +433,9 @@ if ! hash ciopfs &> /dev/null; then | |||||||
| 		rm -rf /tmp/ciopfs | 		rm -rf /tmp/ciopfs | ||||||
| 	fi | 	fi | ||||||
| 	if ! grep -q '^ciopfs' /etc/fstab; then | 	if ! grep -q '^ciopfs' /etc/fstab; then | ||||||
|  | 		# http://www.brain-dump.org/projects/ciopfs/ recommends: | ||||||
|  | 		# /data/projects/ciopfs/data /data/projects/ciopfs/mnt ciopfs allow_other,default_permissions,use_ino,attr_timeout=0 0 0 | ||||||
|  | 		# Really should check the docs on that | ||||||
| 		echo "ciopfs#/srv/A2SERVER/.a2files /srv/A2SERVER/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 | 	fi | ||||||
| 	if ! mount | grep '^ciopfs.*A2FILES'; then | 	if ! mount | grep '^ciopfs.*A2FILES'; then | ||||||
| @@ -589,9 +531,9 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]]; | |||||||
|  |  | ||||||
| 	sudo mv /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko /tmp 2> /dev/null | 	sudo mv /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko /tmp 2> /dev/null | ||||||
|  |  | ||||||
|     if [[ ! $compileFromSource && ${arch%_*} == "debian" ]]; then | 	if [[ ${arch%_*} == "debian" ]]; then | ||||||
| 		echo "A2SERVER: Fetching AppleTalk kernel module for Debian..." | 		echo "A2SERVER: Fetching AppleTalk kernel module for Debian..." | ||||||
|         wget -qO /tmp/appletalk.tgz ${binaryURL}precompiled/appletalk-$kernelRelease-${arch}.tgz | 		wget -qO /tmp/appletalk.tgz "${a2sBinaryURL}/picopkg/appletalk-${kernelRelease}-${arch}.tgz" | ||||||
| 		if [[ $? -eq 0 ]]; then | 		if [[ $? -eq 0 ]]; then | ||||||
| 			# if we found a prebuilt one on a2server site, install it and load it | 			# if we found a prebuilt one on a2server site, install it and load it | ||||||
| 			sudo tar Pxf /tmp/appletalk.tgz &> /dev/null | 			sudo tar Pxf /tmp/appletalk.tgz &> /dev/null | ||||||
| @@ -602,12 +544,10 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]]; | |||||||
| 				sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk | 				sudo sed -i "s/ATALKD_RUN=no/ATALKD_RUN=yes/" /etc/default/netatalk | ||||||
| 				sudo /etc/init.d/netatalk restart &> /dev/null | 				sudo /etc/init.d/netatalk restart &> /dev/null | ||||||
| 			else | 			else | ||||||
|                 echo "A2SERVER: failed to load AppleTalk kernel module" |  | ||||||
| 				# if we didn't load it successfully, remove it | 				# if we didn't load it successfully, remove it | ||||||
| 				sudo rm /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko 2> /dev/null | 				sudo rm /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko 2> /dev/null | ||||||
|  | 				echo "A2SERVER: failed to load AppleTalk kernel module" | ||||||
| 			fi | 			fi | ||||||
|         else # download failed, so premade kernel not found, remove empty file |  | ||||||
|             rm /tmp/appletalk.tgz 2>/dev/null |  | ||||||
| 		fi | 		fi | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| @@ -625,7 +565,6 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]]; | |||||||
| 			[[ -f /boot/config-$kernelRelease ]] || break | 			[[ -f /boot/config-$kernelRelease ]] || break | ||||||
| 			sudo apt-get -y install linux-headers-$kernelRelease linux-source-$kernelMajorMinor || break | 			sudo apt-get -y install linux-headers-$kernelRelease linux-source-$kernelMajorMinor || break | ||||||
| 			sudo apt-get -y install build-essential | 			sudo apt-get -y install build-essential | ||||||
|             sudo apt-get -y install libelf-dev # required as of kernel 4.14.12, apparently |  | ||||||
| 			cd /usr/src | 			cd /usr/src | ||||||
| 			kernelSrc=$(find linux-source-${kernelMajorMinor}*) | 			kernelSrc=$(find linux-source-${kernelMajorMinor}*) | ||||||
| 			if [[ ${kernelSrc##*.} == "xz" ]]; then | 			if [[ ${kernelSrc##*.} == "xz" ]]; then | ||||||
| @@ -656,7 +595,6 @@ if [[ -f "/lib/modules/$kernelRelease/kernel/drivers/net/appletalk/ipddp.ko" ]]; | |||||||
| 			sudo rm /usr/src/$kernelSrc | 			sudo rm /usr/src/$kernelSrc | ||||||
| 			sudo rm -r /usr/src/linux-source-$kernelMajorMinor | 			sudo rm -r /usr/src/linux-source-$kernelMajorMinor | ||||||
| 			sudo apt-get -y purge linux-source-$kernelMajorMinor | 			sudo apt-get -y purge linux-source-$kernelMajorMinor | ||||||
|             sudo apt -y autoremove |  | ||||||
| 		done | 		done | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| @@ -690,7 +628,7 @@ echo "A2SERVER: Netatalk is installed, configured, and running." | |||||||
| echo | echo | ||||||
|  |  | ||||||
| # if atalkd isn't running (no AppleTalk), and this is a Rasbperry Pi: | # if atalkd isn't running (no AppleTalk), and this is a Rasbperry Pi: | ||||||
| if [[ ( ! $(ps aux | grep [a]talkd) ) && ( $isRpi ) ]]; then     | if [[ ( ! $(pgrep atalkd) ) && $isRpi ]]; then | ||||||
|  |  | ||||||
| 	# if AppleTalk module exists, try to load it | 	# if AppleTalk module exists, try to load it | ||||||
| 	if [[ -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # module present, but not loaded? | 	if [[ -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # module present, but not loaded? | ||||||
| @@ -708,7 +646,7 @@ if [[ ( ! $(ps aux | grep [a]talkd) ) && ( $isRpi ) ]]; then | |||||||
| 	# if no AppleTalk module, try to download it from a2server site | 	# if no AppleTalk module, try to download it from a2server site | ||||||
| 	if [[ ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # check for rpi kernel module | 	if [[ ! -f /lib/modules/$kernelRelease/kernel/net/appletalk/appletalk.ko ]]; then # check for rpi kernel module | ||||||
| 		echo "A2SERVER: Installing AppleTalk kernel module for Raspbian..." | 		echo "A2SERVER: Installing AppleTalk kernel module for Raspbian..." | ||||||
|         wget -qO /tmp/appletalk.ko.gz ${binaryURL}appletalk-$kernelRelease-rpi.ko.gz | 		wget -qO /tmp/appletalk.ko.gz "${a2sBinaryURL}/picopkg/appletalk-${kernelRelease}-rpi.ko.gz" | ||||||
| 		if [[ $? -eq 0 ]]; then | 		if [[ $? -eq 0 ]]; then | ||||||
| 			# if we found a prebuilt one on a2server site, install it and load it | 			# if we found a prebuilt one on a2server site, install it and load it | ||||||
| 			gunzip -f /tmp/appletalk.ko.gz &> /dev/null | 			gunzip -f /tmp/appletalk.ko.gz &> /dev/null | ||||||
| @@ -779,6 +717,21 @@ if [[ ! $(dpkg -l avahi-daemon 2> /dev/null | grep ^ii) || ! $(dpkg -l libnss-md | |||||||
| fi | fi | ||||||
| sudo sed -i 's/^\(hosts.*\)$/\1 mdns/' /etc/nsswitch.conf | 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 | 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 | 	sudo tee /etc/avahi/services/afpd.service >/dev/null <<EOF | ||||||
|  | <?xml version="1.0" standalone="no"?><!--*-nxml-*--> | ||||||
|  | <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> | ||||||
|  | <service-group> | ||||||
|  | <name replace-wildcards="yes">%h</name> | ||||||
|  |   <service> | ||||||
|  |     <type>_afpovertcp._tcp</type> | ||||||
|  |     <port>548</port> | ||||||
|  |   </service> | ||||||
|  |     <service> | ||||||
|  |     <type>_device-info._tcp</type> | ||||||
|  |     <port>0</port> | ||||||
|  |     <txt-record>model=MacPro</txt-record> | ||||||
|  |   </service> | ||||||
|  | </service-group> | ||||||
|  | EOF | ||||||
| fi | fi | ||||||
| sudo /etc/init.d/avahi-daemon restart &> /dev/null | sudo /etc/init.d/avahi-daemon restart &> /dev/null | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # this script downloads and installs the Apple boot blocks required | # this script downloads and installs the Apple boot blocks required | ||||||
| # for booting an Apple II client over the network, and places | # for booting an Apple II client over the network, and places | ||||||
| @@ -7,15 +7,19 @@ | |||||||
| # program (for Apple IIe users, and IIgs users in ProDOS network mode). | # 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. | # It also can download and install GS/OS for a network boot configuration. | ||||||
|  |  | ||||||
| # Ensure URL we'll use ends in a / | a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/master" | ||||||
| case "$A2SERVER_SCRIPT_URL" in | a2sBinaryURL="http://blocksfree.com/downloads" | ||||||
|     */) scriptURL="$A2SERVER_SCRIPT_URL" ;; |  | ||||||
|     *) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | # Find the path of our source directory | ||||||
| esac | a2sSource="$( dirname "${BASH_SOURCE[0]}" )/.." | ||||||
| case "$A2SERVER_BINARY_URL" in | pushd $a2sSource >/dev/null | ||||||
|     */) binaryURL="$A2SERVER_BINARY_URL" ;; | a2sSource="$PWD" | ||||||
|     *) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;; | popd >/dev/null | ||||||
| esac | if [[ ! -f "$a2sSource/.a2server_source" ]]; then | ||||||
|  | 	printf "\na2server: cannot find a2server source directory in $a2sSource.\n\n" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| useExternalURL=1 | useExternalURL=1 | ||||||
| [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | ||||||
|  |  | ||||||
| @@ -149,27 +153,30 @@ updateP8YearTables () { | |||||||
| 	else | 	else | ||||||
| 		# perform patch | 		# perform patch | ||||||
| 		while (( $i < ${#files[@]} )); do | 		while (( $i < ${#files[@]} )); do | ||||||
|             [[ ! -f "${files[$i]}" ]] && { (( i++ )); continue; } | 			if [[ ! -f "${files[$i]}" ]]; then | ||||||
|             [[ $patch1 ]] && echo -n -e ${patch1} | sudo dd of="${files[$i]}" seek=${offset1[$i]} bs=1 conv=notrunc 2> /dev/null | 				(( i++ )) | ||||||
|             [[ $patch2 ]] && echo -n -e ${patch2} | sudo dd of="${files[$i]}" seek=${offset2[$i]} bs=1 conv=notrunc 2> /dev/null | 				continue | ||||||
|  | 			fi | ||||||
|  | 			if [[ $patch1 ]]; then | ||||||
|  | 				echo -n -e ${patch1} | sudo dd of="${files[$i]}" seek=${offset1[$i]} bs=1 conv=notrunc 2>/dev/null | ||||||
|  | 			fi | ||||||
|  | 			if [[ $patch2 ]]; then | ||||||
|  | 				echo -n -e ${patch2} | sudo dd of="${files[$i]}" seek=${offset2[$i]} bs=1 conv=notrunc 2>/dev/null | ||||||
|  | 			fi | ||||||
| 			(( i++ )) | 			(( i++ )) | ||||||
| 		done | 		done | ||||||
| 		patched=0 # 0 is true | 		patched=0 # 0 is true | ||||||
| 	fi | 	fi | ||||||
| 	return $patched | 	return $patched | ||||||
|  |  | ||||||
|     # echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="p8" bs=38 seek=1 conv=notrunc 2> /dev/null |  | ||||||
|     # echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="p8" bs=3958 seek=1 conv=notrunc 2> /dev/null |  | ||||||
|     # echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="ProDOS16 Image" bs=3110 seek=1 conv=notrunc 2> /dev/null |  | ||||||
|     # echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="ProDOS16 Image" bs=7030 seek=1 conv=notrunc 2> /dev/null |  | ||||||
|     # echo -n -e "\xb0\xb2\xad\xc1\xf5\xe7\xad\xb1\xb5" | sudo dd of="Apple :2f:2fe Boot Blocks" bs=79 seek=1 conv=notrunc 2> /dev/null |  | ||||||
|     # echo -n -e "\x12\x11\x0b\x10\x0f\x0e\x0d" | sudo dd of="Apple :2f:2fe Boot Blocks" bs=7071 seek=1 conv=notrunc 2> /dev/null |  | ||||||
|  |  | ||||||
| 	cd "$wd" | 	cd "$wd" | ||||||
| } | } | ||||||
|  |  | ||||||
| # bail out on automated netboot setup unless -b is also specified | # bail out on automated netboot setup unless -b is also specified | ||||||
| [[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes= | autoAnswerYes= | ||||||
|  | if [[ -f /tmp/a2server-autoAnswerYes ]]; then | ||||||
|  | 	autoAnswerYes=1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| netbootInstalled= | netbootInstalled= | ||||||
| if [[ -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Boot\ Blocks && \ | if [[ -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Boot\ Blocks && \ | ||||||
| @@ -213,15 +220,15 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 			cd /tmp/netboot | 			cd /tmp/netboot | ||||||
|  |  | ||||||
| 			if [[ $useExternalURL ]]; then | 			if [[ $useExternalURL ]]; then | ||||||
|                 wget --max-redirect 0 -qO Disk_7_of_7-Apple_II_Setup.sea.bin ${gsosURL}Disk_7_of_7-Apple_II_Setup.sea.bin | 				wget --max-redirect 0 -qO Disk_7_of_7-Apple_II_Setup.sea.bin "${gsosURL}Disk_7_of_7-Apple_II_Setup.sea.bin" | ||||||
| 				unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null | 				unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null | ||||||
| 				if (( $? != 0 )); then | 				if (( $? != 0 )); then | ||||||
|                     wget -qO Disk_7_of_7-Apple_II_Setup.sea.bin ${gsosBackupURL}Disk_7_of_7-Apple_II_Setup.sea.bin | 					wget -qO Disk_7_of_7-Apple_II_Setup.sea.bin "${gsosBackupURL}Disk_7_of_7-Apple_II_Setup.sea.bin" | ||||||
| 					unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null | 					unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 			fi | 			fi | ||||||
| 			if [[ ! -f 'Disk 7 of 7-Apple II Setup.sea' ]]; then | 			if [[ ! -f 'Disk 7 of 7-Apple II Setup.sea' ]]; then | ||||||
|                 wget -qO Disk_7_of_7-Apple_II_Setup.sea.bin ${binaryURL}external/appleii/gsos601/Disk_7_of_7-Apple_II_Setup.sea.bin | 				wget -qO Disk_7_of_7-Apple_II_Setup.sea.bin "${a2sBinaryURL}/appleii/gsos601/Disk_7_of_7-Apple_II_Setup.sea.bin" | ||||||
| 				unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null | 				unar -k skip Disk_7_of_7-Apple_II_Setup.sea.bin &> /dev/null | ||||||
| 			fi | 			fi | ||||||
| 			truncate -s 819284 'Disk 7 of 7-Apple II Setup.sea' | 			truncate -s 819284 'Disk 7 of 7-Apple II Setup.sea' | ||||||
| @@ -256,11 +263,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 		|| [[ ! -f /usr/local/bin/mkvolinfo ]] \ | 		|| [[ ! -f /usr/local/bin/mkvolinfo ]] \ | ||||||
| 		|| [[ ! -f /usr/local/bin/afpsync ]] \ | 		|| [[ ! -f /usr/local/bin/afpsync ]] \ | ||||||
| 		|| [[ ! -f /usr/local/bin/cppo ]]; then | 		|| [[ ! -f /usr/local/bin/cppo ]]; then | ||||||
|             rm /tmp/2.tools &> /dev/null | 			"$a2sSource/scripts/a2server-2-tools.txt" | ||||||
|             wget -q -O /tmp/2.tools "${scriptURL}scripts/a2server-2-tools.txt" |  | ||||||
|             chmod ugo+x /tmp/2.tools |  | ||||||
|             /tmp/2.tools |  | ||||||
|             rm /tmp/2.tools |  | ||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
| 		# put BASIC.SYSTEM at root for ProDOS 8 startup | 		# put BASIC.SYSTEM at root for ProDOS 8 startup | ||||||
| @@ -393,8 +396,8 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 				fi | 				fi | ||||||
|  |  | ||||||
| 				# delete previously downloaded installer | 				# delete previously downloaded installer | ||||||
|                 rm "$imagesDir/* $imagesDir/.AppleDouble"/* 2> /dev/null | 				rm -f "$imagesDir/* $imagesDir/.AppleDouble"/* | ||||||
|                 rm "$netInstallDir/* $netInstallDir/.AppleDouble"/* 2> /dev/null | 				rm -f "$netInstallDir/* $netInstallDir/.AppleDouble"/* | ||||||
| 				afpsync -v $gsosDir > /dev/null | 				afpsync -v $gsosDir > /dev/null | ||||||
|  |  | ||||||
| 				for diskname in ${diskNames[@]}; do | 				for diskname in ${diskNames[@]}; do | ||||||
| @@ -411,7 +414,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 							fi | 							fi | ||||||
| 						fi | 						fi | ||||||
| 						if [[ ! -f "Disk ${activeDisk} of 7-${diskname}.sea" ]]; then | 						if [[ ! -f "Disk ${activeDisk} of 7-${diskname}.sea" ]]; then | ||||||
|                             wget -qO "Disk_${activeDisk}_of_7-${diskname}.sea.bin" "${binaryURL}external/appleii/gsos601/Disk_${activeDisk}_of_7-${diskname}.sea.bin" | 							wget -qO "Disk_${activeDisk}_of_7-${diskname}.sea.bin" "${a2sBinaryURL}/appleii/gsos601/Disk_${activeDisk}_of_7-${diskname}.sea.bin" | ||||||
| 							unar -k skip "Disk_${activeDisk}_of_7-${diskname}.sea.bin" &> /dev/null | 							unar -k skip "Disk_${activeDisk}_of_7-${diskname}.sea.bin" &> /dev/null | ||||||
| 						fi | 						fi | ||||||
| 						truncate -s 819284 "Disk ${activeDisk} of 7-${diskname}.sea" | 						truncate -s 819284 "Disk ${activeDisk} of 7-${diskname}.sea" | ||||||
| @@ -421,14 +424,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 							wget -qO $outfile "$gsosURL/IIGS%20System%206.0.2%20-%20Disk%20${activeDisk}%20${diskWebNames[$activeDisk-1]}.po" | 							wget -qO $outfile "$gsosURL/IIGS%20System%206.0.2%20-%20Disk%20${activeDisk}%20${diskWebNames[$activeDisk-1]}.po" | ||||||
| 						fi | 						fi | ||||||
| 						if [[ $? -ne 0 || ! -f $outfile ]]; then | 						if [[ $? -ne 0 || ! -f $outfile ]]; then | ||||||
|                             wget -qO $outfile "${binaryURL}external/appleii/gsos602/$diskname.po" | 							wget -qO $outfile "${a2sBinaryURL}/appleii/gsos602/$diskname.po" | ||||||
| 						fi | 						fi | ||||||
| 					elif (( $gsosInstall == 3 )); then | 					elif (( $gsosInstall == 3 )); then | ||||||
| 						if [[ $useExternalURL ]]; then | 						if [[ $useExternalURL ]]; then | ||||||
| 							wget -qO $outfile "$gsosURL/$diskname.po" | 							wget -qO $outfile "$gsosURL/$diskname.po" | ||||||
| 						fi | 						fi | ||||||
| 						if [[ $? -ne 0 || ! -f $outfile ]]; then | 						if [[ $? -ne 0 || ! -f $outfile ]]; then | ||||||
|                             wget -qO $outfile "${binaryURL}external/appleii/gsos603/$diskname.po" | 							wget -qO $outfile "${a2sBinaryURL}/appleii/gsos603/$diskname.po" | ||||||
| 						fi | 						fi | ||||||
| 					fi | 					fi | ||||||
| 					cppo -s -ad $outfile $netInstallDir | 					cppo -s -ad $outfile $netInstallDir | ||||||
| @@ -456,7 +459,9 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 						# echo $entryIndex $entryCount ${scriptEntry[@]} | 						# echo $entryIndex $entryCount ${scriptEntry[@]} | ||||||
| 						action=${scriptEntry[1]:0:1} | 						action=${scriptEntry[1]:0:1} | ||||||
| 						sourcePathMixed=$(tr ':' '/' <<<  ${scriptEntry[5]}) | 						sourcePathMixed=$(tr ':' '/' <<<  ${scriptEntry[5]}) | ||||||
|                         [[ ${sourcePathMixed:0:1} != '/' ]] && sourcePathMixed="${pathPrefix}/$sourcePathMixed" | 						if [[ ${sourcePathMixed:0:1} != '/' ]]; then | ||||||
|  | 							sourcePathMixed="${pathPrefix}/$sourcePathMixed" | ||||||
|  | 						fi | ||||||
| 						sourcePath=$sourcePathMixed | 						sourcePath=$sourcePathMixed | ||||||
| 						targetPath=$gsosDir/$(tr ':' '/' <<< ${scriptEntry[6]}) | 						targetPath=$gsosDir/$(tr ':' '/' <<< ${scriptEntry[6]}) | ||||||
| 						# volumeName=$(cut -d/ -f 2 <<< $sourcePath) | 						# volumeName=$(cut -d/ -f 2 <<< $sourcePath) | ||||||
| @@ -470,15 +475,15 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 							echo "copying: $sourcePathMixed" | 							echo "copying: $sourcePathMixed" | ||||||
| 							echo "     to: $targetPath" | 							echo "     to: $targetPath" | ||||||
| 							echo | 							echo | ||||||
|                             [[ ! -d $targetParent ]] && mkdir -p $targetParent | 							mkdir -p $targetParent | ||||||
| 							cp -p ${gsosDir%/*}$sourcePath $targetPath | 							cp -p ${gsosDir%/*}$sourcePath $targetPath | ||||||
|                             [[ ! -d $targetParent/.AppleDouble ]] && mkdir -p $targetParent/.AppleDouble | 							mkdir -p $targetParent/.AppleDouble | ||||||
| 							cp -p ${gsosDir%/*}$sourceParent/.AppleDouble/$sourceFile $targetParent/.AppleDouble/$targetFile | 							cp -p ${gsosDir%/*}$sourceParent/.AppleDouble/$sourceFile $targetParent/.AppleDouble/$targetFile | ||||||
| 						elif [[ $action == 3 || $action == 4 ]]; then | 						elif [[ $action == 3 || $action == 4 ]]; then | ||||||
| 							if [[ -f "$targetPath" ]]; then | 							if [[ -f "$targetPath" ]]; then | ||||||
| 								echo "deleting $targetPath" | 								echo "deleting $targetPath" | ||||||
|                                 rm "$targetPath" | 								rm -f "$targetPath" | ||||||
|                                 [[ -f $targetParent/.AppleDouble/$targetFile ]] && rm "$targetParent/.AppleDouble/$targetFile" | 								rm -f "$targetParent/.AppleDouble/$targetFile" | ||||||
| 							fi | 							fi | ||||||
| 						fi | 						fi | ||||||
| 						(( entryIndex++ )) | 						(( entryIndex++ )) | ||||||
| @@ -512,34 +517,35 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 			fi | 			fi | ||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
|         # if [[ ! $autoAnswerYes && (! $gsosInstall || $gsosInstall -lt 2) ]] && ! checkP8YearTables 603; then |  | ||||||
|         #     echo |  | ||||||
|         #     echo -n "Do you want to update the ProDOS 8 Thunderclock year table? " |  | ||||||
|         #     read |  | ||||||
|         # fi |  | ||||||
|         # if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then |  | ||||||
|         #    updateP8YearTables 603 |  | ||||||
|         # elif [[ $gsosInstall -ge 2 ]]; then |  | ||||||
|         #    updateP8YearTables 60${gsosInstall} |  | ||||||
|         # fi |  | ||||||
|  |  | ||||||
| 		# patch ProDOS 8 Thunderclock driver year table based on today's date | 		# patch ProDOS 8 Thunderclock driver year table based on today's date | ||||||
| 		echo | 		echo | ||||||
| 		echo "A2SERVER: Updating ProDOS 8 Thunderclock driver year table..." | 		echo "A2SERVER: Updating ProDOS 8 Thunderclock driver year table..." | ||||||
| 		mkdir -p /tmp/netboot | 		mkdir -p /tmp/netboot | ||||||
| 		rm -r /tmp/netboot/* 2> /dev/null | 		rm -r /tmp/netboot/* 2> /dev/null | ||||||
|         wget -qO /tmp/netboot/clock.patch.py "${scriptURL}scripts/clock.patch.py" | 		p8ClockPatch="$a2sSource/scripts/clock.patch.py" | ||||||
|         updateP8YearTables $(python /tmp/netboot/clock.patch.py $(LANG=C date +"%a %m/%d/%y")) | 		updateP8YearTables $(python $p8ClockPatch $(LANG=C date +"%a %m/%d/%y")) | ||||||
|  |  | ||||||
| 		gsosInstalled="" | 		gsosInstalled="" | ||||||
|         [[ -f "$gsosDir/System/Start.GS.OS" ]] && gsosInstalled="GS/OS and " | 		if [[ -f "$gsosDir/System/Start.GS.OS" ]]; then | ||||||
|  | 			gsosInstalled="GS/OS and " | ||||||
|  | 		fi | ||||||
| 		p8ToolsInstalled= | 		p8ToolsInstalled= | ||||||
|         [[ -f $diskToolsP8Dir/SHRINKIT && -f $diskToolsP8Dir/DSK2FILE && -f $diskToolsP8Dir/SYSUTIL ]] && p8ToolsInstalled=1 | 		if [[ -f $diskToolsP8Dir/SHRINKIT && \ | ||||||
|  | 				-f $diskToolsP8Dir/DSK2FILE && \ | ||||||
|  | 				-f $diskToolsP8Dir/SYSUTIL ]]; then | ||||||
|  | 			p8ToolsInstalled=1 | ||||||
|  | 		fi | ||||||
| 		gsosToolsInstalled= | 		gsosToolsInstalled= | ||||||
|         [[ -f $imageToolsDir/Asimov && -f $gsosDir/System/System.Setup/MountIt && -f $imageToolsDir/GSHK ]] && gsosToolsInstalled=1 | 		if [[ -f $imageToolsDir/Asimov && \ | ||||||
|  | 				-f $gsosDir/System/System.Setup/MountIt && \ | ||||||
|  | 				-f $imageToolsDir/GSHK ]]; then | ||||||
|  | 			gsosToolsInstalled=1 | ||||||
|  | 		fi | ||||||
| 		toolsInstalled= | 		toolsInstalled= | ||||||
| 		if [[ $gsosInstalled ]]; then | 		if [[ $gsosInstalled ]]; then | ||||||
|             [[ $gsosToolsInstalled && $p8ToolsInstalled ]] && toolsInstalled=1 | 			if [[ $gsosToolsInstalled && $p8ToolsInstalled ]]; then | ||||||
|  | 				toolsInstalled=1 | ||||||
|  | 			fi | ||||||
| 		else | 		else | ||||||
| 			toolsInstalled=$p8ToolsInstalled | 			toolsInstalled=$p8ToolsInstalled | ||||||
| 		fi | 		fi | ||||||
| @@ -570,14 +576,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					echo | 					echo | ||||||
| 					cd /tmp/netboot | 					cd /tmp/netboot | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO Asimov.shk http://www.ninjaforce.com/downloads/Asimov.shk | 						wget -qO Asimov.shk "http://www.ninjaforce.com/downloads/Asimov.shk" | ||||||
| 						if (( $? != 0 )); then | 						if (( $? != 0 )); then | ||||||
|                             wget -qO Asimov.shk http://web.archive.org/web/20160330184627/http://www.ninjaforce.com/downloads/Asimov.shk | 							wget -qO Asimov.shk "http://web.archive.org/web/20160330184627/http://www.ninjaforce.com/downloads/Asimov.shk" | ||||||
| 						fi | 						fi | ||||||
| 						nulib2 -x -s Asimov.shk &> /dev/null | 						nulib2 -x -s Asimov.shk &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -d Asimov ]]; then | 					if [[ ! -d Asimov ]]; then | ||||||
|                         wget -qO Asimov.shk ${binaryURL}external/appleii/Asimov.shk | 						wget -qO Asimov.shk "${a2sBinaryURL}/appleii/Asimov.shk" | ||||||
| 						nulib2 -x -s Asimov.shk &> /dev/null | 						nulib2 -x -s Asimov.shk &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					cp -p Asimov/Asimov $imageToolsDir/Asimov | 					cp -p Asimov/Asimov $imageToolsDir/Asimov | ||||||
| @@ -595,14 +601,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					mkdir -p /tmp/netboot/gshk | 					mkdir -p /tmp/netboot/gshk | ||||||
| 					cd /tmp/netboot/gshk | 					cd /tmp/netboot/gshk | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO gshk11.sea http://www.nulib.com/library/gshk11.sea | 						wget -qO gshk11.sea "http://www.nulib.com/library/gshk11.sea" | ||||||
| 						if (( $? != 0 )); then | 						if (( $? != 0 )); then | ||||||
|                             wget -qO gshk11.sea http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea | 							wget -qO gshk11.sea "http://web.archive.org/web/20131031160750/http://nulib.com/library/gshk11.sea" | ||||||
| 						fi | 						fi | ||||||
| 						nulib2 -x -s gshk11.sea &> /dev/null | 						nulib2 -x -s gshk11.sea &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -f GSHK ]]; then | 					if [[ ! -f GSHK ]]; then | ||||||
|                         wget -qO gshk11.sea ${binaryURL}external/appleii/gshk11.sea | 						wget -qO gshk11.sea "${a2sBinaryURL}/appleii/gshk11.sea" | ||||||
| 						nulib2 -x -s gshk11.sea &> /dev/null | 						nulib2 -x -s gshk11.sea &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					cp -p GSHK $imageToolsDir/GSHK | 					cp -p GSHK $imageToolsDir/GSHK | ||||||
| @@ -621,15 +627,15 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					mkdir -p /tmp/netboot/mountit | 					mkdir -p /tmp/netboot/mountit | ||||||
| 					cd /tmp/netboot/mountit | 					cd /tmp/netboot/mountit | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -q -O MOUNTIT.SHK http://www.brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK | 						wget -q -O MOUNTIT.SHK "http://www.brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK" | ||||||
| 						if (( $? != 0 )); then | 						if (( $? != 0 )); then | ||||||
|                             wget -q -O http://web.archive.org/web/20150201044930/http://brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK | 							wget -q -O "http://web.archive.org/web/20150201044930/http://brutaldeluxe.fr/products/apple2gs/MOUNTIT.SHK" | ||||||
| 						fi | 						fi | ||||||
| 						cppo -s -ad MOUNTIT.SHK System:System.Setup:MountIt . &> /dev/null | 						cppo -s -ad MOUNTIT.SHK System:System.Setup:MountIt . &> /dev/null | ||||||
| 						cppo -s -ad MOUNTIT.SHK ReadMe . &> /dev/null | 						cppo -s -ad MOUNTIT.SHK ReadMe . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -f ReadMe ]]; then | 					if [[ ! -f ReadMe ]]; then | ||||||
|                         wget -qO MOUNTIT.SHK ${binaryURL}external/appleii/MOUNTIT.SHK | 						wget -qO MOUNTIT.SHK "${a2sBinaryURL}/appleii/MOUNTIT.SHK" | ||||||
| 						cppo -s -ad MOUNTIT.SHK System:System.Setup:MountIt . &> /dev/null | 						cppo -s -ad MOUNTIT.SHK System:System.Setup:MountIt . &> /dev/null | ||||||
| 						cppo -s -ad MOUNTIT.SHK ReadMe . &> /dev/null | 						cppo -s -ad MOUNTIT.SHK ReadMe . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| @@ -654,14 +660,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 				echo | 				echo | ||||||
| 				cd /tmp/netboot | 				cd /tmp/netboot | ||||||
| 				if [[ $useExternalURL ]]; then | 				if [[ $useExternalURL ]]; then | ||||||
|                     wget -qO shrinkit.sdk http://www.nulib.com/library/shrinkit.sdk | 					wget -qO shrinkit.sdk "http://www.nulib.com/library/shrinkit.sdk" | ||||||
| 					if (( $? != 0 )); then | 					if (( $? != 0 )); then | ||||||
|                         wget -qO shrinkit.sdk http://web.archive.org/web/20131031160750/http://www.nulib.com/library/shrinkit.sdk | 						wget -qO shrinkit.sdk "http://web.archive.org/web/20131031160750/http://www.nulib.com/library/shrinkit.sdk" | ||||||
| 					fi | 					fi | ||||||
| 					nulib2 -x -s -e shrinkit.sdk &> /dev/null | 					nulib2 -x -s -e shrinkit.sdk &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 				if [[ ! -f "SHRINKIT#000118i" ]]; then | 				if [[ ! -f "SHRINKIT#000118i" ]]; then | ||||||
|                     wget -qO shrinkit.sdk ${binaryURL}external/appleii/shrinkit.sdk | 					wget -qO shrinkit.sdk "${a2sBinaryURL}/appleii/shrinkit.sdk" | ||||||
| 					nulib2 -x -s -e shrinkit.sdk &> /dev/null | 					nulib2 -x -s -e shrinkit.sdk &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 				cppo -s -ad "SHRINKIT#000118i" /SHRINKIT/SHRINKIT $diskToolsP8Dir &> /dev/null | 				cppo -s -ad "SHRINKIT#000118i" /SHRINKIT/SHRINKIT $diskToolsP8Dir &> /dev/null | ||||||
| @@ -676,14 +682,15 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 				echo | 				echo | ||||||
| 				cd /tmp/netboot | 				cd /tmp/netboot | ||||||
| 				if [[ $useExternalURL ]]; then | 				if [[ $useExternalURL ]]; then | ||||||
|                     wget -q -O dsk2file.shk http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip | 					# This should not be .zip *sigh* | ||||||
|  | 					wget -q -O dsk2file.shk "http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip" | ||||||
| 					if (( $? != 0 )); then | 					if (( $? != 0 )); then | ||||||
| 						wget -q -O dsk2file.shk http://web.archive.org/web/20120726132356/http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip | 						wget -q -O dsk2file.shk http://web.archive.org/web/20120726132356/http://www.dwheeler.com/6502/oneelkruns/dsk2file.zip | ||||||
| 					fi | 					fi | ||||||
| 					nulib2 -x -s dsk2file.shk &> /dev/null | 					nulib2 -x -s dsk2file.shk &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 				if [[ ! -f DSK2FILE58 ]]; then | 				if [[ ! -f DSK2FILE58 ]]; then | ||||||
|                     wget -qO dsk2file.shk ${binaryURL}external/appleii/dsk2file.shk | 					wget -qO dsk2file.shk "${a2sBinaryURL}/appleii/dsk2file.shk" | ||||||
| 					nulib2 -x -s dsk2file.shk &> /dev/null | 					nulib2 -x -s dsk2file.shk &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 				cp -p DSK2FILE58 $diskToolsP8Dir/DSK2FILE | 				cp -p DSK2FILE58 $diskToolsP8Dir/DSK2FILE | ||||||
| @@ -698,14 +705,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 				echo | 				echo | ||||||
| 				cd /tmp/netboot | 				cd /tmp/netboot | ||||||
| 				if [[ $useExternalURL ]]; then | 				if [[ $useExternalURL ]]; then | ||||||
|                     wget --max-redirect 0 -qO Apple_II_System_Disk_3.2.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_II_Supplemental/Apple_II_System_Disk_3.2.sea.bin | 					wget --max-redirect 0 -qO Apple_II_System_Disk_3.2.sea.bin "http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_II_Supplemental/Apple_II_System_Disk_3.2.sea.bin" | ||||||
| 					if (( $? != 0 )); then | 					if (( $? != 0 )); then | ||||||
|                         wget -qO Apple_II_System_Disk_3.2.sea.bin http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_II_Supplemental%2FApple_II_System_Disk_3.2.sea.bin | 						wget -qO Apple_II_System_Disk_3.2.sea.bin "http://archive.org/download/download.info.apple.com.2012.11/download.info.apple.com.2012.11.zip/download.info.apple.com%2FApple_Support_Area%2FApple_Software_Updates%2FEnglish-North_American%2FApple_II%2FApple_II_Supplemental%2FApple_II_System_Disk_3.2.sea.bin" | ||||||
| 					fi | 					fi | ||||||
| 					unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null | 					unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 				if [[ ! -f 'Apple II System Disk 3.2.sea' ]]; then | 				if [[ ! -f 'Apple II System Disk 3.2.sea' ]]; then | ||||||
|                     wget -qO Apple_II_System_Disk_3.2.sea.bin ${binaryURL}external/appleii/Apple_II_System_Disk_3.2.sea.bin | 					wget -qO Apple_II_System_Disk_3.2.sea.bin "${a2sBinaryURL}/appleii/Apple_II_System_Disk_3.2.sea.bin" | ||||||
| 					unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null | 					unar -k skip Apple_II_System_Disk_3.2.sea.bin &> /dev/null | ||||||
| 				fi | 				fi | ||||||
| 				truncate -s 819284 'Apple II System Disk 3.2.sea' | 				truncate -s 819284 'Apple II System Disk 3.2.sea' | ||||||
| @@ -720,12 +727,25 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
| 		p8CommInstalled= | 		p8CommInstalled= | ||||||
|         [[ -f $commDir/ProTERM/PROTERM && -f $commDir/Z.Link/Z.LINK && -f $commDir/ADTPro/ADTPRO && -f $commDir/ADTPro/VSDRIVE ]] && p8CommInstalled=1 | 		if [[ -f $commDir/ProTERM/PROTERM && \ | ||||||
|  | 				-f $commDir/Z.Link/Z.LINK && \ | ||||||
|  | 				-f $commDir/ADTPro/ADTPRO && \ | ||||||
|  | 				-f $commDir/ADTPro/VSDRIVE ]]; then | ||||||
|  | 			p8CommInstalled=1 | ||||||
|  | 		fi | ||||||
| 		gsosCommInstalled= | 		gsosCommInstalled= | ||||||
|         [[ -f $commDir/Spectrum/Spectrum && -f $commDir/SAM2/SAM2 && -f $commDir/SAFE2/SAFE2 && -f $commDir/SNAP/SNAP && -f $gsosDir/System/CDevs/TCPIP ]] && gsosCommInstalled=1 | 		if [[ -f $commDir/Spectrum/Spectrum && \ | ||||||
|  | 				-f $commDir/SAM2/SAM2 && \ | ||||||
|  | 				-f $commDir/SAFE2/SAFE2 && \ | ||||||
|  | 				-f $commDir/SNAP/SNAP && \ | ||||||
|  | 				-f $gsosDir/System/CDevs/TCPIP ]]; then | ||||||
|  | 			gsosCommInstalled=1 | ||||||
|  | 		fi | ||||||
| 		commInstalled= | 		commInstalled= | ||||||
| 		if [[ $gsosInstalled ]]; then | 		if [[ $gsosInstalled ]]; then | ||||||
|             [[ $gsosCommInstalled && $p8CommInstalled ]] && commInstalled=1 | 			if [[ $gsosCommInstalled && $p8CommInstalled ]]; then | ||||||
|  | 				commInstalled=1 | ||||||
|  | 			fi | ||||||
| 		else | 		else | ||||||
| 			commInstalled=$p8CommInstalled | 			commInstalled=$p8CommInstalled | ||||||
| 		fi | 		fi | ||||||
| @@ -773,18 +793,18 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					mkdir -p /tmp/netboot/spectrum | 					mkdir -p /tmp/netboot/spectrum | ||||||
| 					cd /tmp/netboot/spectrum | 					cd /tmp/netboot/spectrum | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO spectrum_gold_2mg.zip http://speccie.uk/speccie/downloads/spectrum_gold_2mg.zip | 						wget -qO spectrum_gold_2mg.zip "http://www.speccie.co.uk/speccie/software/spectrum_gold_2mg.zip" | ||||||
| 						unzip spectrum_gold_2mg.zip Spectrum.Gold.2mg &> /dev/null | 						unzip spectrum_gold_2mg.zip Spectrum.Gold.2mg &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -f Spectrum.Gold.2mg || $(wc -c < Spectrum.Gold.2mg) -eq 0 ]]; then | 					if [[ ! -f Spectrum.Gold.2mg || $(wc -c < Spectrum.Gold.2mg) -eq 0 ]]; then | ||||||
|                         wget -qO spectrum_gold_2mg.zip ${binaryURL}external/appleii/spectrum_gold_2mg.zip | 						wget -qO spectrum_gold_2mg.zip "${a2sBinaryURL}/appleii/spectrum_gold_2mg.zip" | ||||||
| 						unzip spectrum_gold_2mg.zip Spectrum.Gold.2mg &> /dev/null | 						unzip spectrum_gold_2mg.zip Spectrum.Gold.2mg &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					cppo -s -ad Spectrum.Gold.2mg . &> /dev/null | 					cppo -s -ad Spectrum.Gold.2mg . &> /dev/null | ||||||
| 					userFolder=$(tr [:lower:] [:upper:] <<< $USER) | 					userFolder=$(tr [:lower:] [:upper:] <<< $USER) | ||||||
|  |  | ||||||
| 					for thisFolder in \ | 					for thisFolder in \ | ||||||
|                       Installer/Extras/CDEvs^System/CDevs \ | 					  Installer/Extras/CDevs^System/CDevs \ | ||||||
| 					  Installer/Extras/Tools^System/Tools \ | 					  Installer/Extras/Tools^System/Tools \ | ||||||
| 					  Installer/Extras/Fonts^System/Fonts \ | 					  Installer/Extras/Fonts^System/Fonts \ | ||||||
| 					  Installer/Extras/System.Setup^System/System.Setup \ | 					  Installer/Extras/System.Setup^System/System.Setup \ | ||||||
| @@ -815,31 +835,31 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					cd /tmp/netboot/marinetti | 					cd /tmp/netboot/marinetti | ||||||
|  |  | ||||||
| 					# Marinetti 3.0b1 -- had to repackage because installer is GS/OS self-contained app | 					# Marinetti 3.0b1 -- had to repackage because installer is GS/OS self-contained app | ||||||
|                     wget -qO MarinettiB1.SHK ${binaryURL}appleii/MarinettiB1.SHK | 					wget -qO MarinettiB1.SHK "${a2sBinaryURL}/appleii/MarinettiB1.SHK" | ||||||
|  | 					if (( $? != 0 )); then | ||||||
|  | 						wget -qO Marinetti3.0b8.po http://web.archive.org/web/20171105043713/http://a2retrosystems.com/downloads/Marinetti3.0b8.po | ||||||
|  | 					fi | ||||||
| 					cppo -ad -s -n MarinettiB1.SHK $gsosDir > /dev/null | 					cppo -ad -s -n MarinettiB1.SHK $gsosDir > /dev/null | ||||||
|  |  | ||||||
| 					# TCP/IP update (3.0b8) | 					# TCP/IP update (3.0b8) | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO Marinetti3.0b8.po http://www.a2retrosystems.com/downloads/Marinetti3.0b8.po | 						wget -qO Marinetti3.0b8.po "http://www.a2retrosystems.com/downloads/Marinetti3.0b8.po" | ||||||
|                         if (( $? != 0 )); then |  | ||||||
|                             wget -qO Marinetti3.0b8.po http://web.archive.org/web/20171105043713/http://a2retrosystems.com/downloads/Marinetti3.0b8.po |  | ||||||
|                         fi |  | ||||||
| 					fi | 					fi | ||||||
| 					if [[ $? != 0 || ! -f Marinetti3.0b8.po || $(wc -c < Marinetti3.0b8.po) != "819200" ]]; then | 					if [[ $? != 0 || ! -f Marinetti3.0b8.po || $(wc -c < Marinetti3.0b8.po) != "819200" ]]; then | ||||||
|                         wget -qO Marinetti3.0b8.po ${binaryURL}external/appleii/Marinetti3.0b8.po | 						wget -qO Marinetti3.0b8.po "${a2sBinaryURL}/appleii/Marinetti3.0b8.po" | ||||||
| 					fi | 					fi | ||||||
| 					cppo -ad Marinetti3.0b8.po /MARINETTI3.0B8/TCPIP $gsosDir/System/System.Setup > /dev/null | 					cppo -ad Marinetti3.0b8.po /MARINETTI3.0B8/TCPIP $gsosDir/System/System.Setup > /dev/null | ||||||
| 					cppo -ad Marinetti3.0b8.po /MARINETTI3.0B8/CHANGELOG.3.0B8 $commDir/Marinetti > /dev/null | 					cppo -ad Marinetti3.0b8.po /MARINETTI3.0B8/CHANGELOG.3.0B8 $commDir/Marinetti > /dev/null | ||||||
|  |  | ||||||
| 					# PPP Scripted Link Layer update (1.3d4) | 					# PPP Scripted Link Layer update (1.3d4) | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO PPPX.1.3d4.SHK http://www.apple2.org/marinetti/PPPX.1.3d4.SHK | 						wget -qO PPPX.1.3d4.SHK "http://www.apple2.org/marinetti/PPPX.1.3d4.SHK" | ||||||
|                     fi |  | ||||||
| 						if (( $? != 0 )); then | 						if (( $? != 0 )); then | ||||||
| 							wget -qO PPPX.1.3d4.SHK http://web.archive.org/web/20160331231844/http://www.apple2.org/marinetti/PPPX.1.3d4.SHK | 							wget -qO PPPX.1.3d4.SHK http://web.archive.org/web/20160331231844/http://www.apple2.org/marinetti/PPPX.1.3d4.SHK | ||||||
| 						fi | 						fi | ||||||
|  | 					fi | ||||||
| 					if [[ $? != 0 || ! -f PPPX.1.3d4.SHK || $(wc -c < PPPX.1.3d4.SHK) != "22068" ]]; then | 					if [[ $? != 0 || ! -f PPPX.1.3d4.SHK || $(wc -c < PPPX.1.3d4.SHK) != "22068" ]]; then | ||||||
|                         wget -qO PPPX.1.3d4.SHK ${binaryURL}external/appleii/PPPX.1.3d4.SHK | 						wget -qO PPPX.1.3d4.SHK "${a2sBinaryURL}/appleii/PPPX.1.3d4.SHK" | ||||||
| 					fi | 					fi | ||||||
| 					cppo -ad -s PPPX.1.3d4.SHK . > /dev/null | 					cppo -ad -s PPPX.1.3d4.SHK . > /dev/null | ||||||
| 					cd PPPX.1.3d4 | 					cd PPPX.1.3d4 | ||||||
| @@ -851,24 +871,24 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
|  |  | ||||||
| 					# Uthernet Link Layer | 					# Uthernet Link Layer | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO uthernetll.bxy http://speccie.uk/speccie/downloads/uthernetll.bxy | 						wget -qO uthernetll.bxy "http://www.speccie.co.uk/speccie/software/uthernetll.bxy" | ||||||
| 					fi | 					fi | ||||||
| 					if [[ $? != 0 || ! -f uthernetll.bxy || $(wc -c < uthernetll.bxy) -eq 0 ]]; then | 					if [[ $? != 0 || ! -f uthernetll.bxy || $(wc -c < uthernetll.bxy) -eq 0 ]]; then | ||||||
|                         wget -qO uthernetll.bxy ${binaryURL}external/appleii/uthernetll.bxy | 						wget -qO uthernetll.bxy "${a2sBinaryURL}/appleii/uthernetll.bxy" | ||||||
| 					fi | 					fi | ||||||
| 					cppo -ad -s -n uthernetll.bxy $gsosDir/System/TCPIP > /dev/null | 					cppo -ad -s -n uthernetll.bxy $gsosDir/System/TCPIP > /dev/null | ||||||
|  |  | ||||||
| 					# Uthernet II Link Layer | 					# Uthernet II Link Layer | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         wget -qO uthernet2ll.bxy http://speccie.uk/speccie/downloads/uthernet2ll.bxy | 						wget -qO uthernet2ll.bxy "http://www.speccie.co.uk/speccie/software/uthernet2ll.bxy" | ||||||
| 					fi | 					fi | ||||||
| 					if [[ $? != 0 || ! -f uthernet2ll.bxy || $(wc -c < uthernet2ll.bxy) -eq 0 ]]; then | 					if [[ $? != 0 || ! -f uthernet2ll.bxy || $(wc -c < uthernet2ll.bxy) -eq 0 ]]; then | ||||||
|                         wget -qO uthernet2ll.bxy ${binaryURL}external/appleii/uthernet2ll.bxy | 						wget -qO uthernet2ll.bxy "${a2sBinaryURL}/appleii/uthernet2ll.bxy" | ||||||
| 					fi | 					fi | ||||||
| 					cppo -ad -s -n uthernet2ll.bxy $gsosDir/System/TCPIP > /dev/null | 					cppo -ad -s -n uthernet2ll.bxy $gsosDir/System/TCPIP > /dev/null | ||||||
|  |  | ||||||
| 					# MacIP Link Layer settings for A2SERVER | 					# MacIP Link Layer settings for A2SERVER | ||||||
|                     wget -qO- ${binaryURL}macip-prefs.tgz | tar Pxz | 					wget -qO- "${a2sBinaryURL}/a2server/macip-prefs.tgz" | tar Pxz | ||||||
|  |  | ||||||
| 					afpsync -v $gsosDir > /dev/null | 					afpsync -v $gsosDir > /dev/null | ||||||
| 				fi | 				fi | ||||||
| @@ -882,12 +902,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					mkdir -p /tmp/netboot/safe2 | 					mkdir -p /tmp/netboot/safe2 | ||||||
| 					cd /tmp/netboot/safe2 | 					cd /tmp/netboot/safe2 | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         [[ ! $safeUrl ]] && safeUrl="http://speccie.uk/speccie/downloads/safe230.bxy" | 						if [[ ! $safeUrl ]]; then | ||||||
|  | 							safeUrl="http://www.speccie.co.uk/speccie/software/safe230.bxy" | ||||||
|  | 						fi | ||||||
| 						wget -qO safe2.bxy "$safeUrl" | 						wget -qO safe2.bxy "$safeUrl" | ||||||
| 						cppo -s -ad safe2.bxy . &> /dev/null | 						cppo -s -ad safe2.bxy . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -f SAFE2.Archive/Safe2 ]]; then | 					if [[ ! -f SAFE2.Archive/Safe2 ]]; then | ||||||
|                         wget -qO safe2.bxy ${binaryURL}external/appleii/safe2.bxy | 						wget -qO safe2.bxy "${a2sBinaryURL}/appleii/safe230.bxy" | ||||||
| 						cppo -s -ad safe2.bxy . &> /dev/null | 						cppo -s -ad safe2.bxy . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					cd SAFE2.Archive | 					cd SAFE2.Archive | ||||||
| @@ -897,11 +919,11 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					cpAD Version.History $commDir/SAFE2 | 					cpAD Version.History $commDir/SAFE2 | ||||||
| 					cpAD Fonts/SAFE.8 $gsosDir/System/Fonts | 					cpAD Fonts/SAFE.8 $gsosDir/System/Fonts | ||||||
| 					cpAD Fonts/Shaston.16 $gsosDir/System/Fonts | 					cpAD Fonts/Shaston.16 $gsosDir/System/Fonts | ||||||
|                     cpAD TimeZone/TimeZone $gsosDir/System/CDEvs | 					cpAD TimeZone/TimeZone $gsosDir/System/CDevs | ||||||
| 					cpAD TimeZone/Tool056 $gsosDir/System/Tools | 					cpAD TimeZone/Tool056 $gsosDir/System/Tools | ||||||
| 					rm -r $gsosDir/System/Desk.Accs/Help.Files/SAFE2 2> /dev/null | 					rm -r $gsosDir/System/Desk.Accs/Help.Files/SAFE2 2> /dev/null | ||||||
| 					mv Help/Help.Files/SAFE2 $gsosDir/System/Desk.Accs/Help.Files | 					mv Help/Help.Files/SAFE2 $gsosDir/System/Desk.Accs/Help.Files | ||||||
|                     wget -qO- ${binaryURL}safe2-setup.tgz | tar Pzx | 					wget -qO- "${a2sBinaryURL}/appleii/safe2-setup.tgz" | tar Pzx | ||||||
|  |  | ||||||
| 					afpsync -v $gsosDir > /dev/null | 					afpsync -v $gsosDir > /dev/null | ||||||
| 				fi | 				fi | ||||||
| @@ -916,12 +938,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					mkdir -p /tmp/netboot/sam2 | 					mkdir -p /tmp/netboot/sam2 | ||||||
| 					cd /tmp/netboot/sam2 | 					cd /tmp/netboot/sam2 | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         [[ ! $samUrl ]] && samUrl="http://speccie.uk/speccie/downloads/sam206.bxy" | 						if [[ ! $samUrl ]]; then | ||||||
|  | 							samUrl="http://www.speccie.co.uk/speccie/software/sam206.bxy" | ||||||
|  | 						fi | ||||||
| 						wget -qO sam2.bxy "$samUrl" | 						wget -qO sam2.bxy "$samUrl" | ||||||
| 						cppo -s -ad sam2.bxy . &> /dev/null | 						cppo -s -ad sam2.bxy . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -f SAM2.Archive/SAM2/SAM2 ]]; then | 					if [[ ! -f SAM2.Archive/SAM2/SAM2 ]]; then | ||||||
|                         wget -qO sam2.bxy ${binaryURL}external/appleii/sam2.bxy | 						wget -qO sam2.bxy "${a2sBinaryURL}/appleii/sam206.bxy" | ||||||
| 						cppo -s -ad sam2.bxy . &> /dev/null | 						cppo -s -ad sam2.bxy . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					cd SAM2.Archive | 					cd SAM2.Archive | ||||||
| @@ -935,11 +959,6 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					cpAD Version.History $commDir/SAM2 | 					cpAD Version.History $commDir/SAM2 | ||||||
| 					rm -r $gsosDir/System/Desk.Accs/Help.Files/SAM2 2> /dev/null | 					rm -r $gsosDir/System/Desk.Accs/Help.Files/SAM2 2> /dev/null | ||||||
| 					mv Help/Help.Files/SAM2 $gsosDir/System/Desk.Accs/Help.Files | 					mv Help/Help.Files/SAM2 $gsosDir/System/Desk.Accs/Help.Files | ||||||
|                     # cpAD Fonts/SIS.3.10 $gsosDir/System/Fonts |  | ||||||
|                     # cpAD Fonts/SIS.4.10 $gsosDir/System/Fonts |  | ||||||
|                     # cpAD Tools/HTMLTool/TOOL130 $gsosDir/System/Tools |  | ||||||
|                     # cpAD Tools/Hierarchic/Hierarchic $gsosDir/System/CDEvs |  | ||||||
|                     # cpAD Fonts/Shaston.16 $gsosDir/System/Fonts |  | ||||||
|  |  | ||||||
| 					afpsync -v $gsosDir > /dev/null | 					afpsync -v $gsosDir > /dev/null | ||||||
| 				fi | 				fi | ||||||
| @@ -953,12 +972,14 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					mkdir -p /tmp/netboot/snap | 					mkdir -p /tmp/netboot/snap | ||||||
| 					cd /tmp/netboot/snap | 					cd /tmp/netboot/snap | ||||||
| 					if [[ $useExternalURL ]]; then | 					if [[ $useExternalURL ]]; then | ||||||
|                         [[ ! $snapUrl ]] && snapUrl="http://speccie.uk/speccie/downloads/snap118.bxy" | 						if [[ ! $snapUrl ]]; then | ||||||
|  | 							snapUrl="http://www.speccie.co.uk/speccie/software/snap118.bxy" | ||||||
|  | 						fi | ||||||
| 						wget -qO snap.bxy "$snapUrl" | 						wget -qO snap.bxy "$snapUrl" | ||||||
| 						cppo -s -ad snap.bxy . &> /dev/null | 						cppo -s -ad snap.bxy . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					if [[ ! -f SNAP.Archive/SNAP ]]; then | 					if [[ ! -f SNAP.Archive/SNAP ]]; then | ||||||
|                         wget -qO snap.bxy ${binaryURL}external/appleii/snap.bxy | 						wget -qO snap.bxy "${a2sBinaryURL}/appleii/snap118.bxy" | ||||||
| 						cppo -s -ad snap.bxy . &> /dev/null | 						cppo -s -ad snap.bxy . &> /dev/null | ||||||
| 					fi | 					fi | ||||||
| 					cd SNAP.Archive | 					cd SNAP.Archive | ||||||
| @@ -971,12 +992,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 					cpAD Quick.Start $commDir/SNAP | 					cpAD Quick.Start $commDir/SNAP | ||||||
| 					rm -r $gsosDir/System/Desk.Accs/Help.Files/SNAP 2> /dev/null | 					rm -r $gsosDir/System/Desk.Accs/Help.Files/SNAP 2> /dev/null | ||||||
| 					mv Help/Help.Files/SNAP $gsosDir/System/Desk.Accs/Help.Files | 					mv Help/Help.Files/SNAP $gsosDir/System/Desk.Accs/Help.Files | ||||||
|                     wget -qO- ${binaryURL}snap-setup.tgz | tar Pzx | 					wget -qO- "${a2sBinaryURL}/appleii/snap-setup.tgz" | tar Pzx | ||||||
|                     # cpAD Fonts/SIS.3.10 $gsosDir/System/Fonts |  | ||||||
|                     # cpAD Fonts/SIS.4.10 $gsosDir/System/Fonts |  | ||||||
|                     # cpAD Tools/HTMLTool/TOOL130 $gsosDir/System/Tools |  | ||||||
|                     # cpAD Tools/Hierarchic/Hierarchic $gsosDir/System/CDEvs |  | ||||||
|                     # cpAD Fonts/Shaston.16 $gsosDir/System/Fonts |  | ||||||
|  |  | ||||||
| 					afpsync -v $gsosDir > /dev/null | 					afpsync -v $gsosDir > /dev/null | ||||||
| 				fi | 				fi | ||||||
| @@ -991,7 +1007,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 				mkdir -p $commDir/ProTERM | 				mkdir -p $commDir/ProTERM | ||||||
| 				mkdir -p $commDir/ProTERM/.AppleDouble | 				mkdir -p $commDir/ProTERM/.AppleDouble | ||||||
| 				cd /tmp/netboot | 				cd /tmp/netboot | ||||||
|                 wget -qO A2CLOUD.HDV "${binaryURL}appleii/A2CLOUD.HDV" | 				wget -qO A2CLOUD.HDV "${a2sBinaryURL}/appleii/A2CLOUD.HDV" | ||||||
| 				cppo -s -ad A2CLOUD.HDV . &> /dev/null | 				cppo -s -ad A2CLOUD.HDV . &> /dev/null | ||||||
| 				cd A2CLOUD | 				cd A2CLOUD | ||||||
| 				mv *PT3* *PROTERM* $commDir/ProTERM | 				mv *PT3* *PROTERM* $commDir/ProTERM | ||||||
| @@ -1062,7 +1078,7 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupNetBoot ]]; then | |||||||
| 		if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | 		if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||||
| 			# Farallon bridge patch for GS/OS courtesy of Geoff Body | 			# Farallon bridge patch for GS/OS courtesy of Geoff Body | ||||||
| 			echo "A2SERVER: Downloading Farallon bridge patch..." | 			echo "A2SERVER: Downloading Farallon bridge patch..." | ||||||
|             wget -qO /tmp/FARALLON.PO "${binaryURL}appleii/FARALLON.B1.PO" &> /dev/null | 			wget -qO /tmp/FARALLON.PO "${a2sBinaryURL}/appleii/FARALLON.B1.PO" &> /dev/null | ||||||
| 			cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir/SYSTEM/SYSTEM.SETUP &> /dev/null | 			cppo -s -ad /tmp/FARALLON.PO /ATALKPATCH/ATALKIRQ $gsosDir/SYSTEM/SYSTEM.SETUP &> /dev/null | ||||||
| 			echo | 			echo | ||||||
| 			echo "A2SERVER: The Farallon bridge patch is installed." | 			echo "A2SERVER: The Farallon bridge patch is installed." | ||||||
|   | |||||||
| @@ -1,10 +1,13 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # Set up A2SERVER to support Samba (Windows File Sharing) | # Set up A2SERVER to support Samba (Windows File Sharing) | ||||||
| # this script can also be used if new shares are introduced | # this script can also be used if new shares are introduced | ||||||
|  |  | ||||||
| [[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes= | autoAnswerYes= | ||||||
|  | if [[ -f /tmp/a2server-autoAnswerYes ]]; then | ||||||
|  | 	autoAnswerYes=1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then | if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then | ||||||
|  |  | ||||||
| @@ -19,7 +22,9 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then | |||||||
| 		sudo true | 		sudo true | ||||||
|  |  | ||||||
| 		sudo update-rc.d samba defaults &> /dev/null | 		sudo update-rc.d samba defaults &> /dev/null | ||||||
|         [[ ! -f /etc/init.d/samba ]] && installSamba=1 | 		if [[ ! -f /etc/init.d/samba ]]; then | ||||||
|  | 			installSamba=1 | ||||||
|  | 		fi | ||||||
|  |  | ||||||
| 		if (( $installSamba )); then | 		if (( $installSamba )); then | ||||||
| 			if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | 			if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||||
| @@ -38,12 +43,17 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then | |||||||
| 		sudo /etc/init.d/samba start &> /dev/null | 		sudo /etc/init.d/samba start &> /dev/null | ||||||
|  |  | ||||||
| 		workgroup=$(grep -o "^       workgroup = .*$" /etc/samba/smb.conf 2> /dev/null | cut -c 16-) | 		workgroup=$(grep -o "^       workgroup = .*$" /etc/samba/smb.conf 2> /dev/null | cut -c 16-) | ||||||
|         [[ $workgroup ]] || workgroup="WORKGROUP" | 		if [[ -z "$workgroup" ]]; then | ||||||
|  | 			workgroup="WORKGROUP" | ||||||
|  | 		fi | ||||||
| 		if [[ ! $autoAnswerYes ]]; then | 		if [[ ! $autoAnswerYes ]]; then | ||||||
| 			echo | 			echo | ||||||
| 			echo "Enter workgroup name (or press return for '${workgroup}'): " | 			echo "Enter workgroup name (or press return for '${workgroup}'): " | ||||||
| 			read | 			read | ||||||
|             [[ $REPLY ]] && workgroup=$REPLY | 			# FIXME validation? | ||||||
|  | 			if [[ $REPLY ]]; then | ||||||
|  | 				workgroup=$REPLY | ||||||
|  | 			fi | ||||||
| 		fi | 		fi | ||||||
| 		sudo sed -i 's/^   workgroup = .*$/   workgroup = '$workgroup'/' /etc/samba/smb.conf 2> /dev/null | 		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 | 		sudo sed -i 's/^#   security = user/   security = user/' /etc/samba/smb.conf 2> /dev/null | ||||||
| @@ -59,13 +69,15 @@ if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then | |||||||
| 			if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then | 			if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then | ||||||
| 				echo "A2SERVER: $sharename is already set up for Windows file sharing." | 				echo "A2SERVER: $sharename is already set up for Windows file sharing." | ||||||
| 			else | 			else | ||||||
|                 echo "[$sharename]" | sudo tee -a /etc/samba/smb.conf > /dev/null | 				sudo tee -a /etc/samba/smb.conf >/dev/null <<EOF | ||||||
|                 echo "    path = /srv/A2SERVER/$sharename" | sudo tee -a /etc/samba/smb.conf > /dev/null | [$sharename] | ||||||
|                 echo "    browsable = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null |     path = /srv/A2SERVER/$sharename | ||||||
|                 echo "    guest ok = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null |     browsable = yes | ||||||
|                 echo "    read only = no" | sudo tee -a /etc/samba/smb.conf > /dev/null |     guest ok = yes | ||||||
|                 echo "    create mask = 0666" | sudo tee -a /etc/samba/smb.conf > /dev/null |     read only = no | ||||||
|                 echo "    force user = $USER" | sudo tee -a /etc/samba/smb.conf > /dev/null |     create mask = 0666 | ||||||
|  |     force user = $USER | ||||||
|  | EOF | ||||||
| 				echo "A2SERVER: $sharename has been set up for Windows file sharing." | 				echo "A2SERVER: $sharename has been set up for Windows file sharing." | ||||||
| 			fi | 			fi | ||||||
| 		done | 		done | ||||||
|   | |||||||
| @@ -1,23 +1,32 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # This script helps when running on the Linux console within a VirtualBox VM. | # This script helps when running on the Linux console within a VirtualBox VM. | ||||||
|  |  | ||||||
| echo | echo | ||||||
|  |  | ||||||
| userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') | userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') | ||||||
| [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw= | isApple2Pw= | ||||||
| [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw= | if [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]]; then | ||||||
|  | 	isApple2Pw=1 | ||||||
|  | fi | ||||||
|  | isRaspberryPw= | ||||||
|  | if [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]]; then | ||||||
|  | 	isRaspberryPw=1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| password="your password" | password="your password" | ||||||
| [[ $isApple2Pw ]] && password="'apple2'" | [[ $isApple2Pw ]] && password="'apple2'" | ||||||
| [[ $isRaspberryPw ]] && password="'raspberry'" | [[ $isRaspberryPw ]] && password="'raspberry'" | ||||||
|  |  | ||||||
| isDebian= | if [[ "$(lsb_release -ds)" = Debian* ]]; then | ||||||
| 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 [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then | ||||||
|  | 		isDebian=1 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
| if [[ $isDebian ]]; then | if [[ $isDebian ]]; then | ||||||
|     if { lspci 2> /dev/null | grep -q VirtualBox; }; then | 	if lspci 2>/dev/null | grep -q VirtualBox; then | ||||||
| 		echo "A2SERVER: Disabling VirtualBox console screen blanking..." | 		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_DPMS=off/BLANK_DPMS=on/' /etc/kbd/config | ||||||
| 		sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config | 		sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								scripts/compare_version
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										35
									
								
								scripts/compare_version
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | #! /usr/bin/env python3 | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=python: | ||||||
|  |  | ||||||
|  | import sys | ||||||
|  | from pkg_resources import parse_version | ||||||
|  |  | ||||||
|  | def usage(): | ||||||
|  | 	print("Usage: compare_version <version> <operator> <version>") | ||||||
|  | 	print("    where operator is one of lt, le, eq, ge, gt, or ne") | ||||||
|  | 	sys.exit(2) | ||||||
|  |  | ||||||
|  | if len(sys.argv) != 4: | ||||||
|  | 	usage() | ||||||
|  |  | ||||||
|  | ver1 = parse_version(sys.argv[1]) | ||||||
|  | ver2 = parse_version(sys.argv[3]) | ||||||
|  |  | ||||||
|  | # I suppose you could do something clever with meta-method mapping here | ||||||
|  | result = False | ||||||
|  | if sys.argv[2] == 'lt': | ||||||
|  | 	result = ver1 < ver2 | ||||||
|  | elif sys.argv[2] == 'le': | ||||||
|  | 	result = ver1 <= ver2 | ||||||
|  | elif sys.argv[2] == 'eq': | ||||||
|  | 	result = ver1 == ver2 | ||||||
|  | elif sys.argv[2] == 'ge': | ||||||
|  | 	result = ver1 >= ver2 | ||||||
|  | elif sys.argv[2] == 'gt': | ||||||
|  | 	result = ver1 > ver2 | ||||||
|  | elif sys.argv[2] == 'ne': | ||||||
|  | 	result = ver1 != ver2 | ||||||
|  | else: | ||||||
|  | 	usage() | ||||||
|  |  | ||||||
|  | sys.exit(0 if result else 1) | ||||||
| @@ -1,233 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
|  |  | ||||||
| # raspbian-update |  | ||||||
| # updates Raspbian to latest version, including NOOBS if installed |  | ||||||
|  |  | ||||||
| [[ -f /usr/bin/raspi-config ]] && isRpi=1 || isRpi= |  | ||||||
|  |  | ||||||
| if [[ ! $isRpi ]]; then |  | ||||||
|     echo "This ain't a Raspberry Pi." |  | ||||||
|     [[ $0 == "-bash" ]] && return 1 || exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| skipRepoUpdate= |  | ||||||
| autoYes= |  | ||||||
| updateA2Cloud= |  | ||||||
| updateA2Server= |  | ||||||
| while [[ $1 ]]; do |  | ||||||
|     if [[ $1 == "-r" ]]; then |  | ||||||
|         shift |  | ||||||
|         skipRepoUpdate="-r" |  | ||||||
|     elif [[ $1 == "-y" ]]; then |  | ||||||
|         shift |  | ||||||
|         autoYes="-y" |  | ||||||
|     elif [[ $1 == "-n" ]]; then |  | ||||||
|         shift |  | ||||||
|         noobsOnly="-n" |  | ||||||
|     elif [[ $1 == "a2cloud" ]]; then |  | ||||||
|         shift |  | ||||||
|         updateA2Cloud=1 |  | ||||||
|     elif [[ $1 == "a2server" ]]; then |  | ||||||
|         shift |  | ||||||
|         updateA2Server=1 |  | ||||||
|     elif [[ $1 ]]; then |  | ||||||
|         echo "options:" |  | ||||||
|         echo "-y: auto-answer yes to all prompts and don't prompt for restart" |  | ||||||
|         echo "-r: don't update package repositories" |  | ||||||
|         echo "-n: update NOOBS only; don't update Raspbian" |  | ||||||
|         echo "a2cloud : update A2CLOUD when complete" |  | ||||||
|         echo "a2server: update A2SERVER when complete" |  | ||||||
|         [[ $0 == "-bash" ]] && return 1 || exit 1 |  | ||||||
|     fi |  | ||||||
| done |  | ||||||
|  |  | ||||||
| noobs= |  | ||||||
| readarray -t partitions < <(sudo fdisk -l | grep '^/dev') |  | ||||||
| if [[ \ |  | ||||||
|   ${partitions[0]:0:14} == "/dev/mmcblk0p1" && ${partitions[0]:57:2} == " e" && |  | ||||||
|   ${partitions[1]:0:14} == "/dev/mmcblk0p2" && ${partitions[1]:57:2} == "85" && |  | ||||||
|   ${partitions[2]:0:14} == "/dev/mmcblk0p3" && ${partitions[2]:57:2} == "83" && |  | ||||||
|   ${partitions[3]:0:14} == "/dev/mmcblk0p5" && ${partitions[3]:57:2} == " c" && |  | ||||||
|   ${partitions[4]:0:14} == "/dev/mmcblk0p6" && ${partitions[4]:57:2} == "83" ]]; then     |  | ||||||
|     noobs=" and the NOOBS install manager" |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| if [[ ! $autoYes ]]; then |  | ||||||
|     echo |  | ||||||
|     echo "You are about to update your SD card to the latest version of the" |  | ||||||
|     echo "Raspbian operating system${noobs}." |  | ||||||
|     echo |  | ||||||
|     echo "This may take an hour or more, and will require restarting when complete." |  | ||||||
|     echo "You might want a backup before continuing in case it doesn't go as planned." |  | ||||||
|     echo |  | ||||||
|     echo -n "Update Raspbian? " |  | ||||||
|     read |  | ||||||
|     if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then |  | ||||||
|         [[ $0 == "-bash" ]] && return 2 || exit 2 |  | ||||||
|     fi |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| origDir="$PWD" |  | ||||||
| cd /tmp |  | ||||||
|  |  | ||||||
| if [[ ! $skipRepoUpdate ]]; then |  | ||||||
|     echo "Updating package repositories..." |  | ||||||
|     sudo apt-get -y update > /dev/null |  | ||||||
| else |  | ||||||
|     echo "Not updating package repositories..." |  | ||||||
|     echo |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| if [[ ! $noobsOnly ]]; then |  | ||||||
|     { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
|     freeSpace=$(df / | tail -1 | awk '{ print $4 }') |  | ||||||
|     if (( $freeSpace < 400000 )); then |  | ||||||
|         if dpkg -l | grep -q wolfram-engine; then     |  | ||||||
|             if [[ ! $autoYes ]]; then |  | ||||||
|                 echo "In order to create enough space on your SD card to upgrade," |  | ||||||
|                 echo "the Wolfram Language and Mathematica software packages must be removed." |  | ||||||
|                 echo "If you don't know what these are, this won't affect you at all." |  | ||||||
|                 echo |  | ||||||
|                 echo -n "Remove Wolfram software? " |  | ||||||
|                 read |  | ||||||
|                 if [[ ${REPLY:0:1} != "Y" && ${REPLY:0:1} != "y" ]]; then |  | ||||||
|                     [[ $0 == "-bash" ]] && return 2 || exit 2 |  | ||||||
|                 fi |  | ||||||
|                 sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null |  | ||||||
|                 sudo apt-get -y purge wolfram-engine |  | ||||||
|             else |  | ||||||
|                 echo "Removing Wolfram software due to space constraints..." |  | ||||||
|                 sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null |  | ||||||
|                 sudo apt-get -y purge wolfram-engine |  | ||||||
|             fi |  | ||||||
|         else |  | ||||||
|             echo "You don't have enough free space on your SD card to upgrade." |  | ||||||
|             echo "Sorry, man. Delete some stuff or get a bigger card." |  | ||||||
|             [[ $0 == "-bash" ]] && return 1 || exit 1 |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
|     dpkg -l | grep -q a2pi && sudo apt-get -y --force-yes install a2pi |  | ||||||
|     dpkg -l | grep -q apple2user && sudo apt-get -y --force-yes install apple2user gsport |  | ||||||
|     if dpkg -l | grep -q wolfram-engine; then |  | ||||||
|         sudo rm /opt/Wolfram/WolframEngine/10.0/SystemFiles/Java/Linux-ARM 2> /dev/null |  | ||||||
|         if [[ $freeSpace -lt 750000 && $(apt-get -s install wolfram-engine | grep upgraded) ]]; then |  | ||||||
|             sudo apt-get -y purge wolfram-engine |  | ||||||
|             { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
|         fi |  | ||||||
|         sudo apt-get -y install wolfram-engine |  | ||||||
|         { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
|     fi |  | ||||||
|     sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade |  | ||||||
|     { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
|     sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade |  | ||||||
|     { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
|     sudo apt-get -y install raspberrypi-ui-mods |  | ||||||
|     { cd /tmp; sudo apt-get -y autoremove; sudo apt-get -y autoclean; sudo apt-get -y clean; } > /dev/null |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| if [[ $noobs ]]; then |  | ||||||
|     echo "Updating NOOBS..." |  | ||||||
|  |  | ||||||
|     # update Partition 3 |  | ||||||
|     mkdir -p /tmp/p3 |  | ||||||
|     sudo mount /dev/mmcblk0p3 /tmp/p3 |  | ||||||
|     sudo rm -rf /tmp/p3/os/* 2> /dev/null |  | ||||||
|     if grep -q 'Raspple II' /tmp/p3/installed_os.json; then |  | ||||||
|         echo "Downloading Raspple II lite..." |  | ||||||
|         noobsUrl="ivanx.com/rasppleii/files/RasppleII_lite.zip" |  | ||||||
|         noobsOSurl="ivanx.com/rasppleii/noobs-os" |  | ||||||
|         distDir="Raspple_II" |  | ||||||
|         sudo mkdir -p /tmp/p3/os/$distDir |  | ||||||
|         sudo sed -i 's:/Raspbian:/Raspple_II:' /tmp/p3/installed_os.json |  | ||||||
|         sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspple_II.png |  | ||||||
|         { wget -qO- $noobsOSurl/slidesAB.tar | sudo tar -C /tmp/p3/os/$distDir -x; } &> /dev/null |  | ||||||
|     else |  | ||||||
|         echo "Downloading NOOBS lite..." |  | ||||||
|         noobsRoot="downloads.raspberrypi.org/NOOBS_lite/images/" |  | ||||||
|         noobsDir=$(wget -qO- $noobsRoot | grep '^<tr><td' | tail -1 | grep -P -o 'href=".*?"' | cut -c 6- | tr -d '"') |  | ||||||
|         noobsUrl=$noobsRoot$noobsDir$(wget -qO- $noobsRoot$noobsDir | grep -P -o 'href=".*.zip"' | cut -c 6- | tr -d '"') |  | ||||||
|         noobsOSurl="downloads.raspberrypi.org/raspbian" |  | ||||||
|         distDir="Raspbian" |  | ||||||
|         sudo mkdir -p /tmp/p3/os/$distDir |  | ||||||
|         sudo wget -qO /tmp/p3/icon.png $noobsOSurl/Raspbian.png |  | ||||||
|         { wget -qO- $noobsOSurl/marketing.tar | sudo tar -C /tmp/p3/os/$distDir -x; } &> /dev/null |  | ||||||
|     fi |  | ||||||
|     sudo rm -rf /tmp/p3/cache 2> /dev/null |  | ||||||
|     releaseDate=$(wget -qO- $noobsOSurl/os.json | grep 'release_date' | cut -f 4 -d '"') |  | ||||||
|     sudo sed -i 's/"release_date".*$/"release_date" : "'$releaseDate'"/' /tmp/p3/installed_os.json |  | ||||||
|     sudo sed -i 's/keyboard_layout=gb/keyboard_layout=us/' /tmp/p3/noobs.conf |  | ||||||
|     sudo sed -i 's:/mnt/:/settings/:' /tmp/p3/installed_os.json |  | ||||||
|     sudo sed -i 's@"icon".*,@"icon" : "/settings/os/'$distDir'/icon.png",@' /tmp/p3/installed_os.json |  | ||||||
|     sudo cp /tmp/p3/icon.png /tmp/p3/os/$distDir |  | ||||||
|     sudo wget -qO /tmp/p3/os/$distDir/os.json $noobsOSurl/os.json |  | ||||||
|     sudo wget -qO /tmp/p3/os/$distDir/partition_setup.sh $noobsOSurl/partition_setup.sh |  | ||||||
|     sudo wget -qO /tmp/p3/os/$distDir/partitions.json $noobsOSurl/partitions.json |  | ||||||
|     sudo umount /tmp/p3 |  | ||||||
|     rmdir /tmp/p3 |  | ||||||
|  |  | ||||||
|     # update Partition 1 |  | ||||||
|     mkdir -p /tmp/p1 |  | ||||||
|     sudo mount /dev/mmcblk0p1 /tmp/p1 |  | ||||||
|     wget -qO /tmp/noobs_lite.zip $noobsUrl |  | ||||||
|     sudo rm -rf /tmp/p1/* |  | ||||||
|     sudo unzip -d /tmp/p1 /tmp/noobs_lite.zip |  | ||||||
|     sudo sed -i 's/^runinstaller //' /tmp/p1/recovery.cmdline |  | ||||||
|     sudo sed -i 's/silentinstall//' /tmp/p1/recovery.cmdline |  | ||||||
|     grep -q 'keyboard=us' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 keyboard=us/' /tmp/p1/recovery.cmdline |  | ||||||
|     grep -q 'disablesafemode' /tmp/p1/recovery.cmdline || sudo sed -i '1 s/^\(.*\)$/\1 disablesafemode/' /tmp/p1/recovery.cmdline |  | ||||||
|     sudo umount /tmp/p1 |  | ||||||
|     rmdir /tmp/p1 |  | ||||||
|          |  | ||||||
|     sudo sed -i 's/\(Raspple II release.*[^u]$\)/\1u/' /etc/issue |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| echo |  | ||||||
| echo "*** Raspbian update completed. ***" |  | ||||||
| echo |  | ||||||
|  |  | ||||||
| cd /tmp |  | ||||||
|  |  | ||||||
| if [[ $updateA2Cloud ]]; then |  | ||||||
|     wget -qO /tmp/a2cloud-setup ivanx.com/a2cloud/setup/ |  | ||||||
|     source /tmp/a2cloud-setup -y -r noSetGroups |  | ||||||
|     if acmd -g /usr/share/gsport/disks/GSport\ Internet\ Starter\ Kit.2mg SYSTEM/FONTS/SIS.4.10 &> /dev/null; then |  | ||||||
|         wget -qO /tmp/ua2.txt ivanx.com/rasppleii/files/a/ua2.txt |  | ||||||
|         source /tmp/ua2.txt |  | ||||||
|     fi |  | ||||||
|     echo |  | ||||||
|     echo "*** A2CLOUD update completed. ***" |  | ||||||
|     echo |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| cd /tmp |  | ||||||
|  |  | ||||||
| if [[ $updateA2Server ]]; then |  | ||||||
|     wget -q -O /tmp/a2server-setup ivanx.com/a2server/setup/ |  | ||||||
|     if ps aux | grep -q [s]mbd; then |  | ||||||
|         source /tmp/a2server-setup -y -r -w |  | ||||||
|     else |  | ||||||
|         source /tmp/a2server-setup -y -r |  | ||||||
|     fi |  | ||||||
|     echo |  | ||||||
|     echo "*** A2SERVER update completed. ***" |  | ||||||
|     echo |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| cd "$origDir" |  | ||||||
|  |  | ||||||
| if [[ ! $autoYes ]]; then |  | ||||||
|     echo |  | ||||||
|     echo |  | ||||||
|     echo "Your system has been updated and needs to reboot to use its new software." |  | ||||||
|     echo |  | ||||||
|     echo -n "Reboot now (recommended)? " |  | ||||||
|     read |  | ||||||
|     if [[ ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then |  | ||||||
|         sudo shutdown -r now |  | ||||||
|     fi |  | ||||||
| else |  | ||||||
|     echo "*** raspbian-update completed. ***" |  | ||||||
|     sudo shutdown -r now |  | ||||||
| fi |  | ||||||
| @@ -1,19 +1,16 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
| 
 | 
 | ||||||
| alias a2server-help="more /usr/local/etc/a2server-help.txt" | alias a2server-help="more /usr/local/etc/a2server-help.txt" | ||||||
| alias a2server-setup='wget -q -O /tmp/a2server-setup ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}setup/index.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/a2server-setup' | 
 | ||||||
| 
 | 
 | ||||||
| alias a2server-version="cat /usr/local/etc/A2SERVER-version" | alias a2server-version="cat /usr/local/etc/A2SERVER-version" | ||||||
| alias a2server-update='wget -q -O /tmp/a2server-update ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}update/index.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/a2server-update' | 
 | ||||||
| 
 | 
 | ||||||
| alias system-shutdown='sudo shutdown -h now' | alias system-shutdown='sudo shutdown -h now' | ||||||
| alias system-restart='sudo shutdown -r now' | alias system-restart='sudo shutdown -r now' | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| alias raspi-config='[[ -f /usr/bin/raspi-config ]] && sudo /usr/bin/raspi-config || echo "raspi-config not found. Are you using a Raspberry Pi with Raspbian?"' | alias raspi-config='[[ -f /usr/bin/raspi-config ]] && sudo /usr/bin/raspi-config || echo "raspi-config not found. Are you using a Raspberry Pi with Raspbian?"' | ||||||
| alias raspbian-update='wget -qO /tmp/raspbian-update ${A2SERVER_SCRIPT_URL:-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' | alias welcome-message-edit='sudo nano /etc/motd' | ||||||
| 
 | 
 | ||||||
| @@ -10,10 +10,7 @@ a2server-update: check for update to A2SERVER | |||||||
| system-shutdown: shut down the server | system-shutdown: shut down the server | ||||||
| system-restart: shut down and restart the server | system-restart: shut down and restart the server | ||||||
|  |  | ||||||
|  Raspberry Pi commands, if you're using one: | debupdate: update the Raspple II operating system | ||||||
| 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 | welcome-message-edit: change the welcome message | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								scripts/tools/a2serverrc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								scripts/tools/a2serverrc
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | source /usr/local/etc/a2server-aliases | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| #! /bin/bash |  | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: |  | ||||||
|  |  | ||||||
| export A2SERVER_SCRIPT_URL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}" |  | ||||||
| export A2SERVER_BINARY_URL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files/}" |  | ||||||
| source /usr/local/etc/a2server-aliases |  | ||||||
							
								
								
									
										116
									
								
								scripts/tools/afpsync
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										116
									
								
								scripts/tools/afpsync
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # afpsync: updates .AppleDouble components of files on shared volumes | ||||||
|  |  | ||||||
|  | # this must be used if any files are copied to the shared volume via | ||||||
|  | # non-AFP methods (directly, via Samba, etc). | ||||||
|  |  | ||||||
|  | # usage: | ||||||
|  | # afpsync [-v] [shared volume path] | ||||||
|  | # | ||||||
|  | # -v will silently create a .volinfo file if none exists. | ||||||
|  | # If a path is specified, only that volume is synced; otherwise, all | ||||||
|  | # all paths in /srv/A2SERVER which appear in | ||||||
|  | # /usr/local/etc/netatalk/AppleVolumes.default are synced. | ||||||
|  |  | ||||||
|  | processPath () { | ||||||
|  | 	if [[ ! -d $sharepath ]]; then | ||||||
|  | 		echo "$sharepath does not exist." | ||||||
|  | 	else | ||||||
|  | 		volinfo="$sharepath/.AppleDesktop/.volinfo" | ||||||
|  | 		if [[ ! -f $volinfo ]]; then | ||||||
|  | 			if [[ ! $force ]]; then | ||||||
|  | 				echo "Cannot update AppleDouble files for volume $sharepath," | ||||||
|  | 				echo "because its .volinfo file does not exist. To create it, log" | ||||||
|  | 				echo "into the volume from an Apple II or Mac client computer," | ||||||
|  | 				echo "or use \"afpsync -v\"." | ||||||
|  | 			else | ||||||
|  | 				if (( $1 )); then | ||||||
|  | 					mkvolinfo -f -c $sharepath | ||||||
|  | 				else | ||||||
|  | 					mkvolinfo -f $sharepath | ||||||
|  | 				fi | ||||||
|  | 				$0 $sharepath | ||||||
|  | 			fi | ||||||
|  | 		else | ||||||
|  | 			IFS='' | ||||||
|  | 			result=$(sudo dbd -r $sharepath | grep encoding) | ||||||
|  | 			f=$(wc -l <<< $result) | ||||||
|  | 			[[ $(wc -w <<< $result) == 0 ]] && f=0 | ||||||
|  | 			[[ $f -eq 1 && $(grep AppleDesktop <<< "$result") && $(grep MTOULOWER $sharepath/.AppleDesktop/.volinfo) ]] && (( f-- )) | ||||||
|  | 			if (( f == 0 )); then | ||||||
|  | 				echo "AppleDouble files have been updated for volume $sharepath." | ||||||
|  | 			else | ||||||
|  | 				[[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath." | ||||||
|  | 				if [[ $showerrors ]]; then | ||||||
|  | 					echo $result \ | ||||||
|  | 						| while read LINE; do | ||||||
|  | 						[[ ! $(echo $LINE | grep APPLEDESKTOP) ]] && echo $LINE | ||||||
|  | 					done | ||||||
|  | 				elif [[ $renameLower ]]; then | ||||||
|  | 					echo $result \ | ||||||
|  | 						| while read LINE; do | ||||||
|  | 						if [[ ! $(echo $LINE | grep APPLEDESKTOP) ]]; then | ||||||
|  | 							filepath=$(echo $LINE | sed "s/^Bad\ encoding\ for\ '//" | sed s/\'//) | ||||||
|  | 							filename=${filepath##*/} | ||||||
|  | 							filedir=${filepath%/*} | ||||||
|  | 							mv $filepath $filedir/${filename^^} | ||||||
|  | 							echo "Renamed $filedir/${filename^^}." | ||||||
|  | 						fi | ||||||
|  | 					done | ||||||
|  | 					$0 $sharepath | ||||||
|  | 				else | ||||||
|  | 					echo "Use afpsync -e to see error details." | ||||||
|  | 				fi | ||||||
|  | 			fi | ||||||
|  | 			unset IFS | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | while [[ $1 == "-r" || $1 == "-e" || $1 = "-v" ]]; do | ||||||
|  |  | ||||||
|  | 	if [[ $1 == "-v" ]]; then | ||||||
|  | 		force=1 | ||||||
|  | 		shift | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if [[ $1 == "-e" ]]; then | ||||||
|  | 		showerrors=1 | ||||||
|  | 		shift | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if [[ $1 == "-r" ]]; then | ||||||
|  | 		renameLower=1 | ||||||
|  | 		shift | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [[ ${1:0:1} == "-" ]]; then | ||||||
|  | 	echo "Usage: afpsync [-e|-r] [-v] [shared volume path]" | ||||||
|  | 	echo | ||||||
|  | 	echo "-e: show error details" | ||||||
|  | 	echo "-r: rename lowercase filenames to uppercase" | ||||||
|  | 	echo "-v: create .volinfo file if none exists" | ||||||
|  | 	echo "If no directory is specified, all found in" | ||||||
|  | 	echo "  /usr/local/etc/netatalk/AppleVolumes.default are processed." | ||||||
|  | 	echo | ||||||
|  | else | ||||||
|  | 	sudo true | ||||||
|  | 	if [[ $1 ]]; then | ||||||
|  | 		sharepath=$(readlink -m $1) | ||||||
|  | 		# behavior change in 1.3.0: now defaults to mixed case | ||||||
|  | 		#   on a volume when specifying a folder and -v | ||||||
|  | 		#   (as opposed to defaulting to casefold:toupper previously) | ||||||
|  | 		processPath 1 | ||||||
|  | 	else | ||||||
|  | 		grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \ | ||||||
|  | 			while read line; do | ||||||
|  | 			[[ $(echo $line | grep toupper) ]]; nocasefold=$? | ||||||
|  | 			sharepath=$(echo $line | cut -d" " -f1) | ||||||
|  | 			processPath nocasefold | ||||||
|  | 		done | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
| @@ -1,116 +0,0 @@ | |||||||
| #! /bin/bash |  | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: |  | ||||||
|  |  | ||||||
| # afpsync: updates .AppleDouble components of files on shared volumes |  | ||||||
|  |  | ||||||
| # this must be used if any files are copied to the shared volume via |  | ||||||
| # non-AFP methods (directly, via Samba, etc). |  | ||||||
|  |  | ||||||
| # usage: |  | ||||||
| # afpsync [-v] [shared volume path] |  | ||||||
| # |  | ||||||
| # -v will silently create a .volinfo file if none exists. |  | ||||||
| # If a path is specified, only that volume is synced; otherwise, all |  | ||||||
| # all paths in /srv/A2SERVER which appear in |  | ||||||
| # /usr/local/etc/netatalk/AppleVolumes.default are synced. |  | ||||||
|  |  | ||||||
| processPath () { |  | ||||||
|     if [[ ! -d $sharepath ]]; then |  | ||||||
|         echo "$sharepath does not exist." |  | ||||||
|     else |  | ||||||
|         volinfo="$sharepath/.AppleDesktop/.volinfo" |  | ||||||
|         if [[ ! -f $volinfo ]]; then |  | ||||||
|             if [[ ! $force ]]; then |  | ||||||
|                 echo "Cannot update AppleDouble files for volume $sharepath," |  | ||||||
|                 echo "because its .volinfo file does not exist. To create it, log" |  | ||||||
|                 echo "into the volume from an Apple II or Mac client computer," |  | ||||||
|                 echo "or use \"afpsync -v\"." |  | ||||||
|             else |  | ||||||
|                 if (( $1 )); then |  | ||||||
|                     mkvolinfo -f -c $sharepath |  | ||||||
|                 else |  | ||||||
|                     mkvolinfo -f $sharepath |  | ||||||
|                 fi |  | ||||||
|                 $0 $sharepath |  | ||||||
|             fi |  | ||||||
|         else |  | ||||||
|             IFS='' |  | ||||||
|             result=$(sudo dbd -r $sharepath | grep encoding) |  | ||||||
|             f=$(wc -l <<< $result) |  | ||||||
|             [[ $(wc -w <<< $result) == 0 ]] && f=0 |  | ||||||
|             [[ $f -eq 1 && $(grep AppleDesktop <<< "$result") && $(grep MTOULOWER $sharepath/.AppleDesktop/.volinfo) ]] && (( f-- )) |  | ||||||
|             if (( f == 0 )); then |  | ||||||
|                 echo "AppleDouble files have been updated for volume $sharepath." |  | ||||||
|             else |  | ||||||
|                 [[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath." |  | ||||||
|                 if [[ $showerrors ]]; then |  | ||||||
|                     echo $result \ |  | ||||||
|                         | while read LINE; do |  | ||||||
|                         [[ ! $(echo $LINE | grep APPLEDESKTOP) ]] && echo $LINE |  | ||||||
|                     done |  | ||||||
|                 elif [[ $renameLower ]]; then |  | ||||||
|                     echo $result \ |  | ||||||
|                         | while read LINE; do |  | ||||||
|                         if [[ ! $(echo $LINE | grep APPLEDESKTOP) ]]; then |  | ||||||
|                             filepath=$(echo $LINE | sed "s/^Bad\ encoding\ for\ '//" | sed s/\'//) |  | ||||||
|                             filename=${filepath##*/} |  | ||||||
|                             filedir=${filepath%/*} |  | ||||||
|                             mv $filepath $filedir/${filename^^} |  | ||||||
|                             echo "Renamed $filedir/${filename^^}." |  | ||||||
|                         fi |  | ||||||
|                     done |  | ||||||
|                     $0 $sharepath |  | ||||||
|                 else |  | ||||||
|                     echo "Use afpsync -e to see error details." |  | ||||||
|                 fi |  | ||||||
|             fi |  | ||||||
|             unset IFS |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| while [[ $1 == "-r" || $1 == "-e" || $1 = "-v" ]]; do |  | ||||||
|  |  | ||||||
|     if [[ $1 == "-v" ]]; then |  | ||||||
|         force=1 |  | ||||||
|         shift |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [[ $1 == "-e" ]]; then |  | ||||||
|         showerrors=1 |  | ||||||
|         shift |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [[ $1 == "-r" ]]; then |  | ||||||
|         renameLower=1 |  | ||||||
|         shift |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
| done |  | ||||||
|  |  | ||||||
| if [[ ${1:0:1} == "-" ]]; then |  | ||||||
|     echo "Usage: afpsync [-e|-r] [-v] [shared volume path]" |  | ||||||
|     echo |  | ||||||
|     echo "-e: show error details" |  | ||||||
|     echo "-r: rename lowercase filenames to uppercase" |  | ||||||
|     echo "-v: create .volinfo file if none exists" |  | ||||||
|     echo "If no directory is specified, all found in" |  | ||||||
|     echo "  /usr/local/etc/netatalk/AppleVolumes.default are processed." |  | ||||||
|     echo |  | ||||||
| else |  | ||||||
|     sudo true |  | ||||||
|     if [[ $1 ]]; then |  | ||||||
|         sharepath=$(readlink -m $1) |  | ||||||
|         # behavior change in 1.3.0: now defaults to mixed case |  | ||||||
|         #   on a volume when specifying a folder and -v |  | ||||||
|         #   (as opposed to defaulting to casefold:toupper previously) |  | ||||||
|         processPath 1 |  | ||||||
|     else |  | ||||||
|         grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \ |  | ||||||
|             while read line; do |  | ||||||
|             [[ $(echo $line | grep toupper) ]]; nocasefold=$? |  | ||||||
|             sharepath=$(echo $line | cut -d" " -f1) |  | ||||||
|             processPath nocasefold |  | ||||||
|         done |  | ||||||
|     fi |  | ||||||
| fi |  | ||||||
							
								
								
									
										498
									
								
								scripts/tools/afptype
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										498
									
								
								scripts/tools/afptype
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,498 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # 2-25-11: tested on 10.6.5 and Ubuntu 10.10. Final. | ||||||
|  |  | ||||||
|  | # to do: allow hex offsets | ||||||
|  |  | ||||||
|  | # These bash functions perform single-byte dec-hex-character conversions | ||||||
|  | # and file read/write operations, and hopefully work identically across | ||||||
|  | # different platforms. Each can operate by itself without the presence | ||||||
|  | # of the others. They have been tested on Mac OS X 10.6 and | ||||||
|  | # Ubuntu Linux 10.10. Your mileage may vary. | ||||||
|  |  | ||||||
|  | # You provide parameters to the functions as arguments, or alternatively | ||||||
|  | # standard in (for the functions which accept characters). Examples: | ||||||
|  | #   Write hex byte with value "F0" to offset 23 in file "myFile": | ||||||
|  | # writecharHex myFile 23 F0 | ||||||
|  | #   Write "ABCDE" to the beginning of file "myFile" | ||||||
|  | # echo "ABCDE" | writechars myFile | ||||||
|  |  | ||||||
|  | # For functions which output something (all but the write operations), | ||||||
|  | # you can call the functions with command substitution if you want to | ||||||
|  | # assign the output to a variable rather than display it. Examples: | ||||||
|  | #   Convert decimal value 65 to its hexadecimal equivalent: | ||||||
|  | # val=$(decToHex 65) | ||||||
|  | #   Get decimal value of the character/byte at offset 215 in "myFile": | ||||||
|  | # val=$(readcharDec "myFile" 215) | ||||||
|  |  | ||||||
|  | # For functions which convert to or from a character, 0-127 will be | ||||||
|  | # ASCII/UTF-8, while 128-255 will be system/locale/codepage dependent. | ||||||
|  | # In this context, a character is effectively the same as a byte. | ||||||
|  |  | ||||||
|  | # The functions return a non-zero exit status for invalid or missing | ||||||
|  | # arguments. If you don't need these checks, remove the lines | ||||||
|  | # above the comment "args are valid" (or as otherwise noted). | ||||||
|  | # The exit statuses are, generally: | ||||||
|  | #    0 = no error | ||||||
|  | #    8 = extraneous argument | ||||||
|  | #    9 = standard input is invalid | ||||||
|  | #   1x = missing required argument (e.g. 11 for missing argument 1) | ||||||
|  | #   2x = argument is invalid (e.g. 22 for invalid argument 2) | ||||||
|  | # any other exit status will originate from the final command in the | ||||||
|  | # function (e.g. dd, printf) | ||||||
|  |  | ||||||
|  | # For the functions which output chars (readchars, decToChar, and | ||||||
|  | # hexToChar), be aware that NUL (0) and trailing LF (10/0x0A) chars will | ||||||
|  | # be stripped when assigned to a variable, and cannot appear in an | ||||||
|  | # argument. To preserve them, pipe the output elsewhere, such as into | ||||||
|  | # charToDec, charToHex, writechars, or a command. (readcharDec and | ||||||
|  | # readcharHex handle these characters correctly.) | ||||||
|  |  | ||||||
|  | # questions/comments to ivan@ivanx.com | ||||||
|  |  | ||||||
|  | decToHex () { | ||||||
|  | # converts single-byte decimal value to hexadecimal equivalent | ||||||
|  | # arg: decimal value from 0-255 | ||||||
|  | # out: two-digit hex value from 00-FF | ||||||
|  | #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $2 ]] && return 8 | ||||||
|  | 	[[ ( $(printf %d "$1" 2> /dev/null) == $1 ) \ | ||||||
|  | 		&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||||
|  | 	# args are valid | ||||||
|  | 	printf %02X "$1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | hexToDec () { | ||||||
|  | # converts single-byte hexadecimal value to decimal equivalent | ||||||
|  | # arg: two-digit hex value from 00-FF | ||||||
|  | # out: decimal value | ||||||
|  | #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $2 ]] && return 8 | ||||||
|  | 	[[ ${#1} -eq 2 ]] || return 21 | ||||||
|  | 	[[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||||
|  | 		$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 | ||||||
|  | 	# args are valid | ||||||
|  | 	printf %d "0x$1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | charToDec () { | ||||||
|  | # converts single character to corresponding decimal value | ||||||
|  | # stdin OR arg: one character | ||||||
|  | #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] | ||||||
|  | # out: decimal value from 0-255 | ||||||
|  | #exit: 8=extraneous arg, 9=invalid stdin, | ||||||
|  | #      11=missing stdin/arg, 21=invalid arg | ||||||
|  | 	[[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } | ||||||
|  | 	[[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } | ||||||
|  | 	# arg/stdin is potentially valid (additional check below) | ||||||
|  | 	charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" | ||||||
|  | 	[[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) | ||||||
|  | 	# above line verifies that arg/stdin is valid | ||||||
|  | 	[[ ${#charX} -ne 2 ]] && { echo -n 0; return 0; } | ||||||
|  | 	echo -n "${charX:0:1}" | od -t u1 | \ | ||||||
|  | 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | charToHex () { | ||||||
|  | # converts single character to corresponding hexadecimal value | ||||||
|  | # stdin OR arg: one character | ||||||
|  | #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] | ||||||
|  | # out: decimal value from 0-255 | ||||||
|  | #exit: 8=extraneous arg, 9=invalid stdin, | ||||||
|  | #      11=missing stdin/arg, 21=invalid arg | ||||||
|  | 	[[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } | ||||||
|  | 	[[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } | ||||||
|  | 	# arg/stdin is potentially valid (additional check below) | ||||||
|  | 	charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" | ||||||
|  | 	[[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) | ||||||
|  | 	# above line verifies that stdin/arg is valid | ||||||
|  | 	[[ ${#charX} -ne 2 ]] && { echo -n "00"; return 0; } | ||||||
|  | 	printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ | ||||||
|  | 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | decToChar () { | ||||||
|  | # converts single-byte decimal value to equivalent character | ||||||
|  | # arg: decimal number from 0-255 | ||||||
|  | # out: one character | ||||||
|  | #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $2 ]] && return 8 | ||||||
|  | 	[[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ | ||||||
|  | 		&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||||
|  | 	# args are valid | ||||||
|  | 	echo -n -e "\x$(printf %02X "$1")" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | hexToChar () { | ||||||
|  | # converts single-byte hexadecimal value to corresponding character | ||||||
|  | # arg: two-digit hexadecimal number from 00-FF | ||||||
|  | # out: one character | ||||||
|  | #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $2 ]] && return 8 | ||||||
|  | 	[[ ${#1} -eq 2 ]] || return 21 | ||||||
|  | 	[[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||||
|  | 		$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 | ||||||
|  | 	# args are valid | ||||||
|  | 	echo -n -e "\x$1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | readchars () { | ||||||
|  | # read one or more characters from a file | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: (optional) offset (# of bytes to skip before reading) | ||||||
|  | # arg3: (optional) # of chars to read (default is until end of file) | ||||||
|  | #  out: sequence of characters | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, | ||||||
|  | #       21=invalid arg1, 22=invalid arg2, 23=invalid arg3 | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $4 ]] && return 8 | ||||||
|  | 	[[ -f $1 ]] || return 21 | ||||||
|  | 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||||
|  | 		&& ( $2 -ge 0 ) ]] || return 22; } | ||||||
|  | 	[[ $3 ]] && { [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ | ||||||
|  | 		&& ( $3 -ge 0 ) ]] || return 23; } | ||||||
|  | 	# args are valid | ||||||
|  | 	dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \ | ||||||
|  | 		2> /dev/null | tr -d ' \0' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | readcharDec () { | ||||||
|  | # read one character from file & convert to equivalent decimal value | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: (optional) offset (# of bytes to skip before reading) | ||||||
|  | #  out: decimal value from 0-255 | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, | ||||||
|  | #       21=invalid arg1, 22=invalid arg2 | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $3 ]] && return 8 | ||||||
|  | 	[[ -f $1 ]] || return 21 | ||||||
|  | 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||||
|  | 		&& ( $2 -ge 0 ) ]] || return 22; } | ||||||
|  | 	# args are valid | ||||||
|  | 	charX="$(dd if="$1" bs=1 skip=$(($2)) \ | ||||||
|  | 		count=1 2> /dev/null | tr -d '\0'; echo -n X)" | ||||||
|  | 	[[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; } | ||||||
|  | 	echo -n "${charX:0:1}" | od -t u1 | \ | ||||||
|  | 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | readcharHex () { | ||||||
|  | # read one character from file & convert to corresponding hex value | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: (optional) offset (# of bytes to skip before reading) | ||||||
|  | #  out: two-digit hex value from 00-FF | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, | ||||||
|  | #       21=invalid arg1, 22=invalid arg2 | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $3 ]] && return 8 | ||||||
|  | 	[[ -f $1 ]] || return 21 | ||||||
|  | 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||||
|  | 		&& ( $2 -ge 0 ) ]] || return 22; } | ||||||
|  | 	# args are valid | ||||||
|  | 	charX="$(dd if="$1" bs=1 skip=$(($2)) \ | ||||||
|  | 		count=1 2> /dev/null | tr -d '\0'; echo -n X)" | ||||||
|  | 	[[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } | ||||||
|  | 	printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ | ||||||
|  | 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ### 2-15-11 above tested on OS X and Linux | ||||||
|  |  | ||||||
|  | writechars () { | ||||||
|  | # write one or more characters (bytes) to file | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: (optional) offset (# of bytes to skip before writing) | ||||||
|  | # arg3 OR stdin: sequence of characters | ||||||
|  | #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] | ||||||
|  | #  out: nothing | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, | ||||||
|  | #       13=missing stdin/arg3, 22=invalid arg2 | ||||||
|  | 	[[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } | ||||||
|  | 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ | ||||||
|  | 		( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } | ||||||
|  | 	[[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } | ||||||
|  | 	[[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } | ||||||
|  | 	# args are valid | ||||||
|  | 	if [[ -t 0 ]]; then | ||||||
|  | 		echo -n "$3" | \ | ||||||
|  | 			dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||||
|  | 	else | ||||||
|  | 		dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | writecharDec () { | ||||||
|  | # write corresponding character of single-byte decimal value into file | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: offset (# of bytes to skip before writing) | ||||||
|  | # arg3: decimal number from 0-255 | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, | ||||||
|  | #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 | ||||||
|  | #  out: nothing | ||||||
|  | 	[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 | ||||||
|  | 	[[ $4 ]] && return 8 | ||||||
|  | 	[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||||
|  | 		&& ( $2 -ge 0 ) ]] || return 22 | ||||||
|  | 	[[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ | ||||||
|  | 		&& ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23 | ||||||
|  | 	# args are valid | ||||||
|  | 	echo -n -e "\x$(printf %02X "$3")" | \ | ||||||
|  | 		dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | writecharHex () { | ||||||
|  | # write corresponding character of single-byte hex value into file | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: offset (# of bytes to skip before writing) | ||||||
|  | # arg3: two-digit hexadecimal number from 00-FF | ||||||
|  | #  out: nothing | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, | ||||||
|  | #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 | ||||||
|  | 	[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 | ||||||
|  | 	[[ $4 ]] && return 8 | ||||||
|  | 	[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||||
|  | 		&& ( $2 -ge 0 ) ]] || return 22 | ||||||
|  | 	[[ $(printf %02X "0x$3" 2> /dev/null) == \ | ||||||
|  | 		$(echo -n "$3" | tr [a-z] [A-Z]) ]] || return 23 | ||||||
|  | 	# args are valid | ||||||
|  | 	echo -n -e "\x$3" | \ | ||||||
|  | 		dd of="$1" bs=1 seek=$2 conv=notrunc 2> /dev/null | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # --- afptype is below this line | ||||||
|  |  | ||||||
|  | isHexByte () { | ||||||
|  | 	[[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||||
|  | 	$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # support 00 and 0A as filetype chars? | ||||||
|  |  | ||||||
|  | debug=1 | ||||||
|  | ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" | ||||||
|  |  | ||||||
|  | quit () { | ||||||
|  | 	if [[ $2 && $debug ]]; then | ||||||
|  | 		echo "$1" "$2" | ||||||
|  | 	else | ||||||
|  | 		echo -e "Error: $1" | ||||||
|  | 	fi | ||||||
|  | 	exit_usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | exit_usage () { | ||||||
|  | 	echo "Usage:" | ||||||
|  | 	echo | ||||||
|  | 	echo "show types: afptype filename" | ||||||
|  | 	echo "set Mac OS: afptype [-t 'type'] [-c 'creator'] [-q] filename" | ||||||
|  | 	echo "set ProDOS: afptype [-p type] [-a auxtype] [-q] filename" | ||||||
|  | 	echo "Mac OS type or creator must be four characters; use \x plus" | ||||||
|  | 	echo "  two hex digits for untypeables (note: use '\xZZ' for 00)." | ||||||
|  | 	echo "ProDOS type should be two hex digits, and auxtype should be four;" | ||||||
|  | 	echo "  type can alternatively be BAS, BIN, INT, P16, S16, SHK, SYS, TXT." | ||||||
|  | 	echo "-q skips recheck of file (show types) after setting" | ||||||
|  | 	echo | ||||||
|  | 	exit 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | lookupPdosType () { | ||||||
|  | # looks up ProDOS hex type from code in list 'ptypes' | ||||||
|  | # arg: three-character code | ||||||
|  | # out: two-digit hex value | ||||||
|  | #exit: 0=type found, 1=error, 2=type not found | ||||||
|  | 	ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" | ||||||
|  | 	[[ $1 ]] || quit "lookupPdosType:" "no argument supplied ($1)" | ||||||
|  | 	[[ ${#1} -eq 3 ]] || return 1 | ||||||
|  | 	arg=$(echo -n "$1" | tr [a-z] [A-Z]) | ||||||
|  | 	for ptype in $ptypes; do | ||||||
|  | 		if [[ ${ptype:3:3} == $arg ]]; then | ||||||
|  | 			echo -n "${ptype:0:2}" | ||||||
|  | 			return 0 | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  | 	echo "$1" | ||||||
|  | 	return 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | verifyTC () { | ||||||
|  | 	[[ $1 ]] || return 1 | ||||||
|  | 	tcX="$(echo -e -n "$1"X)" | ||||||
|  | 	[[ ${#tcX} -eq 5 ]] || return 1 | ||||||
|  | 	echo "$tcX" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | while [[ $1 && ( "${1:0:1}" == '-' ) ]]; do | ||||||
|  | 	if [[ $1 == "-p" ]]; then | ||||||
|  | 		[[ $p ]] && exit_usage | ||||||
|  | 		shift | ||||||
|  | 		p="$1" | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [[ $1 == "-a" ]]; then | ||||||
|  | 		[[ $a ]] && exit_usage | ||||||
|  | 		shift | ||||||
|  | 		a="$1" | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [[ $1 == "-t" ]]; then | ||||||
|  | 		[[ $t ]] && exit_usage | ||||||
|  | 		shift | ||||||
|  | 		t="$1" | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [[ $1 == "-c" ]]; then | ||||||
|  | 		[[ $c ]] && exit_usage | ||||||
|  | 		shift | ||||||
|  | 		c="$1" | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [[ $1 == "-q" ]]; then | ||||||
|  | 		[[ $q ]] && exit_usage | ||||||
|  | 		q=1 | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	else | ||||||
|  | 		exit_usage | ||||||
|  | 		break | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [[ ( ( $p || $a ) && ( $t || $c ) ) || ( -z $1 ) ]]; then | ||||||
|  | 	exit_usage | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | #filename="$1" | ||||||
|  | #shift | ||||||
|  |  | ||||||
|  | for filename in $@; do | ||||||
|  |  | ||||||
|  | 	[[ ${#@} -gt 1 ]] && linestart="($filename) " | ||||||
|  |  | ||||||
|  | 	if [[ ! -f $filename ]]; then | ||||||
|  | 		echo "${linestart}Not found." | ||||||
|  | 		continue | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	adname="$(dirname "$filename")/.AppleDouble/$(basename "$filename")" | ||||||
|  | 	[[ -f $adname ]] && filename=$adname | ||||||
|  | 	ADversion=$(readcharDec "$filename" 5) | ||||||
|  | 	if [[ ( ( $ADversion -ne 1 ) && ( $ADversion -ne 2 ) ) \ | ||||||
|  | 		|| ( "$(readchars "$filename" 1 3)" != "$(echo -e -n "\x05\x16\x07")" ) \ | ||||||
|  | 		|| ( $(readcharDec "$filename" 0) -ne 0 ) \ | ||||||
|  | 		|| ( $(readcharDec "$filename" 4) -ne 0 ) \ | ||||||
|  | 		|| ( $(readcharDec "$filename" 6) -ne 0 ) \ | ||||||
|  | 		|| ( $(readcharDec "$filename" 7) -ne 0 ) ]]; then | ||||||
|  | 		echo "${linestart}Not an AppleDouble file." | ||||||
|  | 		continue | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	entrycount=`readcharDec "$filename" 25` | ||||||
|  |  | ||||||
|  | 	entry=1 | ||||||
|  | 	offset=29 | ||||||
|  |  | ||||||
|  | 	while [[ $(readcharDec "$filename" $offset) -ne 9 ]]; do | ||||||
|  | 		(( entry = entry + 1 )) | ||||||
|  | 		if (( entry > entrycount )); then | ||||||
|  | 			echo "${linestart}Finder Info entry not found in AppleDouble file." | ||||||
|  | 			break | ||||||
|  | 		fi | ||||||
|  | 		(( offset = (entry * 12 + 29) - 12 )) | ||||||
|  | 	done | ||||||
|  | 	(( entry > entrycount )) && continue | ||||||
|  |  | ||||||
|  | 	(( offset = offset + 3 )) | ||||||
|  | 	(( tposHi = $(readcharDec "$filename" $offset) * 256 )) | ||||||
|  | 	(( offset = offset + 1 )) | ||||||
|  | 	(( tpos = $(readcharDec "$filename" $offset) + tposHi )) | ||||||
|  | 	(( cpos = tpos + 4 )) | ||||||
|  | 	(( ppos = tpos + 1 )) | ||||||
|  | 	(( apos = tpos + 2 )) | ||||||
|  |  | ||||||
|  | 	if [[ $p || $a || $t || $c ]]; then # set | ||||||
|  | 		if [[ $p || $a ]]; then | ||||||
|  | 			if [[ $p ]]; then | ||||||
|  | 				[[ ${#p} -eq 3 ]] && { p=$(lookupPdosType $p) || quit "Invalid ProDOS type name ($p)."; } | ||||||
|  | 				isHexByte "$p" || quit "Invalid ProDOS file type ($p)." | ||||||
|  | 				writecharHex "$filename" $ppos "$p" | ||||||
|  | 			fi | ||||||
|  | 			if [[ $a ]]; then | ||||||
|  | 				isHexByte "${a:0:2}" && isHexByte "${a:2:2}" || quit "Invalid ProDOS aux type ($a)." | ||||||
|  | 				writecharHex "$filename" $apos "${a:0:2}" | ||||||
|  | 				(( apos=apos+1 )) | ||||||
|  | 				writecharHex "$filename" $apos "${a:2:2}" | ||||||
|  | 			fi | ||||||
|  | 			writechars "$filename" $tpos "p" | ||||||
|  | 			writechars "$filename" $cpos "pdos" | ||||||
|  | 		elif [[ $t || $c ]]; then | ||||||
|  | 			if [[ $t ]]; then | ||||||
|  | 				type=$(verifyTC "$t") || quit "$(echo -n "Invalid Mac file type ($t)."; [[ $t == *x* ]] && echo -n " Try quotes."; echo)" | ||||||
|  | 				writechars "$filename" $tpos "${type:0:4}" | ||||||
|  | 			fi | ||||||
|  | 			if [[ $c ]]; then | ||||||
|  | 				creator=$(verifyTC "$c") || quit "$(echo -n "Invalid Mac file creator ($c)."; [[ $c == *x* ]] && echo -n " Try quotes."; echo)" | ||||||
|  | 				writechars "$filename" $cpos "${creator:0:4}" | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  | 		[[ $q ]] || { echo -n "${linestart}File changed: "; "$0" "$filename"; } | ||||||
|  |  | ||||||
|  | 	else # show | ||||||
|  | 		[[ $q ]] && quit "Can only use -q when changing type." | ||||||
|  |  | ||||||
|  | 		type="$(readchars "$filename" $tpos 4)" | ||||||
|  | 		creator="$(readchars "$filename" $cpos 4)" | ||||||
|  |  | ||||||
|  | 		echo -n "$linestart" | ||||||
|  |  | ||||||
|  | 		if [[ $creator != "pdos" || ( ( $type != "TEXT" ) \ | ||||||
|  | 			&& ( $type != "PSYS" ) && ( ${type:0:1} != "p" ) ) ]]; then | ||||||
|  | 			if [[ $creator || $type ]]; then | ||||||
|  | 				echo "Mac file.   Type:$type   Creator:$creator" | ||||||
|  | 			else | ||||||
|  | 				echo "This file has no Mac or ProDOS file type information." | ||||||
|  | 			fi | ||||||
|  | 			continue | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		if [[ $type == "TEXT" ]]; then | ||||||
|  | 			pdosType="\$04 [TXT]" | ||||||
|  | 			pdosAuxType='$0000' | ||||||
|  | 		elif [[ $type == "PSYS" ]]; then | ||||||
|  | 			pdosType="\$FF [SYS]" | ||||||
|  | 			pdosAuxType='$0000' | ||||||
|  | 		else | ||||||
|  | 			(( tpos=tpos+1 )) | ||||||
|  | 			pdosType=$(readcharHex "$filename" $tpos) | ||||||
|  | 			for ptype in $ptypes; do | ||||||
|  | 				if [[ "${ptype:0:2}" == "$pdosType" ]]; then | ||||||
|  | 					pdosType="$pdosType [${ptype:3:3}]" | ||||||
|  | 					break | ||||||
|  | 				fi | ||||||
|  | 			done | ||||||
|  |  | ||||||
|  | 			(( tpos=tpos+1 )) | ||||||
|  | 			auxTypeHi=$(readcharHex "$filename" $tpos) | ||||||
|  | 			(( tpos=tpos+1 )) | ||||||
|  | 			auxTypeLo=$(readcharHex "$filename" $tpos) | ||||||
|  | 			pdosAuxType=$auxTypeHi$auxTypeLo | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		echo "ProDOS file.  Type:\$$pdosType   AuxType:\$$pdosAuxType" | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # 7-19-11 | ||||||
|  | # quick ProDOS testing/fixing on Linux, needs more | ||||||
|  | # Mac Type testing not done yet, nor testing on a Mac | ||||||
|  |  | ||||||
|  | # test on lunix | ||||||
|  | # test inside and outside of AD directory, and from other dirs (both cases) | ||||||
|  | # finish conversion writebyte/readchar library | ||||||
|  | # consider return 2 for missing parameters for subroutines | ||||||
| @@ -1,498 +0,0 @@ | |||||||
| #! /bin/bash |  | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: |  | ||||||
|  |  | ||||||
| # 2-25-11: tested on 10.6.5 and Ubuntu 10.10. Final. |  | ||||||
|  |  | ||||||
| # to do: allow hex offsets |  | ||||||
|  |  | ||||||
| # These bash functions perform single-byte dec-hex-character conversions |  | ||||||
| # and file read/write operations, and hopefully work identically across |  | ||||||
| # different platforms. Each can operate by itself without the presence |  | ||||||
| # of the others. They have been tested on Mac OS X 10.6 and |  | ||||||
| # Ubuntu Linux 10.10. Your mileage may vary. |  | ||||||
|  |  | ||||||
| # You provide parameters to the functions as arguments, or alternatively |  | ||||||
| # standard in (for the functions which accept characters). Examples: |  | ||||||
| #   Write hex byte with value "F0" to offset 23 in file "myFile": |  | ||||||
| # writecharHex myFile 23 F0 |  | ||||||
| #   Write "ABCDE" to the beginning of file "myFile" |  | ||||||
| # echo "ABCDE" | writechars myFile |  | ||||||
|  |  | ||||||
| # For functions which output something (all but the write operations), |  | ||||||
| # you can call the functions with command substitution if you want to |  | ||||||
| # assign the output to a variable rather than display it. Examples: |  | ||||||
| #   Convert decimal value 65 to its hexadecimal equivalent: |  | ||||||
| # val=$(decToHex 65) |  | ||||||
| #   Get decimal value of the character/byte at offset 215 in "myFile": |  | ||||||
| # val=$(readcharDec "myFile" 215) |  | ||||||
|  |  | ||||||
| # For functions which convert to or from a character, 0-127 will be |  | ||||||
| # ASCII/UTF-8, while 128-255 will be system/locale/codepage dependent. |  | ||||||
| # In this context, a character is effectively the same as a byte. |  | ||||||
|  |  | ||||||
| # The functions return a non-zero exit status for invalid or missing |  | ||||||
| # arguments. If you don't need these checks, remove the lines |  | ||||||
| # above the comment "args are valid" (or as otherwise noted). |  | ||||||
| # The exit statuses are, generally: |  | ||||||
| #    0 = no error |  | ||||||
| #    8 = extraneous argument |  | ||||||
| #    9 = standard input is invalid |  | ||||||
| #   1x = missing required argument (e.g. 11 for missing argument 1) |  | ||||||
| #   2x = argument is invalid (e.g. 22 for invalid argument 2) |  | ||||||
| # any other exit status will originate from the final command in the |  | ||||||
| # function (e.g. dd, printf) |  | ||||||
|  |  | ||||||
| # For the functions which output chars (readchars, decToChar, and |  | ||||||
| # hexToChar), be aware that NUL (0) and trailing LF (10/0x0A) chars will |  | ||||||
| # be stripped when assigned to a variable, and cannot appear in an |  | ||||||
| # argument. To preserve them, pipe the output elsewhere, such as into |  | ||||||
| # charToDec, charToHex, writechars, or a command. (readcharDec and |  | ||||||
| # readcharHex handle these characters correctly.) |  | ||||||
|  |  | ||||||
| # questions/comments to ivan@ivanx.com |  | ||||||
|  |  | ||||||
| decToHex () { |  | ||||||
| # converts single-byte decimal value to hexadecimal equivalent |  | ||||||
| # arg: decimal value from 0-255 |  | ||||||
| # out: two-digit hex value from 00-FF |  | ||||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $2 ]] && return 8 |  | ||||||
|     [[ ( $(printf %d "$1" 2> /dev/null) == $1 ) \ |  | ||||||
|         && ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 |  | ||||||
|     # args are valid |  | ||||||
|     printf %02X "$1" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| hexToDec () { |  | ||||||
| # converts single-byte hexadecimal value to decimal equivalent |  | ||||||
| # arg: two-digit hex value from 00-FF |  | ||||||
| # out: decimal value |  | ||||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $2 ]] && return 8 |  | ||||||
|     [[ ${#1} -eq 2 ]] || return 21 |  | ||||||
|     [[ $(printf %02X "0x$1" 2> /dev/null) == \ |  | ||||||
|         $(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 |  | ||||||
|     # args are valid |  | ||||||
|     printf %d "0x$1" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| charToDec () { |  | ||||||
| # converts single character to corresponding decimal value |  | ||||||
| # stdin OR arg: one character |  | ||||||
| #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] |  | ||||||
| # out: decimal value from 0-255 |  | ||||||
| #exit: 8=extraneous arg, 9=invalid stdin, |  | ||||||
| #      11=missing stdin/arg, 21=invalid arg |  | ||||||
|     [[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } |  | ||||||
|     [[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } |  | ||||||
|     # arg/stdin is potentially valid (additional check below) |  | ||||||
|     charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" |  | ||||||
|     [[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) |  | ||||||
|     # above line verifies that arg/stdin is valid |  | ||||||
|     [[ ${#charX} -ne 2 ]] && { echo -n 0; return 0; } |  | ||||||
|     echo -n "${charX:0:1}" | od -t u1 | \ |  | ||||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| charToHex () { |  | ||||||
| # converts single character to corresponding hexadecimal value |  | ||||||
| # stdin OR arg: one character |  | ||||||
| #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] |  | ||||||
| # out: decimal value from 0-255 |  | ||||||
| #exit: 8=extraneous arg, 9=invalid stdin, |  | ||||||
| #      11=missing stdin/arg, 21=invalid arg |  | ||||||
|     [[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } |  | ||||||
|     [[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } |  | ||||||
|     # arg/stdin is potentially valid (additional check below) |  | ||||||
|     charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" |  | ||||||
|     [[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) |  | ||||||
|     # above line verifies that stdin/arg is valid |  | ||||||
|     [[ ${#charX} -ne 2 ]] && { echo -n "00"; return 0; } |  | ||||||
|     printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ |  | ||||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n') |  | ||||||
| } |  | ||||||
|  |  | ||||||
| decToChar () { |  | ||||||
| # converts single-byte decimal value to equivalent character |  | ||||||
| # arg: decimal number from 0-255 |  | ||||||
| # out: one character |  | ||||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $2 ]] && return 8 |  | ||||||
|     [[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ |  | ||||||
|         && ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 |  | ||||||
|     # args are valid |  | ||||||
|     echo -n -e "\x$(printf %02X "$1")" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| hexToChar () { |  | ||||||
| # converts single-byte hexadecimal value to corresponding character |  | ||||||
| # arg: two-digit hexadecimal number from 00-FF |  | ||||||
| # out: one character |  | ||||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $2 ]] && return 8 |  | ||||||
|     [[ ${#1} -eq 2 ]] || return 21 |  | ||||||
|     [[ $(printf %02X "0x$1" 2> /dev/null) == \ |  | ||||||
|         $(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 |  | ||||||
|     # args are valid |  | ||||||
|     echo -n -e "\x$1" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| readchars () { |  | ||||||
| # read one or more characters from a file |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: (optional) offset (# of bytes to skip before reading) |  | ||||||
| # arg3: (optional) # of chars to read (default is until end of file) |  | ||||||
| #  out: sequence of characters |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, |  | ||||||
| #       21=invalid arg1, 22=invalid arg2, 23=invalid arg3 |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $4 ]] && return 8 |  | ||||||
|     [[ -f $1 ]] || return 21 |  | ||||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ |  | ||||||
|         && ( $2 -ge 0 ) ]] || return 22; } |  | ||||||
|     [[ $3 ]] && { [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ |  | ||||||
|         && ( $3 -ge 0 ) ]] || return 23; } |  | ||||||
|     # args are valid |  | ||||||
|     dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \ |  | ||||||
|         2> /dev/null | tr -d ' \0' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| readcharDec () { |  | ||||||
| # read one character from file & convert to equivalent decimal value |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: (optional) offset (# of bytes to skip before reading) |  | ||||||
| #  out: decimal value from 0-255 |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, |  | ||||||
| #       21=invalid arg1, 22=invalid arg2 |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $3 ]] && return 8 |  | ||||||
|     [[ -f $1 ]] || return 21 |  | ||||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ |  | ||||||
|         && ( $2 -ge 0 ) ]] || return 22; } |  | ||||||
|     # args are valid |  | ||||||
|     charX="$(dd if="$1" bs=1 skip=$(($2)) \ |  | ||||||
|         count=1 2> /dev/null | tr -d '\0'; echo -n X)" |  | ||||||
|     [[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; } |  | ||||||
|     echo -n "${charX:0:1}" | od -t u1 | \ |  | ||||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| readcharHex () { |  | ||||||
| # read one character from file & convert to corresponding hex value |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: (optional) offset (# of bytes to skip before reading) |  | ||||||
| #  out: two-digit hex value from 00-FF |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, |  | ||||||
| #       21=invalid arg1, 22=invalid arg2 |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $3 ]] && return 8 |  | ||||||
|     [[ -f $1 ]] || return 21 |  | ||||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ |  | ||||||
|         && ( $2 -ge 0 ) ]] || return 22; } |  | ||||||
|     # args are valid |  | ||||||
|     charX="$(dd if="$1" bs=1 skip=$(($2)) \ |  | ||||||
|         count=1 2> /dev/null | tr -d '\0'; echo -n X)" |  | ||||||
|     [[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } |  | ||||||
|     printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ |  | ||||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n') |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ### 2-15-11 above tested on OS X and Linux |  | ||||||
|  |  | ||||||
| writechars () { |  | ||||||
| # write one or more characters (bytes) to file |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: (optional) offset (# of bytes to skip before writing) |  | ||||||
| # arg3 OR stdin: sequence of characters |  | ||||||
| #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] |  | ||||||
| #  out: nothing |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, |  | ||||||
| #       13=missing stdin/arg3, 22=invalid arg2 |  | ||||||
|     [[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } |  | ||||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ |  | ||||||
|         ( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } |  | ||||||
|     [[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } |  | ||||||
|     [[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } |  | ||||||
|     # args are valid |  | ||||||
|     if [[ -t 0 ]]; then |  | ||||||
|         echo -n "$3" | \ |  | ||||||
|             dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null |  | ||||||
|     else |  | ||||||
|         dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| writecharDec () { |  | ||||||
| # write corresponding character of single-byte decimal value into file |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: offset (# of bytes to skip before writing) |  | ||||||
| # arg3: decimal number from 0-255 |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, |  | ||||||
| #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 |  | ||||||
| #  out: nothing |  | ||||||
|     [[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 |  | ||||||
|     [[ $4 ]] && return 8 |  | ||||||
|     [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ |  | ||||||
|         && ( $2 -ge 0 ) ]] || return 22 |  | ||||||
|     [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ |  | ||||||
|         && ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23 |  | ||||||
|     # args are valid |  | ||||||
|     echo -n -e "\x$(printf %02X "$3")" | \ |  | ||||||
|         dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null |  | ||||||
| } |  | ||||||
|  |  | ||||||
| writecharHex () { |  | ||||||
| # write corresponding character of single-byte hex value into file |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: offset (# of bytes to skip before writing) |  | ||||||
| # arg3: two-digit hexadecimal number from 00-FF |  | ||||||
| #  out: nothing |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, |  | ||||||
| #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 |  | ||||||
|     [[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 |  | ||||||
|     [[ $4 ]] && return 8 |  | ||||||
|     [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ |  | ||||||
|         && ( $2 -ge 0 ) ]] || return 22 |  | ||||||
|     [[ $(printf %02X "0x$3" 2> /dev/null) == \ |  | ||||||
|         $(echo -n "$3" | tr [a-z] [A-Z]) ]] || return 23 |  | ||||||
|     # args are valid |  | ||||||
|     echo -n -e "\x$3" | \ |  | ||||||
|         dd of="$1" bs=1 seek=$2 conv=notrunc 2> /dev/null |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # --- afptype is below this line |  | ||||||
|  |  | ||||||
| isHexByte () { |  | ||||||
|     [[ $(printf %02X "0x$1" 2> /dev/null) == \ |  | ||||||
|     $(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # support 00 and 0A as filetype chars? |  | ||||||
|  |  | ||||||
| debug=1 |  | ||||||
| ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" |  | ||||||
|  |  | ||||||
| quit () { |  | ||||||
|     if [[ $2 && $debug ]]; then |  | ||||||
|         echo "$1" "$2" |  | ||||||
|     else |  | ||||||
|         echo -e "Error: $1" |  | ||||||
|     fi |  | ||||||
|     exit_usage |  | ||||||
| } |  | ||||||
|  |  | ||||||
| exit_usage () { |  | ||||||
|     echo "Usage:" |  | ||||||
|     echo |  | ||||||
|     echo "show types: afptype filename" |  | ||||||
|     echo "set Mac OS: afptype [-t 'type'] [-c 'creator'] [-q] filename" |  | ||||||
|     echo "set ProDOS: afptype [-p type] [-a auxtype] [-q] filename" |  | ||||||
|     echo "Mac OS type or creator must be four characters; use \x plus" |  | ||||||
|     echo "  two hex digits for untypeables (note: use '\xZZ' for 00)." |  | ||||||
|     echo "ProDOS type should be two hex digits, and auxtype should be four;" |  | ||||||
|     echo "  type can alternatively be BAS, BIN, INT, P16, S16, SHK, SYS, TXT." |  | ||||||
|     echo "-q skips recheck of file (show types) after setting" |  | ||||||
|     echo |  | ||||||
|     exit 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| lookupPdosType () { |  | ||||||
| # looks up ProDOS hex type from code in list 'ptypes' |  | ||||||
| # arg: three-character code |  | ||||||
| # out: two-digit hex value |  | ||||||
| #exit: 0=type found, 1=error, 2=type not found |  | ||||||
|     ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" |  | ||||||
|     [[ $1 ]] || quit "lookupPdosType:" "no argument supplied ($1)" |  | ||||||
|     [[ ${#1} -eq 3 ]] || return 1 |  | ||||||
|     arg=$(echo -n "$1" | tr [a-z] [A-Z]) |  | ||||||
|     for ptype in $ptypes; do |  | ||||||
|         if [[ ${ptype:3:3} == $arg ]]; then |  | ||||||
|             echo -n "${ptype:0:2}" |  | ||||||
|             return 0 |  | ||||||
|         fi |  | ||||||
|     done |  | ||||||
|     echo "$1" |  | ||||||
|     return 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| verifyTC () { |  | ||||||
|     [[ $1 ]] || return 1 |  | ||||||
|     tcX="$(echo -e -n "$1"X)" |  | ||||||
|     [[ ${#tcX} -eq 5 ]] || return 1 |  | ||||||
|     echo "$tcX" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| while [[ $1 && ( "${1:0:1}" == '-' ) ]]; do |  | ||||||
|     if [[ $1 == "-p" ]]; then |  | ||||||
|         [[ $p ]] && exit_usage |  | ||||||
|         shift |  | ||||||
|         p="$1" |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [[ $1 == "-a" ]]; then |  | ||||||
|         [[ $a ]] && exit_usage |  | ||||||
|         shift |  | ||||||
|         a="$1" |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [[ $1 == "-t" ]]; then |  | ||||||
|         [[ $t ]] && exit_usage |  | ||||||
|         shift |  | ||||||
|         t="$1" |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [[ $1 == "-c" ]]; then |  | ||||||
|         [[ $c ]] && exit_usage |  | ||||||
|         shift |  | ||||||
|         c="$1" |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [[ $1 == "-q" ]]; then |  | ||||||
|         [[ $q ]] && exit_usage |  | ||||||
|         q=1 |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     else |  | ||||||
|         exit_usage |  | ||||||
|         break |  | ||||||
|     fi |  | ||||||
| done |  | ||||||
|  |  | ||||||
| if [[ ( ( $p || $a ) && ( $t || $c ) ) || ( -z $1 ) ]]; then |  | ||||||
|     exit_usage |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| #filename="$1" |  | ||||||
| #shift |  | ||||||
|  |  | ||||||
| for filename in $@; do |  | ||||||
|  |  | ||||||
|     [[ ${#@} -gt 1 ]] && linestart="($filename) " |  | ||||||
|  |  | ||||||
|     if [[ ! -f $filename ]]; then |  | ||||||
|         echo "${linestart}Not found." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     adname="$(dirname "$filename")/.AppleDouble/$(basename "$filename")" |  | ||||||
|     [[ -f $adname ]] && filename=$adname |  | ||||||
|     ADversion=$(readcharDec "$filename" 5) |  | ||||||
|     if [[ ( ( $ADversion -ne 1 ) && ( $ADversion -ne 2 ) ) \ |  | ||||||
|         || ( "$(readchars "$filename" 1 3)" != "$(echo -e -n "\x05\x16\x07")" ) \ |  | ||||||
|         || ( $(readcharDec "$filename" 0) -ne 0 ) \ |  | ||||||
|         || ( $(readcharDec "$filename" 4) -ne 0 ) \ |  | ||||||
|         || ( $(readcharDec "$filename" 6) -ne 0 ) \ |  | ||||||
|         || ( $(readcharDec "$filename" 7) -ne 0 ) ]]; then |  | ||||||
|         echo "${linestart}Not an AppleDouble file." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     entrycount=`readcharDec "$filename" 25` |  | ||||||
|  |  | ||||||
|     entry=1 |  | ||||||
|     offset=29 |  | ||||||
|  |  | ||||||
|     while [[ $(readcharDec "$filename" $offset) -ne 9 ]]; do |  | ||||||
|         (( entry = entry + 1 )) |  | ||||||
|         if (( entry > entrycount )); then |  | ||||||
|             echo "${linestart}Finder Info entry not found in AppleDouble file." |  | ||||||
|             break |  | ||||||
|         fi |  | ||||||
|         (( offset = (entry * 12 + 29) - 12 )) |  | ||||||
|     done |  | ||||||
|     (( entry > entrycount )) && continue |  | ||||||
|  |  | ||||||
|     (( offset = offset + 3 )) |  | ||||||
|     (( tposHi = $(readcharDec "$filename" $offset) * 256 )) |  | ||||||
|     (( offset = offset + 1 )) |  | ||||||
|     (( tpos = $(readcharDec "$filename" $offset) + tposHi )) |  | ||||||
|     (( cpos = tpos + 4 )) |  | ||||||
|     (( ppos = tpos + 1 )) |  | ||||||
|     (( apos = tpos + 2 )) |  | ||||||
|  |  | ||||||
|     if [[ $p || $a || $t || $c ]]; then # set |  | ||||||
|         if [[ $p || $a ]]; then |  | ||||||
|             if [[ $p ]]; then |  | ||||||
|                 [[ ${#p} -eq 3 ]] && { p=$(lookupPdosType $p) || quit "Invalid ProDOS type name ($p)."; } |  | ||||||
|                 isHexByte "$p" || quit "Invalid ProDOS file type ($p)." |  | ||||||
|                 writecharHex "$filename" $ppos "$p" |  | ||||||
|             fi |  | ||||||
|             if [[ $a ]]; then |  | ||||||
|                 isHexByte "${a:0:2}" && isHexByte "${a:2:2}" || quit "Invalid ProDOS aux type ($a)." |  | ||||||
|                 writecharHex "$filename" $apos "${a:0:2}" |  | ||||||
|                 (( apos=apos+1 )) |  | ||||||
|                 writecharHex "$filename" $apos "${a:2:2}" |  | ||||||
|             fi |  | ||||||
|             writechars "$filename" $tpos "p" |  | ||||||
|             writechars "$filename" $cpos "pdos" |  | ||||||
|         elif [[ $t || $c ]]; then |  | ||||||
|             if [[ $t ]]; then |  | ||||||
|                 type=$(verifyTC "$t") || quit "$(echo -n "Invalid Mac file type ($t)."; [[ $t == *x* ]] && echo -n " Try quotes."; echo)" |  | ||||||
|                 writechars "$filename" $tpos "${type:0:4}" |  | ||||||
|             fi |  | ||||||
|             if [[ $c ]]; then |  | ||||||
|                 creator=$(verifyTC "$c") || quit "$(echo -n "Invalid Mac file creator ($c)."; [[ $c == *x* ]] && echo -n " Try quotes."; echo)" |  | ||||||
|                 writechars "$filename" $cpos "${creator:0:4}" |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|         [[ $q ]] || { echo -n "${linestart}File changed: "; "$0" "$filename"; } |  | ||||||
|  |  | ||||||
|     else # show |  | ||||||
|         [[ $q ]] && quit "Can only use -q when changing type." |  | ||||||
|  |  | ||||||
|         type="$(readchars "$filename" $tpos 4)" |  | ||||||
|         creator="$(readchars "$filename" $cpos 4)" |  | ||||||
|  |  | ||||||
|         echo -n "$linestart" |  | ||||||
|  |  | ||||||
|         if [[ $creator != "pdos" || ( ( $type != "TEXT" ) \ |  | ||||||
|             && ( $type != "PSYS" ) && ( ${type:0:1} != "p" ) ) ]]; then |  | ||||||
|             if [[ $creator || $type ]]; then |  | ||||||
|                 echo "Mac file.   Type:$type   Creator:$creator" |  | ||||||
|             else |  | ||||||
|                 echo "This file has no Mac or ProDOS file type information." |  | ||||||
|             fi |  | ||||||
|             continue |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         if [[ $type == "TEXT" ]]; then |  | ||||||
|             pdosType="\$04 [TXT]" |  | ||||||
|             pdosAuxType='$0000' |  | ||||||
|         elif [[ $type == "PSYS" ]]; then |  | ||||||
|             pdosType="\$FF [SYS]" |  | ||||||
|             pdosAuxType='$0000' |  | ||||||
|         else |  | ||||||
|             (( tpos=tpos+1 )) |  | ||||||
|             pdosType=$(readcharHex "$filename" $tpos) |  | ||||||
|             for ptype in $ptypes; do |  | ||||||
|                 if [[ "${ptype:0:2}" == "$pdosType" ]]; then |  | ||||||
|                     pdosType="$pdosType [${ptype:3:3}]" |  | ||||||
|                     break |  | ||||||
|                 fi |  | ||||||
|             done |  | ||||||
|  |  | ||||||
|             (( tpos=tpos+1 )) |  | ||||||
|             auxTypeHi=$(readcharHex "$filename" $tpos) |  | ||||||
|             (( tpos=tpos+1 )) |  | ||||||
|             auxTypeLo=$(readcharHex "$filename" $tpos) |  | ||||||
|             pdosAuxType=$auxTypeHi$auxTypeLo |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         echo "ProDOS file.  Type:\$$pdosType   AuxType:\$$pdosAuxType" |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
| done |  | ||||||
|  |  | ||||||
| # 7-19-11 |  | ||||||
| # quick ProDOS testing/fixing on Linux, needs more |  | ||||||
| # Mac Type testing not done yet, nor testing on a Mac |  | ||||||
|  |  | ||||||
| # test on lunix |  | ||||||
| # test inside and outside of AD directory, and from other dirs (both cases) |  | ||||||
| # finish conversion writebyte/readchar library |  | ||||||
| # consider return 2 for missing parameters for subroutines |  | ||||||
							
								
								
									
										1417
									
								
								scripts/tools/cppo
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1417
									
								
								scripts/tools/cppo
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										165
									
								
								scripts/tools/debupdate
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										165
									
								
								scripts/tools/debupdate
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,165 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # debupdate - Upgrades packages on a Debian-based system | ||||||
|  | # Written in 2016 by T. Joseph Carter <tjcarter@spiritsubstance.com> | ||||||
|  | # Based on raspbian-update by Ivan Drucker <ivan@ivanx.com> | ||||||
|  | # | ||||||
|  | # To the extent possible under law, the author(s) have dedicated all copyright | ||||||
|  | # and related and neighboring rights to this software to the public domain | ||||||
|  | # worldwide. This software is distributed without any warranty. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the CC0 Public Domain Dedication along | ||||||
|  | # with this software. If not, you may find a copy here: | ||||||
|  | #  <http://creativecommons.org/publicdomain/zero/1.0/> | ||||||
|  |  | ||||||
|  | PROGNAME="$0" | ||||||
|  | PROGRAM="debupdate" | ||||||
|  | VERSION="0.9.0" | ||||||
|  |  | ||||||
|  | useAptGet= | ||||||
|  | useAutoClean= | ||||||
|  | autoYes= | ||||||
|  |  | ||||||
|  | aptitudeUpgradeArgs="--allow-new-upgrades --allow-new-installs safe-upgrade" | ||||||
|  | aptGetUpgradeArgs="--with-new-pkgs --auto-remove upgrade" | ||||||
|  |  | ||||||
|  | ShowLicense() { | ||||||
|  | 	printf "%s version %s | ||||||
|  | Upgrades packages on a Debian-based system | ||||||
|  |  | ||||||
|  | Written in 2016 by T. Joseph Carter <tjcarter@spiritsubstance.com> | ||||||
|  | Based on raspbian-update by Ivan Drucker <ivan@ivanx.com> | ||||||
|  |  | ||||||
|  | To the extent possible under law, the author(s) have dedicated all copyright | ||||||
|  | and related and neighboring rights to this software to the public domain | ||||||
|  | worldwide. This software is distributed without any warranty. | ||||||
|  |  | ||||||
|  | You should have received a copy of the CC0 Public Domain Dedication along | ||||||
|  | with this software. If not, you may find a copy here: | ||||||
|  |  <http://creativecommons.org/publicdomain/zero/1.0/> | ||||||
|  | " $PROGRAM $VERSION | ||||||
|  | 	exit 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Run() { | ||||||
|  | 	local cmd=( ) | ||||||
|  | 	for i in "${@}"; do | ||||||
|  | 		# Replace argument's spaces with ''; if different, quote the string | ||||||
|  | 		if [ "$i" != "${i/ /}" ]; then | ||||||
|  | 			cmd=( ${cmd[@]} "'${i}'" ) | ||||||
|  | 		else | ||||||
|  | 			cmd=( ${cmd[@]} $i ) | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  | 	printf ">>> %s\n" "${cmd[@]}" | ||||||
|  | 	${@} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ShowHelp() { | ||||||
|  | 	# FIXME | ||||||
|  | 	printf "\nHelp\n" | ||||||
|  |  | ||||||
|  | 	exit ${1:-0} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Process command line arguments | ||||||
|  | while getopts ":hvyacy" opt; do | ||||||
|  | 	case "$opt" in | ||||||
|  | 		h)	ShowHelp ;; | ||||||
|  | 		v)	ShowLicense ;; | ||||||
|  | 		y)	autoYes=1 ;; | ||||||
|  | 		a)	useAptGet=1 ;; | ||||||
|  | 		c)	useAutoClean=1 ;; | ||||||
|  | 		\?) | ||||||
|  | 			printf "Invalid argument: -%s\n" "$OPTARG" | ||||||
|  | 			badArgument=1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | done | ||||||
|  | if [[ "$badArgument" ]]; then | ||||||
|  | 	ShowHelp 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Check for root access | ||||||
|  | if [[ "$UID" != "0" ]]; then | ||||||
|  | 	if hash sudo 2>/dev/null; then | ||||||
|  | 		Run sudo $0 "$@" | ||||||
|  | 		exit $? | ||||||
|  | 	else | ||||||
|  | 		printf "%s requires \"root\" administrator access to upgrade your system.\n" "$PROGRAM" | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Determine if aptitude is installed (unless we're not using it) | ||||||
|  | if [[ -z "$useAptGet" ]]; then | ||||||
|  | 	if ! hash aptitude 2>/dev/null; then | ||||||
|  | 		useAptGet=1 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Clean apt package cache | ||||||
|  | printf "\nCleaning apt package cache...\n" | ||||||
|  | if [[ $useAptGet ]]; then | ||||||
|  | 	Run apt-get ${useAutoClean:+auto}clean | ||||||
|  | else | ||||||
|  | 	Run aptitude ${useAutoClean:+auto}clean | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Update package lists | ||||||
|  | printf "\nUpdating list of available packages...\n" | ||||||
|  | if [[ $useAptGet ]]; then | ||||||
|  | 	Run apt-get update | ||||||
|  | else | ||||||
|  | 	Run aptitude update | ||||||
|  | fi | ||||||
|  | if [[ $? -ne 0 ]]; | ||||||
|  | 	printf "Package list update failed.\n" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Check to see if we even need to upgrade | ||||||
|  | if [[ $useAptGet ]]; then | ||||||
|  | 	apt-get --trivial-only $aptGetUpgradeArgs &>/dev/null | ||||||
|  | else | ||||||
|  | 	aptitude $aptitudeUpgradeArgs <<<"n" &>/dev/null | ||||||
|  | fi | ||||||
|  | if [[ $? -eq 0 ]]; then | ||||||
|  | 	printf "Your packages are already up to date.\n" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Do the upgrade itself | ||||||
|  | if [[ $useAptGet ]]; then | ||||||
|  | 	Run apt-get ${autoYes:+-y} $aptGetUpgradeArgs | ||||||
|  | else | ||||||
|  | 	Run aptitude ${autoYes:+-y} $aptitudeUpgradeArgs | ||||||
|  | fi | ||||||
|  | if [[ $? -ne 0 ]]; then | ||||||
|  | 	# FIXME | ||||||
|  | 	printf "System upgrade failed.  Something about a log should be here.\n" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # apt-get needs explicit autoremove (aptitude doesn't) | ||||||
|  | if [[ $useAptGet ]]; then | ||||||
|  | 	Run apt-get autoremove | ||||||
|  | 	if [[ $? -ne 0 ]]; then | ||||||
|  | 		printf "Failure attempting to auto-remove unneeded packages.\n" | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Clean apt package cache (again) | ||||||
|  | printf "Cleaning apt package cache...\n" | ||||||
|  | if [[ $useAptGet ]]; then | ||||||
|  | 	Run apt-get autoclean | ||||||
|  | else | ||||||
|  | 	Run aptitude autoclean | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | printf "\nIt is generally recommended that you reboot your system after upgrades.  You | ||||||
|  | can do this with the \"reboot\" command, which must be run as root.\n\n" | ||||||
							
								
								
									
										286
									
								
								scripts/tools/mkatinit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										286
									
								
								scripts/tools/mkatinit
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,286 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # mkatinit by Ivan Drucker, http://appleii.ivanx.com | ||||||
|  | # not licensed; please modify and redistribute as you like | ||||||
|  | # 1.0b4 1-30-11 | ||||||
|  |  | ||||||
|  | # 1.1d1 -- uses bashByter. NOT TESTED. | ||||||
|  |  | ||||||
|  | # This script creates the ATINIT file required for netbooting Apple IIe and | ||||||
|  | #   IIGS clients from a netatalk server. ATINIT is put in the in the | ||||||
|  | #   (sharename)/USERS hierarchy, or the current directory if it can't. | ||||||
|  | #   The user can specify the ProDOS startup system program and default prefix. | ||||||
|  | #   If an argument is supplied, it is used as the username and the prompt is | ||||||
|  | #   skipped. | ||||||
|  |  | ||||||
|  | # The ATINIT file is not as complete as the ones generated by AppleShare 3.0, | ||||||
|  | #   and features such as default printer are not used. | ||||||
|  |  | ||||||
|  | # to do | ||||||
|  | # possibly require confirmation if AFPD_GUEST is not set correctly | ||||||
|  | #  or offer to change it | ||||||
|  |  | ||||||
|  | # from ID-bashByter library | ||||||
|  | decToChar () { | ||||||
|  | # converts single-byte decimal value to equivalent character | ||||||
|  | # arg: decimal number from 0-255 | ||||||
|  | # out: one character | ||||||
|  | #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||||
|  | 	[[ $1 ]] || return 11 | ||||||
|  | 	[[ $2 ]] && return 8 | ||||||
|  | 	[[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ | ||||||
|  | 		&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||||
|  | 	# args are valid | ||||||
|  | 	echo -n -e "\x$(printf %02X "$1")" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | writechars () { | ||||||
|  | # write one or more characters (bytes) to file | ||||||
|  | # arg1: filename | ||||||
|  | # arg2: (optional) offset (# of bytes to skip before writing) | ||||||
|  | # arg3 OR stdin: sequence of characters | ||||||
|  | #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] | ||||||
|  | #  out: nothing | ||||||
|  | # exit: 8=extraneous arg, 11=missing arg1, | ||||||
|  | #       13=missing stdin/arg3, 22=invalid arg2 | ||||||
|  | 	[[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } | ||||||
|  | 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ | ||||||
|  | 		( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } | ||||||
|  | 	[[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } | ||||||
|  | 	[[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } | ||||||
|  | 	# args are valid | ||||||
|  | 	if [[ -t 0 ]]; then | ||||||
|  | 		echo -n "$3" | \ | ||||||
|  | 			dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||||
|  | 	else | ||||||
|  | 		dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #---- mkatinit starts here | ||||||
|  | IFS='' | ||||||
|  |  | ||||||
|  | #defaults | ||||||
|  | sharepath=$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) | ||||||
|  | prefix=/$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f2) | ||||||
|  | gsprefix=$prefix | ||||||
|  | startprog="$prefix/BASIC.SYSTEM" | ||||||
|  | gsstartprog="$prefix/SYSTEM/FINDER" | ||||||
|  | filename="ATINIT" | ||||||
|  | user=$(whoami) | ||||||
|  |  | ||||||
|  | echo | ||||||
|  |  | ||||||
|  | usersfolder=1 | ||||||
|  | while [ -n "$1" ] && [ "${1:0:1}" = '-' ]; do | ||||||
|  | 	flag="$1" | ||||||
|  | 	if [ $flag = "-gs" ]; then | ||||||
|  | 		gs=1 | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [ $flag = "-d" ]; then | ||||||
|  | 		noprompt=1 | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [ $flag = "-f" ]; then | ||||||
|  | 		overwrite=1 | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [ $flag = "-g" ]; then | ||||||
|  | 		alsoguest=1 | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	elif [ $flag = "-c" ]; then | ||||||
|  | 		usersfolder=0 | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 	else | ||||||
|  | 		badflag=1 | ||||||
|  | 		break | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [ $usersfolder -eq 0 ] && [ -n "$alsoguest" ]; then | ||||||
|  | 	badflag=1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [ $badflag ]; then | ||||||
|  | 	echo "usage: mkatinit [-gs] [-d] [-f] [-g | -c] [<username>|guest]" | ||||||
|  | 	echo | ||||||
|  | 	echo "<username> should be the name of a netatalk user, or 'guest'" | ||||||
|  | 	echo "-gs sets the default ProDOS netboot system startup program and" | ||||||
|  | 	echo "    prefix for GS/OS (if omitted, ProDOS 8 defaults are used)" | ||||||
|  | 	echo "-d  use the default start program and prefix, without prompting" | ||||||
|  | 	echo "-f  overwrite existing ATINIT file if present, without warning" | ||||||
|  | 	echo "-g  create an ATINIT file for Guest as well as the specified user" | ||||||
|  | 	echo "-c  write ATNIT to current directory instead of USERS hierarchy" | ||||||
|  | 	echo | ||||||
|  | 	exit | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | arg="$1" | ||||||
|  |  | ||||||
|  | [[ -z $arg ]] && arg=$user | ||||||
|  |  | ||||||
|  | while : ; do | ||||||
|  |  | ||||||
|  | 	if [ ${#arg} -gt 32 ]; then | ||||||
|  | 		echo "User name is too long. Exiting with no action." | ||||||
|  | 		exit | ||||||
|  | 	elif [ -n "$arg" ]; then | ||||||
|  | 		if [ `echo $arg | tr '[:upper:]' '[:lower:]'` = "guest" ]; then | ||||||
|  | 			username='<Any User>' | ||||||
|  | 			alsoguest= | ||||||
|  | 			if [[ ! $(grep -F -s $(ls -1 /home) /etc/default/netatalk) ]]; then | ||||||
|  | 				echo 'Warning: The AFPD_GUEST setting in /etc/default/netatalk is not assigned to a' | ||||||
|  | 				echo 'user with a folder in /home. Guest users may be able to boot over the network' | ||||||
|  | 				echo 'into ProDOS 8 for read-only access, but will not be able to boot into GS/OS.' | ||||||
|  | 				if [ $gs ]; then | ||||||
|  | 					echo ' Using ProDOS 8 defaults.' | ||||||
|  | 					gs= | ||||||
|  | 				else | ||||||
|  | 					echo | ||||||
|  | 				fi | ||||||
|  | 				echo | ||||||
|  | 			fi | ||||||
|  | 		else | ||||||
|  | 			username="$arg" | ||||||
|  | 			if [[ ! $(ls -1 /home | grep -F -s $username) ]]; then | ||||||
|  | 				echo "Warning: This username ($username) does not have a folder in /home. This user may" | ||||||
|  | 				echo "not be able to boot over the network into ProDOS 8 or GS/OS." | ||||||
|  | 				echo | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  | 		if [ $gs ]; then | ||||||
|  | 			startprog="$gsstartprog" | ||||||
|  | 			prefix="$gsprefix" | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# make username all caps | ||||||
|  | 	username=`echo $username | tr '[:lower:]' '[:upper:]'` | ||||||
|  |  | ||||||
|  | 	# prompt for folders | ||||||
|  | 	if [ ! $doalsoguest ] && [ ! $noprompt ]; then | ||||||
|  | 		while : ; do | ||||||
|  | 			echo "Enter the ProDOS path to the startup system program." | ||||||
|  | 			echo "default (CR to accept): $startprog" | ||||||
|  | 			read | ||||||
|  | 			if [ ${#REPLY} -gt 64 ]; then | ||||||
|  | 				continue | ||||||
|  | 			elif [ -n "$REPLY" ]; then | ||||||
|  | 				startprog="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" | ||||||
|  | 				echo | ||||||
|  | 			fi | ||||||
|  | 			break | ||||||
|  | 		done | ||||||
|  |  | ||||||
|  | 		while : ; do | ||||||
|  | 			echo "Enter the initial ProDOS prefix:" | ||||||
|  | 			echo "default (CR to accept): $prefix" | ||||||
|  | 			read | ||||||
|  | 			if [ ${#REPLY} -gt 64 ]; then | ||||||
|  | 				continue | ||||||
|  | 			elif [ -n "$REPLY" ]; then | ||||||
|  | 				prefix="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" | ||||||
|  | 				echo | ||||||
|  | 			fi | ||||||
|  | 			break | ||||||
|  | 		done | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# create folders if needed | ||||||
|  | 	filepath="$PWD/$filename" | ||||||
|  |  | ||||||
|  | 	while [ $usersfolder -eq 1 ]; do | ||||||
|  | 		# create folders for ATINIT | ||||||
|  | 		while [ ! -d "$sharepath" ]; do | ||||||
|  | 			echo "Shared volume '$sharepath' not found. Edit mkatinit to change the default." | ||||||
|  | 			echo "Enter the local path to the netatalk shared volume used for netboot:" | ||||||
|  | 			read sharepath | ||||||
|  | 		done | ||||||
|  |  | ||||||
|  | 		if [ ! -d "$sharepath/USERS" ]; then | ||||||
|  | 			mkdir "$sharepath/USERS" | ||||||
|  | 			if [ $? -ne 0 ]; then | ||||||
|  | 				break | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  | 		if [ ! -d "$sharepath/USERS/$username" ]; then | ||||||
|  | 			mkdir "$sharepath/USERS/$username" | ||||||
|  | 			if [ $? -ne 0 ]; then | ||||||
|  | 				break | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  | 		if [ ! -d "$sharepath/USERS/$username/SETUP" ]; then | ||||||
|  | 			mkdir "$sharepath/USERS/$username/SETUP" | ||||||
|  | 			if [ $? -ne 0 ]; then | ||||||
|  | 				break | ||||||
|  | 			fi | ||||||
|  | 		else | ||||||
|  | 			if [ ! -w "$sharepath/USERS/$username/SETUP" ]; then | ||||||
|  | 				break | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		# we have a valid USERS folder target for ATINIT | ||||||
|  | 		filepath="$sharepath/USERS/$username/SETUP/$filename" | ||||||
|  | 		usersfolder=2 | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	if [ $usersfolder -eq 1 ]; then | ||||||
|  | 		echo "Could not write to shared volume. Creating ATINIT in current directory." | ||||||
|  | 		if [ -n "$alsoguest" ]; then | ||||||
|  | 			echo "ATINIT for Guest user will not be created." | ||||||
|  | 		fi | ||||||
|  | 		echo | ||||||
|  | 		alsoguest= | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if [ ! $doalsoguest ]; then | ||||||
|  | 		echo "netboot start program: $startprog" | ||||||
|  | 		echo "netboot start prefix : $prefix" | ||||||
|  | 		echo | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	#remove ATINIT if present | ||||||
|  | 	if [ ! $overwrite ] && [ -f "$filepath" ]; then | ||||||
|  | 		echo -n "$filepath already exists. Overwrite? " | ||||||
|  | 		while read -s -n 1 > /dev/null 2>&1; do | ||||||
|  | 			if [ -z "$REPLY" ]; then | ||||||
|  | 				continue | ||||||
|  | 			elif [ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ]; then | ||||||
|  | 				echo | ||||||
|  | 				break | ||||||
|  | 			elif [ "$REPLY" = "N" ] || [ "$REPLY" = "n" ]; then | ||||||
|  | 				echo | ||||||
|  | 				echo "Exiting with no action." | ||||||
|  | 				exit | ||||||
|  | 			fi | ||||||
|  | 		done | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	#write the file. start with zeroes | ||||||
|  | 	dd if=/dev/zero of="$filepath" bs=1 count=276 2> /dev/null | ||||||
|  | 	#put in startprog, prefix, username (first byte of each field is length) | ||||||
|  | 	# ( echo -n "${#startprog}" | awk '{printf("%c",$0);}'; echo -n "$startprog"; ) | dd of="$filepath" bs=1 seek=7 conv=notrunc 2> /dev/null | ||||||
|  | 	# ( echo -n "${#prefix}" | awk '{printf("%c",$0);}'; echo -n "$prefix"; ) | dd of="$filepath" bs=1 seek=78 conv=notrunc 2> /dev/null | ||||||
|  | 	# ( echo -n "${#username}" | awk '{printf("%c",$0);}'; echo -n "$username"; ) | dd of="$filepath" bs=1 seek=143 conv=notrunc 2> /dev/null | ||||||
|  | 	( decToChar "${#startprog}"; echo -n "$startprog"; ) | writechars "$filepath" 7 | ||||||
|  | 	( decToChar "${#prefix}"; echo -n "$prefix"; ) | writechars "$filepath" 78 | ||||||
|  | 	( decToChar "${#username}"; echo -n "$username"; ) | writechars "$filepath" 143 | ||||||
|  |  | ||||||
|  | 	echo "Created $filepath" | ||||||
|  | 	if [ ! $alsoguest ]; then | ||||||
|  | 		break | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if [ $usersfolder -eq 2 ]; then | ||||||
|  | 		usersfolder=1 | ||||||
|  | 	fi | ||||||
|  | 	doalsoguest=1 | ||||||
|  | 	arg='guest' | ||||||
|  | done | ||||||
|  |  | ||||||
|  | echo | ||||||
| @@ -1,286 +0,0 @@ | |||||||
| #! /bin/bash |  | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: |  | ||||||
|  |  | ||||||
| # mkatinit by Ivan Drucker, http://appleii.ivanx.com |  | ||||||
| # not licensed; please modify and redistribute as you like |  | ||||||
| # 1.0b4 1-30-11 |  | ||||||
|  |  | ||||||
| # 1.1d1 -- uses bashByter. NOT TESTED. |  | ||||||
|  |  | ||||||
| # This script creates the ATINIT file required for netbooting Apple IIe and |  | ||||||
| #   IIGS clients from a netatalk server. ATINIT is put in the in the |  | ||||||
| #   (sharename)/USERS hierarchy, or the current directory if it can't. |  | ||||||
| #   The user can specify the ProDOS startup system program and default prefix. |  | ||||||
| #   If an argument is supplied, it is used as the username and the prompt is |  | ||||||
| #   skipped. |  | ||||||
|  |  | ||||||
| # The ATINIT file is not as complete as the ones generated by AppleShare 3.0, |  | ||||||
| #   and features such as default printer are not used. |  | ||||||
|  |  | ||||||
| # to do |  | ||||||
| # possibly require confirmation if AFPD_GUEST is not set correctly |  | ||||||
| #  or offer to change it |  | ||||||
|  |  | ||||||
| # from ID-bashByter library |  | ||||||
| decToChar () { |  | ||||||
| # converts single-byte decimal value to equivalent character |  | ||||||
| # arg: decimal number from 0-255 |  | ||||||
| # out: one character |  | ||||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg |  | ||||||
|     [[ $1 ]] || return 11 |  | ||||||
|     [[ $2 ]] && return 8 |  | ||||||
|     [[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ |  | ||||||
|         && ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 |  | ||||||
|     # args are valid |  | ||||||
|     echo -n -e "\x$(printf %02X "$1")" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| writechars () { |  | ||||||
| # write one or more characters (bytes) to file |  | ||||||
| # arg1: filename |  | ||||||
| # arg2: (optional) offset (# of bytes to skip before writing) |  | ||||||
| # arg3 OR stdin: sequence of characters |  | ||||||
| #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] |  | ||||||
| #  out: nothing |  | ||||||
| # exit: 8=extraneous arg, 11=missing arg1, |  | ||||||
| #       13=missing stdin/arg3, 22=invalid arg2 |  | ||||||
|     [[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } |  | ||||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ |  | ||||||
|         ( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } |  | ||||||
|     [[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } |  | ||||||
|     [[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } |  | ||||||
|     # args are valid |  | ||||||
|     if [[ -t 0 ]]; then |  | ||||||
|         echo -n "$3" | \ |  | ||||||
|             dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null |  | ||||||
|     else |  | ||||||
|         dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #---- mkatinit starts here |  | ||||||
| IFS='' |  | ||||||
|  |  | ||||||
| #defaults |  | ||||||
| sharepath=$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) |  | ||||||
| prefix=/$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f2) |  | ||||||
| gsprefix=$prefix |  | ||||||
| startprog="$prefix/BASIC.SYSTEM" |  | ||||||
| gsstartprog="$prefix/SYSTEM/FINDER" |  | ||||||
| filename="ATINIT" |  | ||||||
| user=$(whoami) |  | ||||||
|  |  | ||||||
| echo |  | ||||||
|  |  | ||||||
| usersfolder=1 |  | ||||||
| while [ -n "$1" ] && [ "${1:0:1}" = '-' ]; do |  | ||||||
|     flag="$1" |  | ||||||
|     if [ $flag = "-gs" ]; then |  | ||||||
|         gs=1 |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [ $flag = "-d" ]; then |  | ||||||
|         noprompt=1 |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [ $flag = "-f" ]; then |  | ||||||
|         overwrite=1 |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [ $flag = "-g" ]; then |  | ||||||
|         alsoguest=1 |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     elif [ $flag = "-c" ]; then |  | ||||||
|         usersfolder=0 |  | ||||||
|         shift |  | ||||||
|         continue |  | ||||||
|     else |  | ||||||
|         badflag=1 |  | ||||||
|         break |  | ||||||
|     fi |  | ||||||
| done |  | ||||||
|  |  | ||||||
| if [ $usersfolder -eq 0 ] && [ -n "$alsoguest" ]; then |  | ||||||
|     badflag=1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| if [ $badflag ]; then |  | ||||||
|     echo "usage: mkatinit [-gs] [-d] [-f] [-g | -c] [<username>|guest]" |  | ||||||
|     echo |  | ||||||
|     echo "<username> should be the name of a netatalk user, or 'guest'" |  | ||||||
|     echo "-gs sets the default ProDOS netboot system startup program and" |  | ||||||
|     echo "      prefix for GS/OS (if omitted, ProDOS 8 defaults are used)" |  | ||||||
|     echo "-d  use the default start program and prefix, without prompting" |  | ||||||
|     echo "-f  overwrite existing ATINIT file if present, without warning" |  | ||||||
|     echo "-g  create an ATINIT file for Guest as well as the specified user" |  | ||||||
|     echo "-c  write ATNIT to current directory instead of USERS hierarchy" |  | ||||||
|     echo |  | ||||||
|     exit |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| arg="$1" |  | ||||||
|  |  | ||||||
| [[ -z $arg ]] && arg=$user |  | ||||||
|  |  | ||||||
| while : ; do |  | ||||||
|  |  | ||||||
|     if [ ${#arg} -gt 32 ]; then |  | ||||||
|         echo "User name is too long. Exiting with no action." |  | ||||||
|         exit |  | ||||||
|     elif [ -n "$arg" ]; then |  | ||||||
|         if [ `echo $arg | tr '[:upper:]' '[:lower:]'` = "guest" ]; then |  | ||||||
|             username='<Any User>' |  | ||||||
|             alsoguest= |  | ||||||
|             if [[ ! $(grep -F -s $(ls -1 /home) /etc/default/netatalk) ]]; then |  | ||||||
|                 echo 'Warning: The AFPD_GUEST setting in /etc/default/netatalk is not assigned to a' |  | ||||||
|                 echo 'user with a folder in /home. Guest users may be able to boot over the network' |  | ||||||
|                 echo 'into ProDOS 8 for read-only access, but will not be able to boot into GS/OS.' |  | ||||||
|                 if [ $gs ]; then |  | ||||||
|                     echo ' Using ProDOS 8 defaults.' |  | ||||||
|                     gs= |  | ||||||
|                 else |  | ||||||
|                     echo |  | ||||||
|                 fi |  | ||||||
|                 echo |  | ||||||
|             fi |  | ||||||
|         else |  | ||||||
|             username="$arg" |  | ||||||
|             if [[ ! $(ls -1 /home | grep -F -s $username) ]]; then |  | ||||||
|                 echo "Warning: This username ($username) does not have a folder in /home. This user may" |  | ||||||
|                 echo "not be able to boot over the network into ProDOS 8 or GS/OS." |  | ||||||
|                 echo |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|         if [ $gs ]; then |  | ||||||
|             startprog="$gsstartprog" |  | ||||||
|             prefix="$gsprefix" |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     # make username all caps |  | ||||||
|     username=`echo $username | tr '[:lower:]' '[:upper:]'` |  | ||||||
|  |  | ||||||
|     # prompt for folders |  | ||||||
|     if [ ! $doalsoguest ] && [ ! $noprompt ]; then |  | ||||||
|         while : ; do |  | ||||||
|             echo "Enter the ProDOS path to the startup system program." |  | ||||||
|             echo "default (CR to accept): $startprog" |  | ||||||
|             read |  | ||||||
|             if [ ${#REPLY} -gt 64 ]; then |  | ||||||
|                 continue |  | ||||||
|             elif [ -n "$REPLY" ]; then |  | ||||||
|                 startprog="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" |  | ||||||
|                 echo |  | ||||||
|             fi |  | ||||||
|             break |  | ||||||
|         done |  | ||||||
|  |  | ||||||
|         while : ; do |  | ||||||
|             echo "Enter the initial ProDOS prefix:" |  | ||||||
|             echo "default (CR to accept): $prefix" |  | ||||||
|             read |  | ||||||
|             if [ ${#REPLY} -gt 64 ]; then |  | ||||||
|                 continue |  | ||||||
|             elif [ -n "$REPLY" ]; then |  | ||||||
|                 prefix="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" |  | ||||||
|                 echo |  | ||||||
|             fi |  | ||||||
|             break |  | ||||||
|         done |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     # create folders if needed |  | ||||||
|     filepath="$PWD/$filename" |  | ||||||
|  |  | ||||||
|     while [ $usersfolder -eq 1 ]; do |  | ||||||
|         # create folders for ATINIT |  | ||||||
|         while [ ! -d "$sharepath" ]; do |  | ||||||
|             echo "Shared volume '$sharepath' not found. Edit mkatinit to change the default." |  | ||||||
|             echo "Enter the local path to the netatalk shared volume used for netboot:" |  | ||||||
|             read sharepath |  | ||||||
|         done |  | ||||||
|  |  | ||||||
|         if [ ! -d "$sharepath/USERS" ]; then |  | ||||||
|             mkdir "$sharepath/USERS" |  | ||||||
|             if [ $? -ne 0 ]; then |  | ||||||
|                 break |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|         if [ ! -d "$sharepath/USERS/$username" ]; then |  | ||||||
|             mkdir "$sharepath/USERS/$username" |  | ||||||
|             if [ $? -ne 0 ]; then |  | ||||||
|                 break |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|         if [ ! -d "$sharepath/USERS/$username/SETUP" ]; then |  | ||||||
|             mkdir "$sharepath/USERS/$username/SETUP" |  | ||||||
|             if [ $? -ne 0 ]; then |  | ||||||
|                 break |  | ||||||
|             fi |  | ||||||
|         else |  | ||||||
|             if [ ! -w "$sharepath/USERS/$username/SETUP" ]; then |  | ||||||
|                 break |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         # we have a valid USERS folder target for ATINIT |  | ||||||
|         filepath="$sharepath/USERS/$username/SETUP/$filename" |  | ||||||
|         usersfolder=2 |  | ||||||
|     done |  | ||||||
|  |  | ||||||
|     if [ $usersfolder -eq 1 ]; then |  | ||||||
|         echo "Could not write to shared volume. Creating ATINIT in current directory." |  | ||||||
|         if [ -n "$alsoguest" ]; then |  | ||||||
|             echo "ATINIT for Guest user will not be created." |  | ||||||
|         fi |  | ||||||
|         echo |  | ||||||
|         alsoguest= |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [ ! $doalsoguest ]; then |  | ||||||
|         echo "netboot start program: $startprog" |  | ||||||
|         echo "netboot start prefix : $prefix" |  | ||||||
|         echo |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     #remove ATINIT if present |  | ||||||
|     if [ ! $overwrite ] && [ -f "$filepath" ]; then |  | ||||||
|         echo -n "$filepath already exists. Overwrite? " |  | ||||||
|         while read -s -n 1 > /dev/null 2>&1; do |  | ||||||
|             if [ -z "$REPLY" ]; then |  | ||||||
|                 continue |  | ||||||
|             elif [ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ]; then |  | ||||||
|                 echo |  | ||||||
|                 break |  | ||||||
|             elif [ "$REPLY" = "N" ] || [ "$REPLY" = "n" ]; then |  | ||||||
|                 echo |  | ||||||
|                 echo "Exiting with no action." |  | ||||||
|                 exit |  | ||||||
|             fi |  | ||||||
|         done |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     #write the file. start with zeroes |  | ||||||
|     dd if=/dev/zero of="$filepath" bs=1 count=276 2> /dev/null |  | ||||||
|     #put in startprog, prefix, username (first byte of each field is length) |  | ||||||
|     # ( echo -n "${#startprog}" | awk '{printf("%c",$0);}'; echo -n "$startprog"; ) | dd of="$filepath" bs=1 seek=7 conv=notrunc 2> /dev/null |  | ||||||
|     # ( echo -n "${#prefix}" | awk '{printf("%c",$0);}'; echo -n "$prefix"; ) | dd of="$filepath" bs=1 seek=78 conv=notrunc 2> /dev/null |  | ||||||
|     # ( echo -n "${#username}" | awk '{printf("%c",$0);}'; echo -n "$username"; ) | dd of="$filepath" bs=1 seek=143 conv=notrunc 2> /dev/null |  | ||||||
|     ( decToChar "${#startprog}"; echo -n "$startprog"; ) | writechars "$filepath" 7 |  | ||||||
|     ( decToChar "${#prefix}"; echo -n "$prefix"; ) | writechars "$filepath" 78 |  | ||||||
|     ( decToChar "${#username}"; echo -n "$username"; ) | writechars "$filepath" 143 |  | ||||||
|  |  | ||||||
|     echo "Created $filepath" |  | ||||||
|     if [ ! $alsoguest ]; then |  | ||||||
|         break |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [ $usersfolder -eq 2 ]; then |  | ||||||
|         usersfolder=1 |  | ||||||
|     fi |  | ||||||
|     doalsoguest=1 |  | ||||||
|     arg='guest' |  | ||||||
| done |  | ||||||
|  |  | ||||||
| echo |  | ||||||
							
								
								
									
										83
									
								
								scripts/tools/mkvolinfo
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								scripts/tools/mkvolinfo
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # mkvolinfo -- creates a (share)/.AppleDesktop/.volinfo file | ||||||
|  |  | ||||||
|  | makeVolInfoFile () { | ||||||
|  | 	[[ -d $sharepath/.AppleDesktop ]] || mkdir $sharepath/.AppleDesktop | ||||||
|  | 	touch $volinfo | ||||||
|  | 	echo 'MAC_CHARSET:MAC_ROMAN' >> $volinfo | ||||||
|  | 	echo 'VOL_CHARSET:UTF8' >> $volinfo | ||||||
|  | 	echo 'ADOUBLE_VER:v2' >> $volinfo | ||||||
|  | 	echo 'CNIDBACKEND:dbd' >> $volinfo | ||||||
|  | 	echo 'CNIDDBDHOST:localhost' >> $volinfo | ||||||
|  | 	echo 'CNIDDBDPORT:4700' >> $volinfo | ||||||
|  | 	echo "CNID_DBPATH:$sharepath" >> $volinfo | ||||||
|  | 	echo 'VOLUME_OPTS:PRODOS CACHEID' >> $volinfo | ||||||
|  | 	if (( $mixedcase )); then | ||||||
|  | 		echo 'VOLCASEFOLD:' >> $volinfo | ||||||
|  | 	else | ||||||
|  | 		echo 'VOLCASEFOLD:MTOULOWER UTOMUPPER' >> $volinfo | ||||||
|  | 	fi | ||||||
|  | 	echo 'EXTATTRTYPE:AFPVOL_EA_AD' >> $volinfo | ||||||
|  | 	echo ".volinfo for $sharepath has been created." | ||||||
|  | } | ||||||
|  |  | ||||||
|  | while [[ $1 == "-f" || $1 == "-c" ]]; do | ||||||
|  | 	if [[ $1 == "-f" ]]; then | ||||||
|  | 		force=1 | ||||||
|  | 		shift | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if [[ $1 == "-c" ]]; then | ||||||
|  | 		mixedcase=1 | ||||||
|  | 		shift | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [[ ${1:0:1} == "-" ]]; then | ||||||
|  |  | ||||||
|  | 	echo "usage: mkvolinfo [-f] [-c] [shared volume path]" | ||||||
|  | 	echo | ||||||
|  | 	echo "-c will create the .volinfo file to specify no uppercase filename conversion" | ||||||
|  | 	echo "-f will create the .volinfo file without prompting, if none exists" | ||||||
|  | 	echo "If a path is specified, that is what is used, otherwise the last entry" | ||||||
|  | 	echo "in /usr/local/etc/netatalk/AppleVolumes.default is used." | ||||||
|  |  | ||||||
|  | else | ||||||
|  | 	sudo true | ||||||
|  | 	if [[ $1 ]]; then | ||||||
|  | 		sharepath=$(readlink -m $1) | ||||||
|  | 	else | ||||||
|  | 		sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	volinfo=$sharepath/.AppleDesktop/.volinfo | ||||||
|  |  | ||||||
|  | 	if [[ ! -d $sharepath ]]; then | ||||||
|  | 		echo "$sharepath does not exist." | ||||||
|  | 	else | ||||||
|  | 		if [[ -f $volinfo ]]; then | ||||||
|  | 			echo "$volinfo already exists." | ||||||
|  | 		else | ||||||
|  | 			if [[ $force ]]; then | ||||||
|  | 				makeVolInfoFile | ||||||
|  | 			else | ||||||
|  | 				echo "The .volinfo file is automatically generated when you first" | ||||||
|  | 				echo "log in from an AFP (Apple II or Mac) client machine." | ||||||
|  | 				echo "If you can't do this, you can create a .volinfo file now" | ||||||
|  | 				echo "based on assumed defaults; proceed with caution if you have" | ||||||
|  | 				echo "customized your AppleVolumes files." | ||||||
|  | 				echo | ||||||
|  | 				echo "If the path shown below is incorrect, you can specify" | ||||||
|  | 				echo "the path to your shared volume as an argument to mkvolinfo." | ||||||
|  | 				echo | ||||||
|  | 				echo -n "Make .volinfo for shared volume $sharepath now? " | ||||||
|  | 				read | ||||||
|  | 				if [[ ${REPLY:0:1} == "y" ]] || [[ ${REPLY:0:1} == "Y" ]]; then | ||||||
|  | 					makeVolInfoFile | ||||||
|  | 				fi | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
| @@ -1,83 +0,0 @@ | |||||||
| #! /bin/bash |  | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: |  | ||||||
|  |  | ||||||
| # mkvolinfo -- creates a (share)/.AppleDesktop/.volinfo file |  | ||||||
|  |  | ||||||
| makeVolInfoFile () { |  | ||||||
|     [[ -d $sharepath/.AppleDesktop ]] || mkdir $sharepath/.AppleDesktop |  | ||||||
|     touch $volinfo |  | ||||||
|     echo 'MAC_CHARSET:MAC_ROMAN' >> $volinfo |  | ||||||
|     echo 'VOL_CHARSET:UTF8' >> $volinfo |  | ||||||
|     echo 'ADOUBLE_VER:v2' >> $volinfo |  | ||||||
|     echo 'CNIDBACKEND:dbd' >> $volinfo |  | ||||||
|     echo 'CNIDDBDHOST:localhost' >> $volinfo |  | ||||||
|     echo 'CNIDDBDPORT:4700' >> $volinfo |  | ||||||
|     echo "CNID_DBPATH:$sharepath" >> $volinfo |  | ||||||
|     echo 'VOLUME_OPTS:PRODOS CACHEID' >> $volinfo |  | ||||||
|     if (( $mixedcase )); then |  | ||||||
|         echo 'VOLCASEFOLD:' >> $volinfo |  | ||||||
|     else |  | ||||||
|         echo 'VOLCASEFOLD:MTOULOWER UTOMUPPER' >> $volinfo |  | ||||||
|     fi |  | ||||||
|     echo 'EXTATTRTYPE:AFPVOL_EA_AD' >> $volinfo |  | ||||||
|     echo ".volinfo for $sharepath has been created." |  | ||||||
| } |  | ||||||
|  |  | ||||||
| while [[ $1 == "-f" || $1 == "-c" ]]; do |  | ||||||
|     if [[ $1 == "-f" ]]; then |  | ||||||
|         force=1 |  | ||||||
|         shift |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if [[ $1 == "-c" ]]; then |  | ||||||
|         mixedcase=1 |  | ||||||
|         shift |  | ||||||
|     fi |  | ||||||
| done |  | ||||||
|  |  | ||||||
| if [[ ${1:0:1} == "-" ]]; then |  | ||||||
|  |  | ||||||
|     echo "usage: mkvolinfo [-f] [-c] [shared volume path]" |  | ||||||
|     echo |  | ||||||
|     echo "-c will create the .volinfo file to specify no uppercase filename conversion" |  | ||||||
|     echo "-f will create the .volinfo file without prompting, if none exists" |  | ||||||
|     echo "If a path is specified, that is what is used, otherwise the last entry" |  | ||||||
|     echo "in /usr/local/etc/netatalk/AppleVolumes.default is used." |  | ||||||
|  |  | ||||||
| else |  | ||||||
|     sudo true |  | ||||||
|     if [[ $1 ]]; then |  | ||||||
|         sharepath=$(readlink -m $1) |  | ||||||
|     else |  | ||||||
|         sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     volinfo=$sharepath/.AppleDesktop/.volinfo |  | ||||||
|  |  | ||||||
|     if [[ ! -d $sharepath ]]; then |  | ||||||
|         echo "$sharepath does not exist." |  | ||||||
|     else |  | ||||||
|         if [[ -f $volinfo ]]; then |  | ||||||
|             echo "$volinfo already exists." |  | ||||||
|         else |  | ||||||
|             if [[ $force ]]; then |  | ||||||
|                 makeVolInfoFile |  | ||||||
|             else |  | ||||||
|                 echo "The .volinfo file is automatically generated when you first" |  | ||||||
|                 echo "log in from an AFP (Apple II or Mac) client machine." |  | ||||||
|                 echo "If you can't do this, you can create a .volinfo file now" |  | ||||||
|                 echo "based on assumed defaults; proceed with caution if you have" |  | ||||||
|                 echo "customized your AppleVolumes files." |  | ||||||
|                 echo |  | ||||||
|                 echo "If the path shown below is incorrect, you can specify" |  | ||||||
|                 echo "the path to your shared volume as an argument to mkvolinfo." |  | ||||||
|                 echo |  | ||||||
|                 echo -n "Make .volinfo for shared volume $sharepath now? " |  | ||||||
|                 read |  | ||||||
|                 if [[ ${REPLY:0:1} == "y" ]] || [[ ${REPLY:0:1} == "Y" ]]; then |  | ||||||
|                     makeVolInfoFile |  | ||||||
|                 fi |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| fi |  | ||||||
							
								
								
									
										397
									
								
								setup/index.txt
									
									
									
									
									
								
							
							
						
						
									
										397
									
								
								setup/index.txt
									
									
									
									
									
								
							| @@ -1,358 +1,93 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # A2SERVER master setup script, last update 15-Jul-20 | # setup/index.txt - upgrade path from Ivan's a2server tree | ||||||
| # it downloads and executes several scripts related to the setup of | # | ||||||
| # netatalk configured for Apple II use on Debian or Raspbian. | # Ivan's a2server installed with a single copy-paste of a command line that | ||||||
| # more info is at http://ivanx.com/a2server | # downloaded a script and ran it sight-unseen.  People are going to continue | ||||||
|  | # to run that command (they shouldn't, but they will), and we can support | ||||||
|  | # them doing it for now. | ||||||
|  |  | ||||||
| # to download and execute, type: | a2sBranch="master" | ||||||
| # wget ivanx.com/a2server/setup; source setup | a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/${a2sBranch}" | ||||||
|  | a2sTarball="https://github.com/RasppleII/a2server/archive/${a2sBranch}.tar.gz" | ||||||
|  |  | ||||||
| a2serverVersion="153" | # Set a2sSource to the location of the source tree if we're running in one | ||||||
|  | a2sSource="$( dirname "${BASH_SOURCE[0]}" )/.." | ||||||
|  | if [[ -f "$a2sSource/.a2server_source" ]]; then | ||||||
|  | 	pushd $a2sSource >/dev/null | ||||||
|  | 	a2sSource="$PWD" | ||||||
|  | 	popd >/dev/null | ||||||
|  |  | ||||||
| # Ensure URL we'll use ends in a / | 	cat <<-EOT | ||||||
| case "$A2SERVER_SCRIPT_URL" in | 	This script exists solely for backward-compatibility with IvanX's a2server | ||||||
| 	*/) scriptURL="$A2SERVER_SCRIPT_URL" ;; | 	website and aliases installed by older versions.  You appear to have an | ||||||
| 	*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | 	a2server source directory here: | ||||||
| esac | 	 	$a2sSource | ||||||
| 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= | 	Please run ./install.sh in that directory.  Thanks! | ||||||
| [[ -f /usr/bin/raspi-config ]] && isRpi=1 |  | ||||||
|  |  | ||||||
| isDebian= | 	EOT | ||||||
| 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 | 	exit 1 | ||||||
|  |  | ||||||
| installedVersion= |  | ||||||
| if [ -f /usr/local/etc/A2SERVER-version ]; then |  | ||||||
|     installedVersion="$(cat /usr/local/etc/A2SERVER-version)" |  | ||||||
| fi | fi | ||||||
| echo "A2SERVER version available: $a2serverVersion" |  | ||||||
| echo "A2SERVER version installed: ${installedVersion:=None}" |  | ||||||
|  |  | ||||||
| echo | # Find the version in the install script | ||||||
| [[ $scriptURL != *"ivanx.com"* && $scriptURL != *"raw.githubusercontent.com/RasppleII/a2server"* ]] && echo "Using script URL: $scriptURL" | newVersion=$(wget -qO- "${a2sScriptURL}/install.sh" | grep '^a2serverVersion' | cut -d '"' -f 2) | ||||||
| [[ $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= | # It almost never is, but this script could be run with command line arguments, | ||||||
|  | # of which -y we can use, so we should check for it.  We'll pass them all to | ||||||
|  | # the install script later | ||||||
| autoAnswerYes= | autoAnswerYes= | ||||||
| installAll= | for arg in $@; do | ||||||
| setupNetBoot= | 	if [[ $arg == "-y" ]]; then | ||||||
| setupWindowsSharing= | 		autoAnswerYes=1 | ||||||
| compileAlways= | 		break | ||||||
| rm /tmp/a2server-* 2> /dev/null |  | ||||||
| while [[ $1 ]]; do |  | ||||||
|     if [[ $1 == "-r" ]]; then |  | ||||||
|         shift |  | ||||||
|         skipRepoUpdate="-r" |  | ||||||
|         touch /tmp/a2server-packageReposUpdated |  | ||||||
|     elif [[ $1 == "-i" ]]; then |  | ||||||
|         shift |  | ||||||
|         installAll="-i" |  | ||||||
|     elif [[ $1 == "-y" ]]; then |  | ||||||
|         shift |  | ||||||
|         autoAnswerYes="-y" |  | ||||||
|         touch /tmp/a2server-autoAnswerYes |  | ||||||
|     elif [[ $1 == "-b" ]]; then |  | ||||||
|         shift |  | ||||||
|         setupNetBoot="-b" |  | ||||||
|         touch /tmp/a2server-setupNetBoot |  | ||||||
|     elif [[ $1 == "-w" ]]; then |  | ||||||
|         shift |  | ||||||
|         setupWindowsSharing="-w" |  | ||||||
|         touch /tmp/a2server-setupWindowsSharing |  | ||||||
|     elif [[ $1 == "-c" ]]; then |  | ||||||
|         shift |  | ||||||
|         compileAlways="-c" |  | ||||||
|         touch /tmp/a2server-compileAlways |  | ||||||
|     elif [[ $1 == "-v" ]]; then |  | ||||||
|         shift |  | ||||||
|         # Version was already printed |  | ||||||
|         [[ $0 == "-bash" ]] && return 1 || exit 1 |  | ||||||
|     elif [[ $1 ]]; then |  | ||||||
|         echo "options:" |  | ||||||
|         echo "-v: display installed and available versions, then exit" |  | ||||||
|         echo "-i: reinstall A2SERVER software (but not Apple II software)" |  | ||||||
|         echo "-y: auto-answer yes to all prompts" |  | ||||||
|         echo "-r: don't update package repositories" |  | ||||||
|         echo "-b: auto-setup network boot (use with -y)" |  | ||||||
|         echo "-w: auto-setup Windows file sharing (use with -y)" |  | ||||||
|         echo "-c: compile non-package items, rather than downloading binaries" |  | ||||||
|         [[ $0 == "-bash" ]] && return 1 || exit 1 |  | ||||||
| 	fi | 	fi | ||||||
| done | done | ||||||
|  |  | ||||||
| if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 110 )); }; then | cat <<EOT | ||||||
|     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 | Hello, you've reached the single wget command version of the a2server install | ||||||
| doSetup=1 | script.  This script is being phased out for a number of reasons.  The most | ||||||
|  | important is that it is not repeatable.  This script will download things | ||||||
|  | behind the scenes, run them without much verification, and then delete what it | ||||||
|  | ran, no matter if the installation finished successfully or not.  The next | ||||||
|  | time you run the same command, you may get a different (hopefully better) | ||||||
|  | version. | ||||||
|  |  | ||||||
| if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 152 )); }; then | Right now, a2server ${newVersion} is available. | ||||||
|     a2server_update=1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| unsupportedOS=1 | If you are seeing this text, iKarith (Joseph Carter) hasn't bothered to write | ||||||
| if [[ $isRpi ]]; then #supported Raspbian? (16-Feb-15, 20-Jun-14, 09-Jan-14, etc) | publicly-facing end-user documentation for downloading and installing a2server | ||||||
|     fwhash=$(zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 'as of' | awk '{print $NF}') | a more preferred way.  He's filed an issue about this, please do follow the | ||||||
|     fwsupported="-8aca5762- -462f3e3f476f7b6- -c32bc633039cd9- -9d34d0475f9- | instructions there: | ||||||
|             -d4f5315cfac4e- -6f4a90c8cb8817f- -5dd9b4962e- -17c8799375- | 	https://github.com/RasppleII/a2server/issues/60 | ||||||
|             -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 && $isRpi ]]; then | For now, this script does what the old installer used to. | ||||||
|     echo |  | ||||||
|     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 | EOT | ||||||
|     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 [[ ! $autoAnswerYes ]]; then | ||||||
| if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then | 	printf "Do you want to install a2server with this script? " | ||||||
|     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 | 	read | ||||||
|         [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? )) | 	if [[ ${REPLY:0:1} != "y" && ${REPLY:0:1} != "Y" ]]; then | ||||||
|  | 		printf "\nOkay, not installing anything now!\n\n" | ||||||
|  | 		exit 1 | ||||||
| 	fi | 	fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
| if (( $doSetup )); then | a2sSource=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX) | ||||||
|  |  | ||||||
|     echo | # Normally tarballs unpack in a subdirectory, but we want it to unpack into | ||||||
|     echo "a2server-setup modifies files and performs actions as the root user." | # $a2sSource directly (even though the directory has the tarball in it.) | ||||||
|     echo "For details, visit http://ivanx.com/a2server." | printf "\na2server: Downloading installer to $a2sSource.\n" | ||||||
|     echo | wget -O "$a2sSource/a2server-$a2sBranch.tar.gz" "$a2sTarball" | ||||||
|     if [[ ! $autoAnswerYes ]]; then | tar -C $a2sSource --strip-components=1 -zxf "$a2sSource/a2server-${a2sBranch}.tar.gz" | ||||||
|         echo -n "Continue? " |  | ||||||
|         read |  | ||||||
|         [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? )) |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     if (( $doSetup )); then | # Now we actually run the installer as if we were installing it by hand | ||||||
|  | printf "\na2server: Running the installer now.\n" | ||||||
|  | "${a2sSource}/install.sh" "$@" | ||||||
|  |  | ||||||
|         checkPw=1 | # Clean up and delete the installer we downloaded | ||||||
|         while [[ $checkPw ]] ; do | printf "\na2server: Finished with installer, now deleting ${a2sSource}.\n" | ||||||
|             userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') | rm -rf "$a2sSource" | ||||||
|             [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw= |  | ||||||
|             [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw= |  | ||||||
|      |  | ||||||
|             password="your password" |  | ||||||
|             [[ $isApple2Pw ]] && password="apple2" |  | ||||||
|             [[ $isRaspberryPw ]] && password="raspberry" |  | ||||||
|             checkPw= |  | ||||||
|      |  | ||||||
|             [[ $isRpi ]] && a2server="your Raspberry Pi" || a2server="A2SERVER" |  | ||||||
|             if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2SERVER-version ]]; then |  | ||||||
|                 if [[ ! $autoAnswerYes ]]; then |  | ||||||
|                     echo |  | ||||||
|                     echo "To ensure that all client computers are able to connect to" |  | ||||||
|                     echo "${a2server} using the same password, you probably want" |  | ||||||
|                     echo "to change your user password to 'apple2'." |  | ||||||
|                     echo |  | ||||||
|                     echo -n "Do you want to change the password for user '$USER' to 'apple2' now? " |  | ||||||
|                     read |  | ||||||
|                 fi |  | ||||||
|                 if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then |  | ||||||
|                     echo "A2SERVER: changing password for user '$USER' to 'apple2'..." |  | ||||||
|                     echo "$USER:apple2" | sudo chpasswd |  | ||||||
|                     checkPw=1 |  | ||||||
|                 fi |  | ||||||
|             fi |  | ||||||
|         done |  | ||||||
|  |  | ||||||
|         echo |  | ||||||
|         echo "During this installation, enter '${password}' if prompted for passwords." |  | ||||||
|         echo |  | ||||||
|  |  | ||||||
|         sudo true |  | ||||||
|  |  | ||||||
|         echo |  | ||||||
|         echo "A2SERVER: Downloading scripts..." |  | ||||||
|  |  | ||||||
|         wget -q -O /tmp/1.storage "${scriptURL}scripts/a2server-1-storage.txt" |  | ||||||
|         chmod ugo+x /tmp/1.storage |  | ||||||
|  |  | ||||||
|         wget -q -O /tmp/2.tools "${scriptURL}scripts/a2server-2-tools.txt" |  | ||||||
|         chmod ugo+x /tmp/2.tools |  | ||||||
|  |  | ||||||
|         wget -q -O /tmp/3.sharing "${scriptURL}scripts/a2server-3-sharing.txt" |  | ||||||
|         chmod ugo+x /tmp/3.sharing |  | ||||||
|  |  | ||||||
|         wget -q -O /tmp/5.netboot "${scriptURL}scripts/a2server-5-netboot.txt" |  | ||||||
|         chmod ugo+x /tmp/5.netboot |  | ||||||
|  |  | ||||||
|         wget -q -O /tmp/6.samba "${scriptURL}scripts/a2server-6-samba.txt" |  | ||||||
|         chmod ugo+x /tmp/6.samba |  | ||||||
|  |  | ||||||
|         wget -q -O /tmp/7.console "${scriptURL}scripts/a2server-7-console.txt" |  | ||||||
|         chmod ugo+x /tmp/7.console |  | ||||||
|  |  | ||||||
|         echo "A2SERVER: Scripts have been downloaded. Installing..." |  | ||||||
|  |  | ||||||
|         if [[ $installAll ]]; then |  | ||||||
|             sudo rm /usr/local/etc/A2SERVER-version 2> /dev/null |  | ||||||
|             sudo rm /usr/local/bin/nulib2 2> /dev/null |  | ||||||
|             sudo rm /usr/local/bin/unar 2> /dev/null |  | ||||||
|             sudo rm /usr/local/sbin/macipgw 2> /dev/null |  | ||||||
|             sudo rm /usr/local/bin/ciopfs 2> /dev/null |  | ||||||
|             sudo rm /usr/local/etc/netatalk/afppasswd 2> /dev/null |  | ||||||
|             sudo rm /usr/local/etc/netatalk/a2boot/p8 /usr/local/etc/netatalk/a2boot/ProDOS16\ Image 2> /dev/null |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         /tmp/1.storage |  | ||||||
|         rm /tmp/1.storage |  | ||||||
|         /tmp/2.tools |  | ||||||
|         rm /tmp/2.tools |  | ||||||
|         /tmp/3.sharing |  | ||||||
|         rm /tmp/3.sharing |  | ||||||
|         /tmp/5.netboot |  | ||||||
|         rm /tmp/5.netboot |  | ||||||
|         /tmp/6.samba |  | ||||||
|         rm /tmp/6.samba |  | ||||||
|         /tmp/7.console |  | ||||||
|         rm /tmp/7.console |  | ||||||
|         rm /tmp/a2server-packageReposUpdated &> /dev/null |  | ||||||
|  |  | ||||||
|         if [[ ! -f /usr/local/etc/A2SERVER-version ]] \ |  | ||||||
|             || (( $(head -c 3 /usr/local/etc/A2SERVER-version) < ${a2serverVersion:0:3} )); then |  | ||||||
|             echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         source /usr/local/etc/a2serverrc |  | ||||||
|  |  | ||||||
|         # get Kernel release (e.g. 3.6.11+) and version (e.g. #557) |  | ||||||
|         kernelRelease=$(uname -r) |  | ||||||
|         kernelMajorRelease=$(cut -d '.' -f 1 <<< $kernelRelease) |  | ||||||
|         kernelMinorRelease=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/') |  | ||||||
|  |  | ||||||
|         echo |  | ||||||
|         # all done, see if AppleTalk is available and notify either way |  | ||||||
|         if [[ $(ps aux | grep [a]talkd) ]]; then |  | ||||||
|             echo "You now have a fully functional file server for Apple II clients." |  | ||||||
|             echo "On an Apple IIe, it should be accessible via \"Log In\" on the" |  | ||||||
|             echo "Workstation Card software. For IIgs users, it should be accessible" |  | ||||||
|             echo "via the AppleShare control panel." |  | ||||||
|             if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then |  | ||||||
|                 echo                 |  | ||||||
|                 echo "You can network boot GS/OS." |  | ||||||
|                 echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)" |  | ||||||
|                 echo "to Your Card, and slot 7 to AppleTalk, and Startup Slot to 7 or Scan." |  | ||||||
|                 echo "On a ROM 3 IIgs, set slot 1 or 2, and Startup Slot, to AppleTalk." |  | ||||||
|             fi |  | ||||||
|             if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then |  | ||||||
|                 echo |  | ||||||
|                 echo "You can network boot ProDOS 8. On an Apple IIe, put your Workstation Card" |  | ||||||
|                 echo "in a slot above your disk controller card, or type PR#X with open-apple" |  | ||||||
|                 echo "held down, with X being the slot of your Workstation Card." |  | ||||||
|                 echo 'On a IIgs, press "8" during the initial procession of periods.' |  | ||||||
|             fi |  | ||||||
|             echo |  | ||||||
|             echo "A2SERVER setup is complete! Go connect from your Apple II!" |  | ||||||
|             echo |  | ||||||
|         elif [[ -f /tmp/rpiUpdate ]]; then |  | ||||||
|             echo "A2SERVER is now configured, but Apple II clients will not be able" |  | ||||||
|             echo "to connect until you restart your Raspberry Pi." |  | ||||||
|             echo |  | ||||||
|             if [[ ! $autoAnswerYes ]]; then |  | ||||||
|                 echo -n "Restart now? " |  | ||||||
|                 read |  | ||||||
|             fi |  | ||||||
|             if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then |  | ||||||
|                 sudo shutdown -r now |  | ||||||
|                 echo |  | ||||||
|                 echo "A2SERVER: Preparing to restart..." |  | ||||||
|                 while :; do sleep 60; done |  | ||||||
|             fi |  | ||||||
|             rm /tmp/rpiUpdate |  | ||||||
|             echo |  | ||||||
|         elif [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRelease -le 15 ]]; then |  | ||||||
|             echo "A2SERVER is now configured, but Apple II clients cannot connect" |  | ||||||
|             echo "because of a kernel-crashing bug in Linux kernel 3.12 through 3.15." |  | ||||||
|             echo "You have kernel version $kernelMajorRelease.$kernelMinorRelease." |  | ||||||
|             echo "A2SERVER has disabled AppleTalk networking to prevent crashes." |  | ||||||
|             echo "Please use kernel 3.11 or earlier, or kernel 3.16 or later." |  | ||||||
|             echo |  | ||||||
|         else |  | ||||||
|             echo "A2SERVER is now configured, but Apple II clients cannot connect because" |  | ||||||
|             echo "AppleTalk networking is unavailable. Please make sure that" |  | ||||||
|             echo "your Linux distribution has a loadable AppleTalk kernel module or" |  | ||||||
|             echo "has AppleTalk built into the kernel, and restart your server." |  | ||||||
|             echo "Or, if you previously disabled AppleTalk in A2SERVER, re-enable it" |  | ||||||
|             echo "by typing 'appletalk-on'." |  | ||||||
|             echo |  | ||||||
|         fi |  | ||||||
|          |  | ||||||
|         if [[ -f /tmp/noMacIP ]]; then |  | ||||||
|             echo |  | ||||||
|             echo "MacIP connections may be unavailable. If you know how, try" |  | ||||||
|             echo "recompiling the AppleTalk kernel module with IPDDP options disabled." |  | ||||||
|             echo |  | ||||||
|             rm /tmp/noMacIP |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         if [[ -f /tmp/singleUser ]]; then |  | ||||||
|             if [[ ! $autoAnswerYes ]]; then |  | ||||||
|                 echo |  | ||||||
|                 echo "Your Raspberry Pi was started in single-user mode in order to" |  | ||||||
|                 echo -n "fix a problem. You should restart to operate normally. Restart now? " |  | ||||||
|                 read |  | ||||||
|             fi |  | ||||||
|             if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then |  | ||||||
|                 sudo shutdown -r now |  | ||||||
|                 echo |  | ||||||
|                 echo "A2SERVER: Preparing to restart..." |  | ||||||
|                 while :; do sleep 60; done |  | ||||||
|             fi |  | ||||||
|             rm /tmp/singleUser |  | ||||||
|             echo |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         echo |  | ||||||
|         echo "Type 'system-shutdown' to turn off A2SERVER." |  | ||||||
|         echo "Type 'a2server-setup' to configure network boot." |  | ||||||
|         echo "Type 'a2server-help' for a list of other commands." |  | ||||||
|     fi |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| unset a2server_update 2> /dev/null |  | ||||||
| unset doSetup 2> /dev/null |  | ||||||
| rm /tmp/a2server-* 2> /dev/null |  | ||||||
| rm setup &> /dev/null |  | ||||||
|   | |||||||
							
								
								
									
										353
									
								
								setup/ivan.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										353
									
								
								setup/ivan.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,353 @@ | |||||||
|  | #! /bin/bash | ||||||
|  | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
|  | # A2SERVER master setup script, last update 17-Nov-15 | ||||||
|  | # it downloads and executes several scripts related to the setup of | ||||||
|  | # netatalk configured for Apple II use on Debian or Raspbian. | ||||||
|  | # more info is at http://ivanx.com/a2server | ||||||
|  |  | ||||||
|  | a2serverVersion="1.9.0" | ||||||
|  | a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/master" | ||||||
|  |  | ||||||
|  | # Find the path of our source directory | ||||||
|  | a2sSource="$( dirname "${BASH_SOURCE[0]}" )/.." | ||||||
|  | pushd $a2sSource >/dev/null | ||||||
|  | a2sSource="$PWD" | ||||||
|  | popd >/dev/null | ||||||
|  | if [[ ! -f "$a2sSource/.a2server_source" ]]; then | ||||||
|  | 	printf "\na2server: cannot find a2server source directory in $a2sSource.\n\n" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | compare_version="$a2sSource/scripts/compare_version" | ||||||
|  |  | ||||||
|  | isRpi= | ||||||
|  | [[ -f /usr/bin/raspi-config ]] && isRpi=1 | ||||||
|  |  | ||||||
|  | isDebian= | ||||||
|  | if [[ "$(lsb_release -ds)" = Debian* ]]; then | ||||||
|  | 	debianVersion="$(lsb_release -rs)" | ||||||
|  | 	if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then | ||||||
|  | 		isDebian=1 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [[ -f /usr/local/etc/A2SERVER-version ]]; then | ||||||
|  | 	read installedVersion </usr/local/etc/A2SERVER-version | ||||||
|  |     if [[ $installedVersion != *.*.* ]]; then | ||||||
|  | 		# Deal with old three-digit version | ||||||
|  |         installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}" | ||||||
|  |     fi | ||||||
|  | fi | ||||||
|  | echo "A2SERVER version available: $a2serverVersion" | ||||||
|  | echo "A2SERVER version installed: ${installedVersion:=None}" | ||||||
|  | if [[ $installedVersion == "None" ]]; then | ||||||
|  | 	installedVersion=0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | skipRepoUpdate= | ||||||
|  | autoAnswerYes= | ||||||
|  | installAll= | ||||||
|  | setupNetBoot= | ||||||
|  | setupWindowsSharing= | ||||||
|  | compileAlways= | ||||||
|  | rm -rf /tmp/a2server-install | ||||||
|  | rm /tmp/a2server-* 2> /dev/null | ||||||
|  | while [[ $1 ]]; do | ||||||
|  | 	if [[ $1 == "-r" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		skipRepoUpdate="-r" | ||||||
|  | 		touch /tmp/a2server-packageReposUpdated | ||||||
|  | 	elif [[ $1 == "-i" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		installAll="-i" | ||||||
|  | 	elif [[ $1 == "-y" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		autoAnswerYes="-y" | ||||||
|  | 		touch /tmp/a2server-autoAnswerYes | ||||||
|  | 	elif [[ $1 == "-b" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		setupNetBoot="-b" | ||||||
|  | 		touch /tmp/a2server-setupNetBoot | ||||||
|  | 	elif [[ $1 == "-w" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		setupWindowsSharing="-w" | ||||||
|  | 		touch /tmp/a2server-setupWindowsSharing | ||||||
|  | 	elif [[ $1 == "-c" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		compileAlways="-c" | ||||||
|  | 		touch /tmp/a2server-compileAlways | ||||||
|  | 	elif [[ $1 == "-v" ]]; then | ||||||
|  | 		shift | ||||||
|  | 		# Version was already printed | ||||||
|  | 		if [[ $0 == "-bash" ]]; then | ||||||
|  | 			return 1 | ||||||
|  | 		else | ||||||
|  | 			exit 1 | ||||||
|  | 		fi | ||||||
|  | 	elif [[ $1 ]]; then | ||||||
|  | 		echo "options:" | ||||||
|  | 		echo "-v: display installed and available versions, then exit" | ||||||
|  | 		echo "-i: reinstall A2SERVER software (but not Apple II software)" | ||||||
|  | 		echo "-y: auto-answer yes to all prompts" | ||||||
|  | 		echo "-r: don't update package repositories" | ||||||
|  | 		echo "-b: auto-setup network boot (use with -y)" | ||||||
|  | 		echo "-w: auto-setup Windows file sharing (use with -y)" | ||||||
|  | 		echo "-c: compile non-package items, rather than downloading binaries" | ||||||
|  | 		if [[ $0 == "-bash" ]]; then | ||||||
|  | 			return 1 | ||||||
|  | 		else | ||||||
|  | 			exit 1 | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if "$compare_version" $installedVersion lt 1.1.0; then | ||||||
|  | 	echo | ||||||
|  | 	echo "WARNING: The current A2SERVER installer scripts haven't been tested for" | ||||||
|  | 	echo "updating the earlier version of A2SERVER that you have. A fresh install" | ||||||
|  | 	echo "is suggested. Continuing is not recommended and could make A2SERVER" | ||||||
|  | 	echo "no longer work properly, or cause data to be lost." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | a2server_update=0 | ||||||
|  | doSetup=1 | ||||||
|  |  | ||||||
|  | if "$compare_version" $installedVersion lt 1.5.2; 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- | ||||||
|  | 			-2a329e0c7d8ea19c085bac5633aa4fccee0f21be- | ||||||
|  | 			-b2420fc150ae4616f5d9ec24bdaedc630586a529-" | ||||||
|  | 	if [[ "$fwsupported" == *-$fwhash-* ]]; then | ||||||
|  | 		unsupportedOS= | ||||||
|  | 	fi | ||||||
|  | elif [[ $isDebian ]]; then # supported Debian? | ||||||
|  | 	 debianVersion=$(cat /etc/debian_version) | ||||||
|  | 	 debianSupported="-9.2- -8.2- -7.9- -7.8- -7.6- -7.3-" | ||||||
|  | 	 [[ $debianSupported == *-$debianVersion-* ]] && unsupportedOS= | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [[ $unsupportedOS && $isRpi ]]; then | ||||||
|  | 	echo | ||||||
|  | 	echo "A2SERVER and its installer scripts have been tested on Raspbian Wheezy," | ||||||
|  | 	echo "Jessie, and Stretch though not this specific firmware version" | ||||||
|  | 	echo "(${fwhash:0:7}). Just FYI." | ||||||
|  | 	unsupportedOS= | ||||||
|  | elif [[ $unsupportedOS && $isDebian ]]; then | ||||||
|  | 	echo | ||||||
|  | 	echo "A2SERVER and its installer scripts have been tested on Debian 7/8/9," | ||||||
|  | 	echo "though not this specific point release ($debianVersion). Just FYI." | ||||||
|  | 	unsupportedOS= | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [[ $unsupportedOS ]]; then | ||||||
|  | 	echo | ||||||
|  | 	echo "WARNING: A2SERVER and its installer scripts have only been tested on" | ||||||
|  | 	echo "Debian and Raspbian. Continuing is probably fine, but might not be." | ||||||
|  | 	echo "Theoretical worst case would be your operating system no longer works" | ||||||
|  | 	echo "properly or data is lost, so consider backing up first." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | doSetup=1 | ||||||
|  | if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then | ||||||
|  | 	echo | ||||||
|  | 	echo "Setting up A2SERVER will take up to 60 minutes, during which" | ||||||
|  | 	echo "you'll see a bunch of stuff spit out across the screen." | ||||||
|  | 	echo | ||||||
|  | 	if [[ ! $autoAnswerYes ]]; then | ||||||
|  | 		echo -n "Ready to set up A2SERVER? " | ||||||
|  | 		read | ||||||
|  | 		[[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? )) | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if (( $doSetup )); then | ||||||
|  |  | ||||||
|  | 	echo | ||||||
|  | 	echo "a2server-setup modifies files and performs actions as the root user." | ||||||
|  | 	echo "For details, visit http://ivanx.com/a2server." | ||||||
|  | 	echo | ||||||
|  | 	if [[ ! $autoAnswerYes ]]; then | ||||||
|  | 		echo -n "Continue? " | ||||||
|  | 		read | ||||||
|  | 		[[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? )) | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if (( $doSetup )); then | ||||||
|  |  | ||||||
|  | 		origDir="$PWD" | ||||||
|  | 		rm -rf /tmp/a2server-install &>/dev/null | ||||||
|  | 		mkdir -p /tmp/a2server-install | ||||||
|  |  | ||||||
|  |         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 | ||||||
|  | 				fi | ||||||
|  | 			fi | ||||||
|  | 		done | ||||||
|  |  | ||||||
|  | 		echo | ||||||
|  | 		echo "During this installation, enter ${password} if prompted for passwords." | ||||||
|  | 		echo | ||||||
|  |  | ||||||
|  | 		sudo true | ||||||
|  |  | ||||||
|  | 		read -d '' a2sSubScripts <<-EOF | ||||||
|  | 			a2server-1-storage.txt | ||||||
|  | 			a2server-2-tools.txt | ||||||
|  | 			a2server-3-sharing.txt | ||||||
|  | 			a2server-5-netboot.txt | ||||||
|  | 			a2server-6-samba.txt | ||||||
|  | 			a2server-7-console.txt | ||||||
|  | 		EOF | ||||||
|  |  | ||||||
|  | 		if [[ $installAll ]]; then | ||||||
|  | 			sudo rm -f /usr/local/etc/A2SERVER-version | ||||||
|  | 			sudo rm -f /usr/local/bin/nulib2 | ||||||
|  | 			sudo rm -f /usr/local/bin/unar | ||||||
|  | 			sudo rm -f /usr/local/sbin/macipgw | ||||||
|  | 			sudo rm -f /usr/local/bin/ciopfs | ||||||
|  | 			sudo rm -f /usr/local/etc/netatalk/afppasswd | ||||||
|  | 			sudo rm -f /usr/local/etc/netatalk/a2boot/p8 | ||||||
|  | 			sudo rm -f /usr/local/etc/netatalk/a2boot/ProDOS16\ Image | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		for _script in $a2sSubScripts; do | ||||||
|  | 			"$a2sSource/scripts/$_script" | ||||||
|  | 		done | ||||||
|  |  | ||||||
|  | 		rm -f /tmp/a2server-packageReposUpdated | ||||||
|  |  | ||||||
|  | 		echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null | ||||||
|  |  | ||||||
|  | 		source /usr/local/etc/a2serverrc | ||||||
|  |  | ||||||
|  | 		# get Kernel release (e.g. 3.6.11+) and version (e.g. #557) | ||||||
|  | 		kernelRelease=$(uname -r) | ||||||
|  | 		kernelMajorRelease=$(cut -d '.' -f 1 <<< $kernelRelease) | ||||||
|  | 		kernelMinorRelease=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/') | ||||||
|  |  | ||||||
|  | 		echo | ||||||
|  | 		# all done, see if AppleTalk is available and notify either way | ||||||
|  | 		if [[ $(ps aux | grep [a]talkd) ]]; then | ||||||
|  | 			echo "You now have a fully functional file server for Apple II clients." | ||||||
|  | 			echo "On an Apple IIe, it should be accessible via \"Log In\" on the" | ||||||
|  | 			echo "Workstation Card software. For IIgs users, it should be accessible" | ||||||
|  | 			echo "via the AppleShare control panel." | ||||||
|  | 			if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then | ||||||
|  | 				echo | ||||||
|  | 				echo "You can network boot GS/OS." | ||||||
|  | 				echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)" | ||||||
|  | 				echo "to Your Card, and slot 7 to AppleTalk, and Startup Slot to 7 or Scan." | ||||||
|  | 				echo "On a ROM 3 IIgs, set slot 1 or 2, and Startup Slot, to AppleTalk." | ||||||
|  | 			fi | ||||||
|  | 			if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then | ||||||
|  | 				echo | ||||||
|  | 				echo "You can network boot ProDOS 8. On an Apple IIe, put your Workstation Card" | ||||||
|  | 				echo "in a slot above your disk controller card, or type PR#X with open-apple" | ||||||
|  | 				echo "held down, with X being the slot of your Workstation Card." | ||||||
|  | 				echo 'On a IIgs, press "8" during the initial procession of periods.' | ||||||
|  | 			fi | ||||||
|  | 			echo | ||||||
|  | 			echo "A2SERVER setup is complete! Go connect from your Apple II!" | ||||||
|  | 			echo | ||||||
|  | 		elif [[ -f /tmp/rpiUpdate ]]; then | ||||||
|  | 			echo "A2SERVER is now configured, but Apple II clients will not be able" | ||||||
|  | 			echo "to connect until you restart your Raspberry Pi." | ||||||
|  | 			echo | ||||||
|  | 			if [[ ! $autoAnswerYes ]]; then | ||||||
|  | 				echo -n "Restart now? " | ||||||
|  | 				read | ||||||
|  | 			fi | ||||||
|  | 			if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||||
|  | 				sudo shutdown -r now | ||||||
|  | 				echo | ||||||
|  | 				echo "A2SERVER: Preparing to restart..." | ||||||
|  | 				while :; do sleep 60; done | ||||||
|  | 			fi | ||||||
|  | 			rm /tmp/rpiUpdate | ||||||
|  | 			echo | ||||||
|  | 		elif [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRelease -le 15 ]]; then | ||||||
|  | 			echo "A2SERVER is now configured, but Apple II clients cannot connect" | ||||||
|  | 			echo "because of a kernel-crashing bug in Linux kernel 3.12 through 3.15." | ||||||
|  | 			echo "You have kernel version $kernelMajorRelease.$kernelMinorRelease." | ||||||
|  | 			echo "A2SERVER has disabled AppleTalk networking to prevent crashes." | ||||||
|  | 			echo "Please use kernel 3.11 or earlier, or kernel 3.16 or later." | ||||||
|  | 			echo | ||||||
|  | 		else | ||||||
|  | 			echo "A2SERVER is now configured, but Apple II clients cannot connect because" | ||||||
|  | 			echo "AppleTalk networking is unavailable. Please make sure that" | ||||||
|  | 			echo "your Linux distribution has a loadable AppleTalk kernel module or" | ||||||
|  | 			echo "has AppleTalk built into the kernel, and restart your server." | ||||||
|  | 			echo "Or, if you previously disabled AppleTalk in A2SERVER, re-enable it" | ||||||
|  | 			echo "by typing 'appletalk-on'." | ||||||
|  | 			echo | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		if [[ -f /tmp/noMacIP ]]; then | ||||||
|  | 			echo | ||||||
|  | 			echo "MacIP connections may be unavailable. If you know how, try" | ||||||
|  | 			echo "recompiling the AppleTalk kernel module with IPDDP options disabled." | ||||||
|  | 			echo | ||||||
|  | 			rm /tmp/noMacIP | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		if [[ -f /tmp/singleUser ]]; then | ||||||
|  | 			if [[ ! $autoAnswerYes ]]; then | ||||||
|  | 				echo | ||||||
|  | 				echo "Your Raspberry Pi was started in single-user mode in order to" | ||||||
|  | 				echo -n "fix a problem. You should restart to operate normally. Restart now? " | ||||||
|  | 				read | ||||||
|  | 			fi | ||||||
|  | 			if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||||
|  | 				sudo shutdown -r now | ||||||
|  | 				echo | ||||||
|  | 				echo "A2SERVER: Preparing to restart..." | ||||||
|  | 				while :; do sleep 60; done | ||||||
|  | 			fi | ||||||
|  | 			rm /tmp/singleUser | ||||||
|  | 			echo | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		echo | ||||||
|  | 		echo "Type 'system-shutdown' to turn off A2SERVER." | ||||||
|  | 		echo "Type 'a2server-setup' to configure network boot." | ||||||
|  | 		echo "Type 'a2server-help' for a list of other commands." | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | unset a2server_update 2> /dev/null | ||||||
|  | unset doSetup 2> /dev/null | ||||||
|  | rm -rf /tmp/a2server-install &>/dev/null | ||||||
|  | rm -f /tmp/a2server-* 2> /dev/null | ||||||
|  | rm -f setup &> /dev/null | ||||||
| @@ -117,4 +117,3 @@ | |||||||
|                  bug fixes when compiling macipgw and ciopfs; |                  bug fixes when compiling macipgw and ciopfs; | ||||||
|                  os option (Raspbian update) removed from a2server-setup |                  os option (Raspbian update) removed from a2server-setup | ||||||
|  |  | ||||||
| 1.5.3a1: July 2020: initial support for Debian/Raspbian Buster |  | ||||||
|   | |||||||
							
								
								
									
										123
									
								
								update/index.txt
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								update/index.txt
									
									
									
									
									
								
							| @@ -1,18 +1,34 @@ | |||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||||
|  |  | ||||||
| # Ensure URL we'll use ends in a / | # update/index.txt - upgrade path from Ivan's a2server tree | ||||||
| case "$A2SERVER_SCRIPT_URL" in | # | ||||||
| 	*/) scriptURL="$A2SERVER_SCRIPT_URL" ;; | # Ivan's a2server installed with a single copy-paste of a command line that | ||||||
| 	*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | # downloaded a script and ran it sight-unseen.  It also installed an alias | ||||||
| esac | # command that would perform a similar one-liner to upgrade a2server to the | ||||||
|  | # latest version.  This script provides that interface for upgrades. | ||||||
|  |  | ||||||
| currentVersion=$(wget -qO- "${scriptURL}setup/index.txt" | grep '^a2serverVersion' | cut -d '"' -f 2) | a2sBranch="master" | ||||||
|  | a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/${a2sBranch}" | ||||||
|  | a2sTarball="https://github.com/RasppleII/a2server/archive/${a2sBranch}.tar.gz" | ||||||
|  |  | ||||||
|  | # Set a2sSource to the location of the source tree if we're running in one | ||||||
|  | a2sSource="$( dirname "${BASH_SOURCE[0]}" )/.." | ||||||
|  | pushd $a2sSource >/dev/null | ||||||
|  | a2sSource="$PWD" | ||||||
|  | popd >/dev/null | ||||||
|  | if [[ ! -f "$a2sSource/.a2server_source" ]]; then | ||||||
|  | 	a2sWebUpdate=1 | ||||||
|  | 	a2sSource=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX) | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | installedVersion= | ||||||
| if [[ -f /usr/local/etc/A2SERVER-version ]]; then | if [[ -f /usr/local/etc/A2SERVER-version ]]; then | ||||||
|     installedVersion=$(cat /usr/local/etc/A2SERVER-version) | 	read installedVersion < /usr/local/etc/A2SERVER-version | ||||||
| else | 	# Convert old three-digit version if needed | ||||||
|     installedVersion=100 |     if [[ $installedVersion != *.*.* ]]; then | ||||||
|  |         installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}" | ||||||
|  |     fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
| autoAnswerYes= | autoAnswerYes= | ||||||
| @@ -23,23 +39,76 @@ for arg in $@; do | |||||||
| 	fi | 	fi | ||||||
| done | done | ||||||
|  |  | ||||||
| echo | printf "\na2server web update\n\n" | ||||||
| echo "Update history:" |  | ||||||
| wget -qO- "${scriptURL}update/versionhistory.txt" | if (( $a2sWebUpdate )); then | ||||||
| echo | 	newVersion=$(wget -qO- "${a2sScriptURL}/install.sh" | grep '^a2serverVersion' | cut -d '"' -f 2) | ||||||
| echo "installed version: ${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2:1}" | 	cat <<-EOT | ||||||
| echo "current version: ${currentVersion:0:1}.${currentVersion:1:1}.${currentVersion:2:1}" | 	You've started the single command a2server update script.  This script will | ||||||
| echo | 	download things behind the scenes, run them without much verification, and | ||||||
| if [[ $autoAnswerYes ]]; then | 	then it will delete what it ran whether the upgrade finished successfully or | ||||||
|     REPLY="y" | 	not.  For this reason, we are going to be phasing this script out in the | ||||||
|  | 	future. | ||||||
|  | 	EOT | ||||||
| else | else | ||||||
|     echo -n "Do you want to update (or reinstall) A2SERVER? " | 	newVersion=$(grep '^a2serverVersion' "$a2sSource/install.sh" | cut -d '"' -f 2) | ||||||
|     read | 	cat <<-EOT | ||||||
| fi | 	You've started the single command a2server update script from inside the | ||||||
| if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then | 	a2server source directory for version $newVersion.  This script will only | ||||||
|     # sudo rm /usr/local/etc/netatalk/a2boot/* &> /dev/null | 	upgrade to or reinstall that version. | ||||||
|     wget -q -O /tmp/setup "${scriptURL}setup/index.txt"; source /tmp/setup -i "$@" | 	EOT | ||||||
| fi | fi | ||||||
|  |  | ||||||
| unset currentVersion 2> /dev/null | if [[ $installedVersion ]]; then | ||||||
| unset installedVersion 2> /dev/null | 	printf "\nRight now you have a2server %s installed\n" "$installedVersion" | ||||||
|  | else | ||||||
|  | 	printf "\nRight now you don't appear to have a2server installed\n" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [[ ! $autoAnswerYes ]]; then | ||||||
|  | 	printf "\nPress Enter to continue " | ||||||
|  | 	read | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # If running from local source tree, that's what you'll be upgrading to | ||||||
|  | printf "\nProject history:\n" | ||||||
|  | if (( $a2sWebUpdate )); then | ||||||
|  | 	wget -qO- "${a2sScriptURL}/update/versionhistory.txt" | ||||||
|  | else | ||||||
|  | 	cat "$a2sSource/update/versionhistory.txt" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | cat <<EOT | ||||||
|  |  | ||||||
|  | installed version: ${installedVersion} | ||||||
|  | available version: ${newVersion} | ||||||
|  |  | ||||||
|  | EOT | ||||||
|  |  | ||||||
|  | if [[ ! $autoAnswerYes ]]; then | ||||||
|  | 	printf "Do you want to update (or reinstall) a2server? " | ||||||
|  | 	read | ||||||
|  | 	if [[ ${REPLY:0:1} != "y" && ${REPLY:0:1} != "Y" ]]; then | ||||||
|  | 		printf "\nOkay, not updating anything now!\n\n" | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if (( $a2sWebUpdate )); then | ||||||
|  | 	a2sSource=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX) | ||||||
|  |  | ||||||
|  | 	# Normally tarballs unpack in a subdirectory, but we want it to unpack into | ||||||
|  | 	# $a2sSource directly (even though the directory has the tarball in it.) | ||||||
|  | 	printf "\na2server: Downloading installer to $a2sSource.\n" | ||||||
|  | 	wget -O "$a2sSource/a2server-$a2sBranch.tar.gz" "$a2sTarball" | ||||||
|  | 	tar -C $a2sSource --strip-components=1 -zxf "$a2sSource/a2server-${a2sBranch}.tar.gz" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Now we actually run the installer as if we were installing it by hand | ||||||
|  | printf "\na2server: Running the update installer now.\n" | ||||||
|  | "${a2sSource}/install.sh" -i "$@" | ||||||
|  |  | ||||||
|  | if (( $a2sWebUpdate )); then | ||||||
|  | 	printf "\na2server: Finished with installer, now deleting ${a2sSource}.\n" | ||||||
|  | 	rm -rf "$a2sSource" | ||||||
|  | fi | ||||||
|   | |||||||
| @@ -67,6 +67,9 @@ | |||||||
|                  for current date; install from any host URL for development; |                  for current date; install from any host URL for development; | ||||||
|                  source code at GitHub (thanks Joseph) |                  source code at GitHub (thanks Joseph) | ||||||
|  |  | ||||||
|  | 1.5.0r2: Jan 16: fixed GitHub URLs to prevent https errors during installation | ||||||
|  |                  (thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html) | ||||||
|  |  | ||||||
| 1.5.1: Jan 2016: fixed GitHub URLs to prevent https errors during installation | 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); |                  (thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html); | ||||||
|                  bug fixes and minor text changes |                  bug fixes and minor text changes | ||||||
| @@ -77,8 +80,6 @@ | |||||||
|                  install; enable SSH server if disabled on Raspberry Pi; fixes |                  install; enable SSH server if disabled on Raspberry Pi; fixes | ||||||
|                  changed download links for GS/OS communication software |                  changed download links for GS/OS communication software | ||||||
|  |  | ||||||
| 1.5.3a2: July 2020: initial support for Debian/Raspbian Buster |  | ||||||
|  |  | ||||||
| Big thanks to: Anthony Martino, Henry Courbis, Joseph Carter, Jason King, | Big thanks to: Anthony Martino, Henry Courbis, Joseph Carter, Jason King, | ||||||
| Andy McFadden, Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, David Schmidt, | Andy McFadden, Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, David Schmidt, | ||||||
| David Schmenk, Ewen Wannop, Andrew Roughan, Antoine Vignau, Martin Haye, | David Schmenk, Ewen Wannop, Andrew Roughan, Antoine Vignau, Martin Haye, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user