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 | ||||
| AppleTalk server for Apple // computers developed by Ivan Drucker, with | ||||
| substantial rework and by T. Joseph Carter | ||||
| AppleTalk server for Apple // computers developed by Ivan Drucker | ||||
|  | ||||
| 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 | ||||
| @@ -14,91 +13,7 @@ relatively modern piece of it.  As such they should be preserved as they are. | ||||
|  | ||||
| ## Developer note | ||||
|  | ||||
| To use the scripts with a specific GitHub tag: | ||||
| ~~~ bash | ||||
| export A2SERVER_SCRIPT_URL=https://raw.githubusercontent.com/RasppleII/a2server/TAG_GOES_HERE/ | ||||
| export A2SERVER_BINARY_URL=${A2SERVER_SCRIPT_URL}files | ||||
| wget -O setup ${A2SERVER_SCRIPT_URL}setup/index.txt; source setup | ||||
| ~~~ | ||||
|  | ||||
| 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 | ||||
| ~~~ | ||||
|  | ||||
| This section used to describe how to run these scripts directly.  That's | ||||
| changing.  Watch this space. | ||||
|  | ||||
| [Ivan's site]: http://appleii.ivanx.com/a2server/ | ||||
|   | ||||
							
								
								
									
										52
									
								
								files/dist/getexternal.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								files/dist/getexternal.sh
									
									
									
									
										vendored
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| if ! hash wget; then | ||||
|     echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew." | ||||
| 	echo "wget is not installed. On a Mac, install it with MacPorts or Homebrew." | ||||
| fi | ||||
|  | ||||
| echo "Downloading items..." | ||||
| @@ -36,30 +36,30 @@ wget -O files/external/appleii/sam2.bxy "$samUrl" | ||||
| wget -O files/external/appleii/snap.bxy "$snapUrl" | ||||
|  | ||||
| for gsosInstall in {1..3}; do | ||||
|     activeDisk=0 | ||||
|     mkdir -p files/external/appleii/gsos60${gsosInstall} | ||||
| 	activeDisk=0 | ||||
| 	mkdir -p files/external/appleii/gsos60${gsosInstall} | ||||
|  | ||||
|     diskNames=( Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB ) | ||||
|     if (( $gsosInstall == 1 )); then | ||||
|         gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/" | ||||
|         wget --max-redirect 0 -O files/external/appleii/gsos601/Disk_7_of_7-Apple_II_Setup.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/Disk_7_of_7-Apple_II_Setup.sea.bin | ||||
|     elif (( $gsosInstall == 2 )); then | ||||
|         gsosURL="http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Software/Operating%20Systems/Apple%20IIGS%20System/Disk%20Images/" | ||||
|         diskNames=( Install System.Disk SystemTools1 SystemTools2 SystemTools3 Fonts1 Fonts2 synthLAB ) | ||||
|         diskWebNames=( Install System%20disk System%20tools%201 System%20tools%202 System%20tools%203 Fonts%201 Fonts%202 Synthlab ) | ||||
|     elif (( $gsosInstall == 3 )); then | ||||
|         gsosURL="ftp://ftp.apple.asimov.net/pub/apple_II/images/gs/os/gsos/Apple_IIGS_System_6.0.3/" | ||||
|     fi | ||||
| 	diskNames=( Install System.Disk SystemTools1 SystemTools2 Fonts synthLAB ) | ||||
| 	if (( $gsosInstall == 1 )); then | ||||
| 		gsosURL="http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/" | ||||
| 		wget --max-redirect 0 -O files/external/appleii/gsos601/Disk_7_of_7-Apple_II_Setup.sea.bin http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/English-North_American/Apple_II/Apple_IIGS_System_6.0.1/Disk_7_of_7-Apple_II_Setup.sea.bin | ||||
| 	elif (( $gsosInstall == 2 )); then | ||||
| 		gsosURL="http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Software/Operating%20Systems/Apple%20IIGS%20System/Disk%20Images/" | ||||
| 		diskNames=( Install System.Disk SystemTools1 SystemTools2 SystemTools3 Fonts1 Fonts2 synthLAB ) | ||||
| 		diskWebNames=( Install System%20disk System%20tools%201 System%20tools%202 System%20tools%203 Fonts%201 Fonts%202 Synthlab ) | ||||
| 	elif (( $gsosInstall == 3 )); then | ||||
| 		gsosURL="ftp://ftp.apple.asimov.net/pub/apple_II/images/gs/os/gsos/Apple_IIGS_System_6.0.3/" | ||||
| 	fi | ||||
|  | ||||
|     for diskname in ${diskNames[@]}; do | ||||
|         outfile="files/external/appleii/gsos60${gsosInstall}/$diskname.po" | ||||
|         (( activeDisk++ )) | ||||
|         if (( $gsosInstall == 1 )); then | ||||
|             wget --max-redirect 0 -O files/external/appleii/gsos601/"Disk_${activeDisk}_of_7-${diskname}.sea.bin" "${gsosURL}Disk_${activeDisk}_of_7-${diskname}.sea.bin" | ||||
|         elif (( $gsosInstall == 2 )); then | ||||
|             wget -O $outfile "$gsosURL/IIGS%20System%206.0.2%20-%20Disk%20${activeDisk}%20${diskWebNames[$activeDisk-1]}.po" | ||||
|         elif (( $gsosInstall == 3 )); then | ||||
|             wget -O $outfile "$gsosURL/$diskname.po" | ||||
|         fi | ||||
|     done | ||||
| 	for diskname in ${diskNames[@]}; do | ||||
| 		outfile="files/external/appleii/gsos60${gsosInstall}/$diskname.po" | ||||
| 		(( activeDisk++ )) | ||||
| 		if (( $gsosInstall == 1 )); then | ||||
| 			wget --max-redirect 0 -O files/external/appleii/gsos601/"Disk_${activeDisk}_of_7-${diskname}.sea.bin" "${gsosURL}Disk_${activeDisk}_of_7-${diskname}.sea.bin" | ||||
| 		elif (( $gsosInstall == 2 )); then | ||||
| 			wget -O $outfile "$gsosURL/IIGS%20System%206.0.2%20-%20Disk%20${activeDisk}%20${diskWebNames[$activeDisk-1]}.po" | ||||
| 		elif (( $gsosInstall == 3 )); then | ||||
| 			wget -O $outfile "$gsosURL/$diskname.po" | ||||
| 		fi | ||||
| 	done | ||||
| done | ||||
|   | ||||
| @@ -45,7 +45,7 @@ HOSTNAME=`/bin/hostname` | ||||
|  | ||||
| # Read in netatalk configuration. | ||||
| if [ -f /etc/default/netatalk ]; then | ||||
|     . /etc/default/netatalk | ||||
| 	. /etc/default/netatalk | ||||
| fi | ||||
|  | ||||
| # Start Netatalk servers. | ||||
| @@ -53,9 +53,9 @@ atalk_startup() { | ||||
| 	if [ x"$ATALKD_RUN" = x"yes" ]; then | ||||
|  | ||||
| 	# Try to load the AppleTalk kernel module if it was intended. | ||||
|     if grep -q '^appletalk$' /etc/modules; then | ||||
| 	if grep -q '^appletalk$' /etc/modules; then | ||||
| 		/sbin/modprobe appletalk || echo "[could not load appletalk module]" | ||||
|     fi | ||||
| 	fi | ||||
|  | ||||
| 	# Start atalkd server. | ||||
| 	/usr/local/sbin/atalkd | ||||
| @@ -70,8 +70,8 @@ atalk_startup() { | ||||
| 	# prepare startup of file services | ||||
| 	if [ "x$CNID_METAD_RUN" = "xyes" -a -x /usr/local/sbin/cnid_metad ] ; then | ||||
| 		echo -n " cnid_metad" | ||||
|         /usr/local/sbin/cnid_metad $CNID_CONFIG | ||||
|     fi | ||||
| 		/usr/local/sbin/cnid_metad $CNID_CONFIG | ||||
| 	fi | ||||
|  | ||||
| 	if [ x"$AFPD_RUN" = x"yes" ]; then | ||||
| 	/usr/local/sbin/afpd $AFPD_UAMLIST -g $AFPD_GUEST -c $AFPD_MAX_CLIENTS \ | ||||
| @@ -79,17 +79,17 @@ atalk_startup() { | ||||
| 	echo -n " afpd" | ||||
| 	fi | ||||
|  | ||||
|     if [ "x$ATALKD_RUN" = "xyes" ]; then | ||||
|         if [ "x$PAPD_RUN" = "xyes" ]; then | ||||
|             /usr/local/sbin/papd | ||||
|             echo -n " papd" | ||||
|         fi | ||||
| 	if [ "x$ATALKD_RUN" = "xyes" ]; then | ||||
| 		if [ "x$PAPD_RUN" = "xyes" ]; then | ||||
| 			/usr/local/sbin/papd | ||||
| 			echo -n " papd" | ||||
| 		fi | ||||
|  | ||||
|         if [ x"$TIMELORD_RUN" = x"yes" ]; then | ||||
|             /usr/local/sbin/timelord | ||||
|             echo -n " timelord" | ||||
|         fi | ||||
|     fi | ||||
| 		if [ x"$TIMELORD_RUN" = x"yes" ]; then | ||||
| 			/usr/local/sbin/timelord | ||||
| 			echo -n " timelord" | ||||
| 		fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| case "$1" in | ||||
| @@ -113,19 +113,19 @@ case "$1" in | ||||
| 		start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/cnid_metad | ||||
|  | ||||
| 		if test -x /usr/local/sbin/papd; then | ||||
|                     echo -n " papd" | ||||
| 		    start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/papd | ||||
| 	        fi | ||||
| 					echo -n " papd" | ||||
| 			start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/papd | ||||
| 			fi | ||||
|  | ||||
| 		if test -x /usr/local/sbin/timelord; then | ||||
|                     echo -n " timelord" | ||||
| 		    start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/timelord | ||||
| 	        fi | ||||
| 					echo -n " timelord" | ||||
| 			start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/timelord | ||||
| 			fi | ||||
|  | ||||
| 		if test -x /usr/local/sbin/atalkd; then | ||||
|                     echo -n " atalkd" | ||||
| 		    start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd | ||||
| 	        fi | ||||
| 					echo -n " atalkd" | ||||
| 			start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/atalkd | ||||
| 			fi | ||||
|  | ||||
| 		echo "." | ||||
| 	;; | ||||
|   | ||||
							
								
								
									
										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,31 +1,25 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # --- Setting up the share volume | ||||
|  | ||||
| # 1.3.0: move /media/A2SHARED (pre-1.3.0) to /srv/A2SERVER | ||||
| if [[ -d /media/A2SHARED ]]; then | ||||
|     echo "A2SERVER: Moving /media/A2SHARED to /srv/A2SERVER..." | ||||
|     sudo /etc/init.d/netatalk stop &> /dev/null | ||||
|     sudo /etc/init.d/samba stop &> /dev/null | ||||
|     [[ ! -d /srv ]] && sudo mkdir -p /srv | ||||
|     sudo mv /media/A2SHARED /srv/A2SERVER | ||||
|     sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /usr/local/etc/netatalk/AppleVolumes.default | ||||
|     [[ -f /etc/samba/smbd.conf ]] && sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /etc/samba/smbd.conf | ||||
|      | ||||
| 	echo "A2SERVER: Moving /media/A2SHARED to /srv/A2SERVER..." | ||||
| 	sudo /etc/init.d/netatalk stop &> /dev/null | ||||
| 	sudo /etc/init.d/samba stop &> /dev/null | ||||
| 	[[ ! -d /srv ]] && sudo mkdir -p /srv | ||||
| 	sudo mv /media/A2SHARED /srv/A2SERVER | ||||
| 	sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /usr/local/etc/netatalk/AppleVolumes.default | ||||
| 	if [[ -f /etc/samba/smbd.conf ]]; then | ||||
| 		sudo sed -i 's|/media/A2SHARED|/srv/A2SERVER|g' /etc/samba/smbd.conf | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # skip if we're already set up | ||||
| if [[ -d /srv/A2SERVER ]]; then | ||||
|  | ||||
|     echo "A2SERVER: Shared volume is already prepared for use." | ||||
|  | ||||
| if [[ ! -d /srv/A2SERVER ]]; then | ||||
| 	echo "A2SERVER: Preparing the shared files volume..." | ||||
| 	sudo mkdir -p /srv/A2SERVER | ||||
| 	sudo chown $USER:$USER /srv/A2SERVER | ||||
| else | ||||
|  | ||||
|     echo "A2SERVER: Preparing the shared files volume..." | ||||
|  | ||||
|     sudo mkdir -p /srv/A2SERVER | ||||
|  | ||||
|     sudo chown $USER:$USER /srv/A2SERVER | ||||
|  | ||||
| 	echo "A2SERVER: Shared volume is already prepared for use." | ||||
| fi | ||||
|   | ||||
| @@ -1,111 +1,109 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # download and install a2server tools: | ||||
| # mkatinit, mkvolinfo, afptype, afpsync, aliases, nulib2 | ||||
|  | ||||
| # Ensure URL we'll use ends in a / | ||||
| case "$A2SERVER_SCRIPT_URL" in | ||||
| 	*/) scriptURL="$A2SERVER_SCRIPT_URL" ;; | ||||
| 	*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | ||||
| esac | ||||
| case "$A2SERVER_BINARY_URL" in | ||||
| 	*/) binaryURL="$A2SERVER_BINARY_URL" ;; | ||||
| 	*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;; | ||||
| esac | ||||
| a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/master" | ||||
| a2sBinaryURL="http://blocksfree.com/downloads" | ||||
|  | ||||
| # Find the path of our source directory | ||||
| 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 | ||||
|  | ||||
| useExternalURL=1 | ||||
| [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | ||||
|  | ||||
| debianVersion=$(cat /etc/debian_version 2> /dev/null) | ||||
| debianVersion="$(lsb_release -rs)" | ||||
| isRpi= | ||||
| arch= | ||||
| if [[ -f /usr/bin/raspi-config ]]; then | ||||
|     isRpi=1 | ||||
|     arch='rpi' | ||||
| elif lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ $(cut -d . -f 1 <<< $debianVersion) -ge "7" ]]; then | ||||
|     uname_m="$(uname -m)" | ||||
|     if [[ $uname_m == "i686" ]]; then | ||||
|         arch='debian_x86' | ||||
|     elif [[ $uname_m == "x86_64" ]]; then | ||||
|         arch='debian_x64' | ||||
|     fi | ||||
| 	isRpi=1 | ||||
| 	arch='rpi' | ||||
| elif [[ "$(lsb_release -ds)" = Debian* ]]; then | ||||
| 	if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then | ||||
| 		uname_m="$(uname -m)" | ||||
| 		if [[ $uname_m == "i686" ]]; then | ||||
| 			arch='debian_x86' | ||||
| 		elif [[ $uname_m == "x86_64" ]]; then | ||||
| 			arch='debian_x64' | ||||
| 		fi | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| debianName= | ||||
| if [[ $debianVersion ]]; then | ||||
|     debianMajor=$(cut -d . -f 1 <<< $debianVersion) | ||||
|     if [[ $debianMajor == "9" ]]; then | ||||
|         debianName="stretch" | ||||
|     elif [[ $debianMajor == "8" ]]; then | ||||
|         debianName="jessie" | ||||
|     elif [[ $debianMajor == "7" ]]; then | ||||
|         debianName="wheezy" | ||||
|     else | ||||
|         debianName="unknown" | ||||
|     fi | ||||
| fi | ||||
| debianName=$(lsb_release -cs) | ||||
|  | ||||
| echo "A2SERVER: Installing A2SERVER tools..." | ||||
|  | ||||
| # delete older nulib2 which doesn't correctly handle zero-length forks in GSHK-created archives | ||||
| if hash nulib2 &> /dev/null; then | ||||
|     nulib2version=$(nulib2 | sed -n 2p | sed 's|^.*v\([0-9]\)\.\([0-9]\)\.\([0-9]\).*$|\1\2\3|' 2> /dev/null) | ||||
|     if (( $nulib2version < 310 )); then | ||||
|         sudo apt-get -y purge nulib2 &> /dev/null | ||||
|         sudo rm $(command -v nulib2) &> /dev/null | ||||
|     fi | ||||
| 	# FIXME make this sed more robust | ||||
| 	nulib2version=$(nulib2 | sed -n 2p | sed 's|^.*v\([0-9]\)\.\([0-9]\)\.\([0-9]\).*$|\1\2\3|' 2> /dev/null) | ||||
| 	if (( $nulib2version < 310 )); then | ||||
| 		sudo apt-get -y purge nulib2 &> /dev/null | ||||
| 		sudo rm $(command -v nulib2) &> /dev/null | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| if ! hash nulib2 &> /dev/null; then | ||||
|  | ||||
|     echo "A2SERVER: Installing nulib2..." | ||||
| 	echo "A2SERVER: Installing nulib2..." | ||||
|  | ||||
|     cd /tmp | ||||
|     if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||
|         { wget -qO- "${binaryURL}precompiled/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null | ||||
|     fi | ||||
| 	cd /tmp | ||||
| 	if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||
| 		{ wget -qO- "${a2sBinaryURL}/picopkg/nulib2-3.1.0a2-${arch}.tgz" | sudo tar Pzx; } &> /dev/null | ||||
| 	fi | ||||
|  | ||||
|     if ! hash nulib2 &> /dev/null; then | ||||
| 	if ! hash nulib2 &> /dev/null; then | ||||
|  | ||||
|         if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
|             # prepare for installing packages | ||||
|             sudo apt-get -y update | ||||
|             touch /tmp/a2server-packageReposUpdated | ||||
|         fi | ||||
| 		if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
| 			# prepare for installing packages | ||||
| 			sudo apt-get -y update | ||||
| 			touch /tmp/a2server-packageReposUpdated | ||||
| 		fi | ||||
|  | ||||
|         # Dependencies: build-dep for nulib | ||||
|         sudo apt-get -y install build-essential zlib1g-dev | ||||
|         sudo apt-get -y clean | ||||
| 		# Dependencies: build-dep for nulib | ||||
| 		sudo apt-get -y install build-essential zlib1g-dev | ||||
| 		sudo apt-get -y clean | ||||
|  | ||||
|         cd /tmp | ||||
|         rm -rf /tmp/nulib2 &> /dev/null | ||||
|         mkdir /tmp/nulib2 | ||||
|         cd /tmp/nulib2 | ||||
|         if [[ $useExternalURL ]]; then | ||||
|             wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7efb4d37fedf807416c16d74d51d893ea48a.zip" | ||||
|             unzip nulib2-3.1.0a2.zip 2> /dev/null | ||||
|             rm nulib2-3.1.0a2.zip &> /dev/null | ||||
|         fi | ||||
|         if [ ! -d nulib2* ]; then | ||||
|             wget -q -O nulib2-3.1.0a2.zip "${binaryURL}external/source/nulib2-3.1.0a2.zip" | ||||
|             unzip nulib2-3.1.0a2.zip 2> /dev/null | ||||
|             rm nulib2-3.1.0a2.zip &> /dev/null | ||||
|         fi | ||||
|         cd nulib2* | ||||
|         cd nufxlib | ||||
|         ./configure | ||||
|         make | ||||
|         sudo make install | ||||
|         cd ../nulib2 | ||||
|         ./configure | ||||
|         make | ||||
|         sudo make install | ||||
|         cd | ||||
|         rm -rf /tmp/nulib2 | ||||
|     fi | ||||
| 		cd /tmp | ||||
| 		rm -rf /tmp/nulib2 &> /dev/null | ||||
| 		mkdir /tmp/nulib2 | ||||
| 		cd /tmp/nulib2 | ||||
| 		if [[ $useExternalURL ]]; then | ||||
| 			# nulib2 does not have this tagged so we use github's auto-zipball feature | ||||
| 			# note: topdir is nulib2-<full hash> | ||||
| 			# note2: .tar.gz also works | ||||
| 			wget -q -O nulib2-3.1.0a2.zip "https://github.com/fadden/nulib2/archive/20fe7ef.zip" | ||||
| 			unzip nulib2-3.1.0a2.zip 2> /dev/null | ||||
| 			rm nulib2-3.1.0a2.zip &> /dev/null | ||||
| 		fi | ||||
| 		if [ ! -d nulib2* ]; then | ||||
| 			wget -q -O nulib2-3.1.0a2.zip "${a2sBinaryURL}/source/nulib2-3.1.0a2.zip" | ||||
| 			unzip nulib2-3.1.0a2.zip 2> /dev/null | ||||
| 			rm nulib2-3.1.0a2.zip &> /dev/null | ||||
| 		fi | ||||
| 		cd nulib2* | ||||
| 		cd nufxlib | ||||
| 		./configure | ||||
| 		make | ||||
| 		sudo make install | ||||
| 		cd ../nulib2 | ||||
| 		./configure | ||||
| 		make | ||||
| 		sudo make install | ||||
| 		cd | ||||
| 		rm -rf /tmp/nulib2 | ||||
| 	fi | ||||
|  | ||||
| else | ||||
|     echo "A2SERVER: Nulib2 has already been installed." | ||||
| 	echo "A2SERVER: Nulib2 has already been installed." | ||||
| fi | ||||
|  | ||||
| # download and install The Unarchiver, for expanding Apple disk images | ||||
| @@ -113,101 +111,104 @@ fi | ||||
|  | ||||
| if ! hash unar &> /dev/null; then | ||||
|  | ||||
|     echo "A2SERVER: Installing The Unarchiver..." | ||||
| 	echo "A2SERVER: Installing The Unarchiver..." | ||||
|  | ||||
|     if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
|         # prepare for installing packages | ||||
|         sudo apt-get -y update | ||||
|         touch /tmp/a2server-packageReposUpdated | ||||
|     fi | ||||
| 	if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
| 		# prepare for installing packages | ||||
| 		sudo apt-get -y update | ||||
| 		touch /tmp/a2server-packageReposUpdated | ||||
| 	fi | ||||
|  | ||||
|     # jessie and later: Just use the unar package | ||||
|     if [[ $debianMajor -ge 8 ]]; then | ||||
|         sudo apt-get -y install unar | ||||
|         sudo apt-get clean | ||||
|     fi | ||||
| 	# jessie and later: Just use the unar package | ||||
| 	if [[ "$debianName" != "wheezy" ]]; then | ||||
| 		sudo apt-get -y install unar | ||||
| 		sudo apt-get clean | ||||
| 	fi | ||||
|  | ||||
|     if ! hash unar &> /dev/null; then | ||||
|         if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||
|             # Dependencies: for unar | ||||
|             sudo apt-get -y install libgnustep-base1.22 | ||||
|             sudo apt-get clean | ||||
|             { wget -qO- "${binaryURL}precompiled/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null | ||||
|         fi | ||||
| 	if ! hash unar &> /dev/null; then | ||||
| 		if [[ $arch && ! -f /tmp/a2server-compileAlways ]]; then | ||||
| 			# Dependencies: for unar | ||||
| 			sudo apt-get -y install libgnustep-base1.22 | ||||
| 			sudo apt-get clean | ||||
| 			{ wget -qO- "${a2sBinaryURL}/picopkg/unar-${arch}_${debianName}.tgz" | sudo tar Pzx; } &> /dev/null | ||||
| 		fi | ||||
|  | ||||
|         # If all else fails, compile from source. | ||||
|         if ! hash unar &> /dev/null; then | ||||
| 		# If all else fails, compile from source. | ||||
| 		if ! hash unar &> /dev/null; then | ||||
|  | ||||
|             # Dependencies: build-deps for unar | ||||
|             sudo apt-get -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip | ||||
|             sudo apt-get clean | ||||
| 			# Dependencies: build-deps for unar | ||||
| 			sudo apt-get -y install build-essential libgnustep-base-dev libz-dev libbz2-dev libssl-dev libicu-dev unzip | ||||
| 			sudo apt-get clean | ||||
|  | ||||
|             rm -rf /tmp/unar &> /dev/null | ||||
|             mkdir /tmp/unar | ||||
|             cd /tmp/unar | ||||
|             if [[ $useExternalURL ]]; then | ||||
|                 wget -O unar-1.8.1.zip https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip | ||||
|                 unzip -o unar-1.8.1.zip &> /dev/null | ||||
|             fi | ||||
|             if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob | ||||
|                 wget -O unar-1.8.1.zip ${binaryURL}external/source/unar-1.8.1.zip | ||||
|                 unzip -o unar-1.8.1.zip &> /dev/null | ||||
|             fi | ||||
|             cd *Unarchiver*/XADMaster | ||||
|             make -f Makefile.linux | ||||
|             sudo mv lsar unar /usr/local/bin | ||||
|             cd ../Extra | ||||
|             sudo mv lsar.1 unar.1 /usr/local/man/man1 | ||||
|             cd | ||||
|             rm -rf /tmp/unar | ||||
|         fi | ||||
|         sudo mandb &> /dev/null | ||||
|     fi | ||||
| 			rm -rf /tmp/unar &> /dev/null | ||||
| 			mkdir /tmp/unar | ||||
| 			cd /tmp/unar | ||||
| 			if [[ $useExternalURL ]]; then | ||||
| 				wget -O unar-1.8.1.zip "https://github.com/incbee/Unarchiver/archive/unar-1.8.1.zip" | ||||
| 				unzip -o unar-1.8.1.zip &> /dev/null | ||||
| 			fi | ||||
| 			if [ ! -d *Unarchiver*/XADMaster ]; then # need single bracket for glob | ||||
| 				wget -O unar-1.8.1.zip "${a2sBinaryURL}/source/unar-1.8.1.zip" | ||||
| 				unzip -o unar-1.8.1.zip &> /dev/null | ||||
| 			fi | ||||
| 			cd *Unarchiver*/XADMaster | ||||
| 			make -f Makefile.linux | ||||
| 			sudo mv lsar unar /usr/local/bin | ||||
| 			cd ../Extra | ||||
| 			sudo mv lsar.1 unar.1 /usr/local/man/man1 | ||||
| 			cd | ||||
| 			rm -rf /tmp/unar | ||||
| 		fi | ||||
| 		sudo mandb &> /dev/null | ||||
| 	fi | ||||
| else | ||||
|     echo "A2SERVER: The Unarchiver has already been installed." | ||||
| 	echo "A2SERVER: The Unarchiver has already been installed." | ||||
| fi | ||||
|  | ||||
| if ! hash unzip &> /dev/null; then | ||||
|     echo "A2SERVER: Installing unzip..." | ||||
|     if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
|         # prepare for installing packages | ||||
|         sudo apt-get -y update | ||||
|         touch /tmp/a2server-packageReposUpdated | ||||
|     fi | ||||
| 	echo "A2SERVER: Installing unzip..." | ||||
| 	if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
| 		# prepare for installing packages | ||||
| 		sudo apt-get -y update | ||||
| 		touch /tmp/a2server-packageReposUpdated | ||||
| 	fi | ||||
|  | ||||
|     # Dependencies: unzip | ||||
|     sudo apt-get -y install unzip | ||||
|     sudo apt-get clean | ||||
| 	# Dependencies: unzip | ||||
| 	sudo apt-get -y install unzip | ||||
| 	sudo apt-get clean | ||||
| else | ||||
|     echo "A2SERVER: unzip has already been installed." | ||||
| 	echo "A2SERVER: unzip has already been installed." | ||||
| fi | ||||
|  | ||||
| sudo wget -q -O /usr/local/bin/afpsync "${scriptURL}scripts/tools/afpsync.txt" | ||||
| sudo chmod ugo+x /usr/local/bin/afpsync | ||||
| sudo wget -q -O /usr/local/bin/afptype "${scriptURL}scripts/tools/afptype.txt" | ||||
| sudo chmod ugo+x /usr/local/bin/afptype | ||||
| sudo wget -q -O /usr/local/bin/mkatinit "${scriptURL}scripts/tools/mkatinit.txt" | ||||
| sudo chmod ugo+x /usr/local/bin/mkatinit | ||||
| sudo wget -q -O /usr/local/bin/mkvolinfo "${scriptURL}scripts/tools/mkvolinfo.txt" | ||||
| sudo chmod ugo+x /usr/local/bin/mkvolinfo | ||||
| sudo wget -q -O /usr/local/bin/cppo "${scriptURL}scripts/tools/cppo.txt" | ||||
| sudo chmod ugo+x /usr/local/bin/cppo | ||||
| sudo wget -q -O /usr/local/etc/a2server-help.txt "${scriptURL}scripts/tools/a2server-help.txt" | ||||
| sudo wget -q -O /usr/local/etc/a2server-aliases "${scriptURL}scripts/tools/a2server-aliases.txt" | ||||
| sudo wget -q -O /usr/local/etc/a2serverrc "${scriptURL}scripts/tools/a2serverrc.txt" | ||||
| a2sTools="afpsync afptype mkatinit mkvolinfo cppo debupdate" | ||||
| a2sHelp="a2server-help.txt" | ||||
| a2sConfScripts="a2server-aliases a2serverrc" | ||||
| for _tool in $a2sTools; do | ||||
| 	sudo install -m 755 "$a2sSource/scripts/tools/$_tool" "/usr/local/bin/$_tool" | ||||
| done | ||||
| for _help in $a2sHelp; do | ||||
| 	sudo install -m 644 "$a2sSource/scripts/tools/$_help" "/usr/local/etc/$_help" | ||||
| done | ||||
| for _confscript in $a2sConfScripts; do | ||||
| 	sudo install -m 755 "$a2sSource/scripts/tools/$_confscript" "/usr/local/etc/$_tool" | ||||
| done | ||||
|  | ||||
| # 1.3.0: a2serverrc is now called from /etc/bash.bashrc, | ||||
| #   which in turn calls a2server-aliases | ||||
| grep 'a2server-aliases' /etc/bash.bashrc > /dev/null && \ | ||||
| sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc | ||||
| grep 'a2serverrc' /etc/bash.bashrc > /dev/null || \ | ||||
| echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc > /dev/null | ||||
| if grep 'a2server-aliases' /etc/bash.bashrc >/dev/null; then | ||||
| 	sudo sed -i 's/a2server-aliases/a2serverrc/' /etc/bash.bashrc | ||||
| fi | ||||
| if ! grep 'a2serverrc' /etc/bash.bashrc >/dev/null; then | ||||
| 	echo "source /usr/local/etc/a2serverrc" | sudo tee -a /etc/bash.bashrc >/dev/null | ||||
| fi | ||||
|  | ||||
| motd="/etc/motd" | ||||
| if [[ ! $(grep A2SERVER $motd) ]]; then | ||||
|     echo | sudo tee -a $motd > /dev/null | ||||
|     echo "Type 'system-shutdown' to turn off A2SERVER." | sudo tee -a $motd > /dev/null | ||||
|     echo "Type 'a2server-setup' to configure network boot." | sudo tee -a $motd > /dev/null | ||||
|     echo "Type 'a2server-help' for a list of other commands." | sudo tee -a $motd > /dev/null | ||||
|     echo | sudo tee -a $motd > /dev/null | ||||
| 	sudo tee -a $motd >/dev/null <<EOF | ||||
|  | ||||
| Type 'system-shutdown' to turn off A2SERVER. | ||||
| Type 'a2server-setup' to configure network boot. | ||||
| Type 'a2server-help' for a list of other commands. | ||||
|  | ||||
| EOF | ||||
| fi | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,86 +1,98 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # Set up A2SERVER to support Samba (Windows File Sharing) | ||||
| # this script can also be used if new shares are introduced | ||||
|  | ||||
| [[ -f /tmp/a2server-autoAnswerYes ]] && autoAnswerYes=1 || autoAnswerYes= | ||||
| autoAnswerYes= | ||||
| if [[ -f /tmp/a2server-autoAnswerYes ]]; then | ||||
| 	autoAnswerYes=1 | ||||
| fi | ||||
|  | ||||
| if [[ ! $autoAnswerYes || -f /tmp/a2server-setupWindowsSharing ]]; then | ||||
|  | ||||
|     if [[ ! $autoAnswerYes ]]; then | ||||
|         echo | ||||
|         echo -n "Should Windows computers be able to connect to A2SERVER? " | ||||
|         read | ||||
|     fi | ||||
|     if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||
| 	if [[ ! $autoAnswerYes ]]; then | ||||
| 		echo | ||||
| 		echo -n "Should Windows computers be able to connect to A2SERVER? " | ||||
| 		read | ||||
| 	fi | ||||
| 	if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||
|  | ||||
|         echo "A2SERVER: Setting up Windows file sharing..." | ||||
|         sudo true | ||||
| 		echo "A2SERVER: Setting up Windows file sharing..." | ||||
| 		sudo true | ||||
|  | ||||
|         sudo update-rc.d samba defaults &> /dev/null | ||||
|         [[ ! -f /etc/init.d/samba ]] && installSamba=1 | ||||
| 		sudo update-rc.d samba defaults &> /dev/null | ||||
| 		if [[ ! -f /etc/init.d/samba ]]; then | ||||
| 			installSamba=1 | ||||
| 		fi | ||||
|  | ||||
|         if (( $installSamba )); then | ||||
|             if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
|                 # prepare for installing packages | ||||
|                 sudo apt-get -y update | ||||
|                 touch /tmp/a2server-packageReposUpdated | ||||
|             fi | ||||
| 		if (( $installSamba )); then | ||||
| 			if [[ ! -f /tmp/a2server-packageReposUpdated ]]; then | ||||
| 				# prepare for installing packages | ||||
| 				sudo apt-get -y update | ||||
| 				touch /tmp/a2server-packageReposUpdated | ||||
| 			fi | ||||
|  | ||||
|             # Dependency: samba for Windows/modern Macs | ||||
|             # FIXME: Figure out when smbpasswd moved and adjust this as necessary | ||||
|             sudo apt-get -y install samba | ||||
|             hash smbpasswd &> /dev/null || sudo apt-get -y install samba-common-bin | ||||
|             sudo apt-get clean | ||||
|         fi | ||||
| 			# Dependency: samba for Windows/modern Macs | ||||
| 			# FIXME: Figure out when smbpasswd moved and adjust this as necessary | ||||
| 			sudo apt-get -y install samba | ||||
| 			hash smbpasswd &> /dev/null || sudo apt-get -y install samba-common-bin | ||||
| 			sudo apt-get clean | ||||
| 		fi | ||||
|  | ||||
|         sudo /etc/init.d/samba start &> /dev/null | ||||
| 		sudo /etc/init.d/samba start &> /dev/null | ||||
|  | ||||
|         workgroup=$(grep -o "^   workgroup = .*$" /etc/samba/smb.conf 2> /dev/null | cut -c 16-) | ||||
|         [[ $workgroup ]] || workgroup="WORKGROUP" | ||||
|         if [[ ! $autoAnswerYes ]]; then | ||||
|             echo | ||||
|             echo "Enter workgroup name (or press return for '${workgroup}'): " | ||||
|             read | ||||
|             [[ $REPLY ]] && workgroup=$REPLY | ||||
|         fi | ||||
|         sudo sed -i 's/^   workgroup = .*$/   workgroup = '$workgroup'/' /etc/samba/smb.conf 2> /dev/null | ||||
|         sudo sed -i 's/^#   security = user/   security = user/' /etc/samba/smb.conf 2> /dev/null | ||||
| 		workgroup=$(grep -o "^       workgroup = .*$" /etc/samba/smb.conf 2> /dev/null | cut -c 16-) | ||||
| 		if [[ -z "$workgroup" ]]; then | ||||
| 			workgroup="WORKGROUP" | ||||
| 		fi | ||||
| 		if [[ ! $autoAnswerYes ]]; then | ||||
| 			echo | ||||
| 			echo "Enter workgroup name (or press return for '${workgroup}'): " | ||||
| 			read | ||||
| 			# FIXME validation? | ||||
| 			if [[ $REPLY ]]; then | ||||
| 				workgroup=$REPLY | ||||
| 			fi | ||||
| 		fi | ||||
| 		sudo sed -i 's/^   workgroup = .*$/   workgroup = '$workgroup'/' /etc/samba/smb.conf 2> /dev/null | ||||
| 		sudo sed -i 's/^#   security = user/   security = user/' /etc/samba/smb.conf 2> /dev/null | ||||
|  | ||||
|         # remove GSFILES if no longer serving it | ||||
|         if ! grep ^/srv/A2SERVER/GSFILES /usr/local/etc/netatalk/AppleVolumes.default; then | ||||
|             sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*\[#\n[#' /etc/samba/smb.conf | ||||
|             sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*$#\n#' /etc/samba/smb.conf | ||||
|         fi | ||||
| 		# remove GSFILES if no longer serving it | ||||
| 		if ! grep ^/srv/A2SERVER/GSFILES /usr/local/etc/netatalk/AppleVolumes.default; then | ||||
| 			sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*\[#\n[#' /etc/samba/smb.conf | ||||
| 			sudo sed -i ':a;N;$!ba;s#\n\[GSFILES\].*$#\n#' /etc/samba/smb.conf | ||||
| 		fi | ||||
|  | ||||
|         grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | cut -d" " -f2 \ | ||||
|             | while read sharename; do | ||||
|             if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then | ||||
|                 echo "A2SERVER: $sharename is already set up for Windows file sharing." | ||||
|             else | ||||
|                 echo "[$sharename]" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "    path = /srv/A2SERVER/$sharename" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "    browsable = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "    guest ok = yes" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "    read only = no" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "    create mask = 0666" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "    force user = $USER" | sudo tee -a /etc/samba/smb.conf > /dev/null | ||||
|                 echo "A2SERVER: $sharename has been set up for Windows file sharing." | ||||
|             fi | ||||
|         done | ||||
| 		grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | cut -d" " -f2 \ | ||||
| 			| while read sharename; do | ||||
| 			if [[ $(grep $sharename /etc/samba/smb.conf) ]]; then | ||||
| 				echo "A2SERVER: $sharename is already set up for Windows file sharing." | ||||
| 			else | ||||
| 				sudo tee -a /etc/samba/smb.conf >/dev/null <<EOF | ||||
| [$sharename] | ||||
|     path = /srv/A2SERVER/$sharename | ||||
|     browsable = yes | ||||
|     guest ok = yes | ||||
|     read only = no | ||||
|     create mask = 0666 | ||||
|     force user = $USER | ||||
| EOF | ||||
| 				echo "A2SERVER: $sharename has been set up for Windows file sharing." | ||||
| 			fi | ||||
| 		done | ||||
|  | ||||
|         echo | ||||
|         echo "A2SERVER: Setting Windows file sharing password to 'apple2'." | ||||
|         echo -e 'apple2\napple2' | sudo smbpasswd -s -a $USER | ||||
| 		echo | ||||
| 		echo "A2SERVER: Setting Windows file sharing password to 'apple2'." | ||||
| 		echo -e 'apple2\napple2' | sudo smbpasswd -s -a $USER | ||||
|  | ||||
|         echo | ||||
|         echo "A2SERVER: Windows file sharing is now running." | ||||
|     else | ||||
|         sudo /etc/init.d/samba stop &> /dev/null | ||||
|         sudo update-rc.d -f samba remove &> /dev/null | ||||
|         echo "A2SERVER: Windows file sharing has been turned off." | ||||
|     fi | ||||
| 		echo | ||||
| 		echo "A2SERVER: Windows file sharing is now running." | ||||
| 	else | ||||
| 		sudo /etc/init.d/samba stop &> /dev/null | ||||
| 		sudo update-rc.d -f samba remove &> /dev/null | ||||
| 		echo "A2SERVER: Windows file sharing has been turned off." | ||||
| 	fi | ||||
|  | ||||
|     echo | ||||
| 	echo | ||||
| fi | ||||
|   | ||||
| @@ -1,27 +1,36 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # This script helps when running on the Linux console within a VirtualBox VM. | ||||
|  | ||||
| echo | ||||
|  | ||||
| userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') | ||||
| [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw= | ||||
| [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw= | ||||
| isApple2Pw= | ||||
| if [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]]; then | ||||
| 	isApple2Pw=1 | ||||
| fi | ||||
| isRaspberryPw= | ||||
| if [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]]; then | ||||
| 	isRaspberryPw=1 | ||||
| fi | ||||
|  | ||||
| password="your password" | ||||
| [[ $isApple2Pw ]] && password="'apple2'" | ||||
| [[ $isRaspberryPw ]] && password="'raspberry'" | ||||
|  | ||||
| isDebian= | ||||
| b_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -d . -f 1 < /etc/debian_version) -ge "7" ) ]] && isDebian=1 | ||||
| if [[ "$(lsb_release -ds)" = Debian* ]]; then | ||||
| 	if [[ "$debianVersion" -ge 7 || $debianVersion == [a-z]* ]]; then | ||||
| 		isDebian=1 | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| if [[ $isDebian ]]; then | ||||
|     if { lspci 2> /dev/null | grep -q VirtualBox; }; then | ||||
|         echo "A2SERVER: Disabling VirtualBox console screen blanking..." | ||||
|         sudo sed -i 's/^BLANK_DPMS=off/BLANK_DPMS=on/' /etc/kbd/config | ||||
|         sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config | ||||
|         sudo /etc/init.d/kbd restart &> /dev/null | ||||
|         sudo /etc/init.d/console-setup restart &> /dev/null | ||||
|     fi | ||||
| 	if lspci 2>/dev/null | grep -q VirtualBox; then | ||||
| 		echo "A2SERVER: Disabling VirtualBox console screen blanking..." | ||||
| 		sudo sed -i 's/^BLANK_DPMS=off/BLANK_DPMS=on/' /etc/kbd/config | ||||
| 		sudo sed -i 's/^BLANK_TIME=[^0].$/BLANK_TIME=0/' /etc/kbd/config | ||||
| 		sudo /etc/init.d/kbd restart &> /dev/null | ||||
| 		sudo /etc/init.d/console-setup restart &> /dev/null | ||||
| 	fi | ||||
| fi | ||||
|   | ||||
							
								
								
									
										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 | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
| 
 | ||||
| alias a2server-help="more /usr/local/etc/a2server-help.txt" | ||||
| alias a2server-setup='wget -q -O /tmp/a2server-setup ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}setup/index.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/a2server-setup' | ||||
| 
 | ||||
| 
 | ||||
| alias a2server-version="cat /usr/local/etc/A2SERVER-version" | ||||
| alias a2server-update='wget -q -O /tmp/a2server-update ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}update/index.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/a2server-update' | ||||
| 
 | ||||
| 
 | ||||
| alias system-shutdown='sudo shutdown -h now' | ||||
| alias system-restart='sudo shutdown -r now' | ||||
| 
 | ||||
| 
 | ||||
| alias raspi-config='[[ -f /usr/bin/raspi-config ]] && sudo /usr/bin/raspi-config || echo "raspi-config not found. Are you using a Raspberry Pi with Raspbian?"' | ||||
| alias raspbian-update='wget -qO /tmp/raspbian-update ${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}scripts/raspbian-update.txt || { echo "Can'"'"'t download A2SERVER setup scripts. Do you has internet?"; false; } && source /tmp/raspbian-update' | ||||
| alias rasppleii-update='raspbian-update a2cloud a2server' | ||||
| 
 | ||||
| alias welcome-message-edit='sudo nano /etc/motd' | ||||
| 
 | ||||
| @@ -10,10 +10,7 @@ a2server-update: check for update to A2SERVER | ||||
| system-shutdown: shut down the server | ||||
| system-restart: shut down and restart the server | ||||
|  | ||||
|  Raspberry Pi commands, if you're using one: | ||||
| raspi-config: utilize all space on RPi SD card & other options | ||||
| raspbian-update : update Raspbian operating system | ||||
| rasppleii-update : update Raspbian OS, A2CLOUD, A2SERVER, Apple II Pi | ||||
| debupdate: update the Raspple II operating system | ||||
|  | ||||
| welcome-message-edit: change the welcome message | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								scripts/tools/a2serverrc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								scripts/tools/a2serverrc
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| source /usr/local/etc/a2server-aliases | ||||
| @@ -1,6 +0,0 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
|  | ||||
| export A2SERVER_SCRIPT_URL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current/}" | ||||
| export A2SERVER_BINARY_URL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files/}" | ||||
| source /usr/local/etc/a2server-aliases | ||||
							
								
								
									
										116
									
								
								scripts/tools/afpsync
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										116
									
								
								scripts/tools/afpsync
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # afpsync: updates .AppleDouble components of files on shared volumes | ||||
|  | ||||
| # this must be used if any files are copied to the shared volume via | ||||
| # non-AFP methods (directly, via Samba, etc). | ||||
|  | ||||
| # usage: | ||||
| # afpsync [-v] [shared volume path] | ||||
| # | ||||
| # -v will silently create a .volinfo file if none exists. | ||||
| # If a path is specified, only that volume is synced; otherwise, all | ||||
| # all paths in /srv/A2SERVER which appear in | ||||
| # /usr/local/etc/netatalk/AppleVolumes.default are synced. | ||||
|  | ||||
| processPath () { | ||||
| 	if [[ ! -d $sharepath ]]; then | ||||
| 		echo "$sharepath does not exist." | ||||
| 	else | ||||
| 		volinfo="$sharepath/.AppleDesktop/.volinfo" | ||||
| 		if [[ ! -f $volinfo ]]; then | ||||
| 			if [[ ! $force ]]; then | ||||
| 				echo "Cannot update AppleDouble files for volume $sharepath," | ||||
| 				echo "because its .volinfo file does not exist. To create it, log" | ||||
| 				echo "into the volume from an Apple II or Mac client computer," | ||||
| 				echo "or use \"afpsync -v\"." | ||||
| 			else | ||||
| 				if (( $1 )); then | ||||
| 					mkvolinfo -f -c $sharepath | ||||
| 				else | ||||
| 					mkvolinfo -f $sharepath | ||||
| 				fi | ||||
| 				$0 $sharepath | ||||
| 			fi | ||||
| 		else | ||||
| 			IFS='' | ||||
| 			result=$(sudo dbd -r $sharepath | grep encoding) | ||||
| 			f=$(wc -l <<< $result) | ||||
| 			[[ $(wc -w <<< $result) == 0 ]] && f=0 | ||||
| 			[[ $f -eq 1 && $(grep AppleDesktop <<< "$result") && $(grep MTOULOWER $sharepath/.AppleDesktop/.volinfo) ]] && (( f-- )) | ||||
| 			if (( f == 0 )); then | ||||
| 				echo "AppleDouble files have been updated for volume $sharepath." | ||||
| 			else | ||||
| 				[[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath." | ||||
| 				if [[ $showerrors ]]; then | ||||
| 					echo $result \ | ||||
| 						| while read LINE; do | ||||
| 						[[ ! $(echo $LINE | grep APPLEDESKTOP) ]] && echo $LINE | ||||
| 					done | ||||
| 				elif [[ $renameLower ]]; then | ||||
| 					echo $result \ | ||||
| 						| while read LINE; do | ||||
| 						if [[ ! $(echo $LINE | grep APPLEDESKTOP) ]]; then | ||||
| 							filepath=$(echo $LINE | sed "s/^Bad\ encoding\ for\ '//" | sed s/\'//) | ||||
| 							filename=${filepath##*/} | ||||
| 							filedir=${filepath%/*} | ||||
| 							mv $filepath $filedir/${filename^^} | ||||
| 							echo "Renamed $filedir/${filename^^}." | ||||
| 						fi | ||||
| 					done | ||||
| 					$0 $sharepath | ||||
| 				else | ||||
| 					echo "Use afpsync -e to see error details." | ||||
| 				fi | ||||
| 			fi | ||||
| 			unset IFS | ||||
| 		fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| while [[ $1 == "-r" || $1 == "-e" || $1 = "-v" ]]; do | ||||
|  | ||||
| 	if [[ $1 == "-v" ]]; then | ||||
| 		force=1 | ||||
| 		shift | ||||
| 	fi | ||||
|  | ||||
| 	if [[ $1 == "-e" ]]; then | ||||
| 		showerrors=1 | ||||
| 		shift | ||||
| 	fi | ||||
|  | ||||
| 	if [[ $1 == "-r" ]]; then | ||||
| 		renameLower=1 | ||||
| 		shift | ||||
| 	fi | ||||
|  | ||||
| done | ||||
|  | ||||
| if [[ ${1:0:1} == "-" ]]; then | ||||
| 	echo "Usage: afpsync [-e|-r] [-v] [shared volume path]" | ||||
| 	echo | ||||
| 	echo "-e: show error details" | ||||
| 	echo "-r: rename lowercase filenames to uppercase" | ||||
| 	echo "-v: create .volinfo file if none exists" | ||||
| 	echo "If no directory is specified, all found in" | ||||
| 	echo "  /usr/local/etc/netatalk/AppleVolumes.default are processed." | ||||
| 	echo | ||||
| else | ||||
| 	sudo true | ||||
| 	if [[ $1 ]]; then | ||||
| 		sharepath=$(readlink -m $1) | ||||
| 		# behavior change in 1.3.0: now defaults to mixed case | ||||
| 		#   on a volume when specifying a folder and -v | ||||
| 		#   (as opposed to defaulting to casefold:toupper previously) | ||||
| 		processPath 1 | ||||
| 	else | ||||
| 		grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \ | ||||
| 			while read line; do | ||||
| 			[[ $(echo $line | grep toupper) ]]; nocasefold=$? | ||||
| 			sharepath=$(echo $line | cut -d" " -f1) | ||||
| 			processPath nocasefold | ||||
| 		done | ||||
| 	fi | ||||
| fi | ||||
| @@ -1,116 +0,0 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
|  | ||||
| # afpsync: updates .AppleDouble components of files on shared volumes | ||||
|  | ||||
| # this must be used if any files are copied to the shared volume via | ||||
| # non-AFP methods (directly, via Samba, etc). | ||||
|  | ||||
| # usage: | ||||
| # afpsync [-v] [shared volume path] | ||||
| # | ||||
| # -v will silently create a .volinfo file if none exists. | ||||
| # If a path is specified, only that volume is synced; otherwise, all | ||||
| # all paths in /srv/A2SERVER which appear in | ||||
| # /usr/local/etc/netatalk/AppleVolumes.default are synced. | ||||
|  | ||||
| processPath () { | ||||
|     if [[ ! -d $sharepath ]]; then | ||||
|         echo "$sharepath does not exist." | ||||
|     else | ||||
|         volinfo="$sharepath/.AppleDesktop/.volinfo" | ||||
|         if [[ ! -f $volinfo ]]; then | ||||
|             if [[ ! $force ]]; then | ||||
|                 echo "Cannot update AppleDouble files for volume $sharepath," | ||||
|                 echo "because its .volinfo file does not exist. To create it, log" | ||||
|                 echo "into the volume from an Apple II or Mac client computer," | ||||
|                 echo "or use \"afpsync -v\"." | ||||
|             else | ||||
|                 if (( $1 )); then | ||||
|                     mkvolinfo -f -c $sharepath | ||||
|                 else | ||||
|                     mkvolinfo -f $sharepath | ||||
|                 fi | ||||
|                 $0 $sharepath | ||||
|             fi | ||||
|         else | ||||
|             IFS='' | ||||
|             result=$(sudo dbd -r $sharepath | grep encoding) | ||||
|             f=$(wc -l <<< $result) | ||||
|             [[ $(wc -w <<< $result) == 0 ]] && f=0 | ||||
|             [[ $f -eq 1 && $(grep AppleDesktop <<< "$result") && $(grep MTOULOWER $sharepath/.AppleDesktop/.volinfo) ]] && (( f-- )) | ||||
|             if (( f == 0 )); then | ||||
|                 echo "AppleDouble files have been updated for volume $sharepath." | ||||
|             else | ||||
|                 [[ ! $renameLower ]] && echo "Could not update all files on volume $sharepath." | ||||
|                 if [[ $showerrors ]]; then | ||||
|                     echo $result \ | ||||
|                         | while read LINE; do | ||||
|                         [[ ! $(echo $LINE | grep APPLEDESKTOP) ]] && echo $LINE | ||||
|                     done | ||||
|                 elif [[ $renameLower ]]; then | ||||
|                     echo $result \ | ||||
|                         | while read LINE; do | ||||
|                         if [[ ! $(echo $LINE | grep APPLEDESKTOP) ]]; then | ||||
|                             filepath=$(echo $LINE | sed "s/^Bad\ encoding\ for\ '//" | sed s/\'//) | ||||
|                             filename=${filepath##*/} | ||||
|                             filedir=${filepath%/*} | ||||
|                             mv $filepath $filedir/${filename^^} | ||||
|                             echo "Renamed $filedir/${filename^^}." | ||||
|                         fi | ||||
|                     done | ||||
|                     $0 $sharepath | ||||
|                 else | ||||
|                     echo "Use afpsync -e to see error details." | ||||
|                 fi | ||||
|             fi | ||||
|             unset IFS | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
|  | ||||
| while [[ $1 == "-r" || $1 == "-e" || $1 = "-v" ]]; do | ||||
|  | ||||
|     if [[ $1 == "-v" ]]; then | ||||
|         force=1 | ||||
|         shift | ||||
|     fi | ||||
|  | ||||
|     if [[ $1 == "-e" ]]; then | ||||
|         showerrors=1 | ||||
|         shift | ||||
|     fi | ||||
|  | ||||
|     if [[ $1 == "-r" ]]; then | ||||
|         renameLower=1 | ||||
|         shift | ||||
|     fi | ||||
|  | ||||
| done | ||||
|  | ||||
| if [[ ${1:0:1} == "-" ]]; then | ||||
|     echo "Usage: afpsync [-e|-r] [-v] [shared volume path]" | ||||
|     echo | ||||
|     echo "-e: show error details" | ||||
|     echo "-r: rename lowercase filenames to uppercase" | ||||
|     echo "-v: create .volinfo file if none exists" | ||||
|     echo "If no directory is specified, all found in" | ||||
|     echo "  /usr/local/etc/netatalk/AppleVolumes.default are processed." | ||||
|     echo | ||||
| else | ||||
|     sudo true | ||||
|     if [[ $1 ]]; then | ||||
|         sharepath=$(readlink -m $1) | ||||
|         # behavior change in 1.3.0: now defaults to mixed case | ||||
|         #   on a volume when specifying a folder and -v | ||||
|         #   (as opposed to defaulting to casefold:toupper previously) | ||||
|         processPath 1 | ||||
|     else | ||||
|         grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | \ | ||||
|             while read line; do | ||||
|             [[ $(echo $line | grep toupper) ]]; nocasefold=$? | ||||
|             sharepath=$(echo $line | cut -d" " -f1) | ||||
|             processPath nocasefold | ||||
|         done | ||||
|     fi | ||||
| fi | ||||
							
								
								
									
										498
									
								
								scripts/tools/afptype
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										498
									
								
								scripts/tools/afptype
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,498 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # 2-25-11: tested on 10.6.5 and Ubuntu 10.10. Final. | ||||
|  | ||||
| # to do: allow hex offsets | ||||
|  | ||||
| # These bash functions perform single-byte dec-hex-character conversions | ||||
| # and file read/write operations, and hopefully work identically across | ||||
| # different platforms. Each can operate by itself without the presence | ||||
| # of the others. They have been tested on Mac OS X 10.6 and | ||||
| # Ubuntu Linux 10.10. Your mileage may vary. | ||||
|  | ||||
| # You provide parameters to the functions as arguments, or alternatively | ||||
| # standard in (for the functions which accept characters). Examples: | ||||
| #   Write hex byte with value "F0" to offset 23 in file "myFile": | ||||
| # writecharHex myFile 23 F0 | ||||
| #   Write "ABCDE" to the beginning of file "myFile" | ||||
| # echo "ABCDE" | writechars myFile | ||||
|  | ||||
| # For functions which output something (all but the write operations), | ||||
| # you can call the functions with command substitution if you want to | ||||
| # assign the output to a variable rather than display it. Examples: | ||||
| #   Convert decimal value 65 to its hexadecimal equivalent: | ||||
| # val=$(decToHex 65) | ||||
| #   Get decimal value of the character/byte at offset 215 in "myFile": | ||||
| # val=$(readcharDec "myFile" 215) | ||||
|  | ||||
| # For functions which convert to or from a character, 0-127 will be | ||||
| # ASCII/UTF-8, while 128-255 will be system/locale/codepage dependent. | ||||
| # In this context, a character is effectively the same as a byte. | ||||
|  | ||||
| # The functions return a non-zero exit status for invalid or missing | ||||
| # arguments. If you don't need these checks, remove the lines | ||||
| # above the comment "args are valid" (or as otherwise noted). | ||||
| # The exit statuses are, generally: | ||||
| #    0 = no error | ||||
| #    8 = extraneous argument | ||||
| #    9 = standard input is invalid | ||||
| #   1x = missing required argument (e.g. 11 for missing argument 1) | ||||
| #   2x = argument is invalid (e.g. 22 for invalid argument 2) | ||||
| # any other exit status will originate from the final command in the | ||||
| # function (e.g. dd, printf) | ||||
|  | ||||
| # For the functions which output chars (readchars, decToChar, and | ||||
| # hexToChar), be aware that NUL (0) and trailing LF (10/0x0A) chars will | ||||
| # be stripped when assigned to a variable, and cannot appear in an | ||||
| # argument. To preserve them, pipe the output elsewhere, such as into | ||||
| # charToDec, charToHex, writechars, or a command. (readcharDec and | ||||
| # readcharHex handle these characters correctly.) | ||||
|  | ||||
| # questions/comments to ivan@ivanx.com | ||||
|  | ||||
| decToHex () { | ||||
| # converts single-byte decimal value to hexadecimal equivalent | ||||
| # arg: decimal value from 0-255 | ||||
| # out: two-digit hex value from 00-FF | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $2 ]] && return 8 | ||||
| 	[[ ( $(printf %d "$1" 2> /dev/null) == $1 ) \ | ||||
| 		&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||
| 	# args are valid | ||||
| 	printf %02X "$1" | ||||
| } | ||||
|  | ||||
| hexToDec () { | ||||
| # converts single-byte hexadecimal value to decimal equivalent | ||||
| # arg: two-digit hex value from 00-FF | ||||
| # out: decimal value | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $2 ]] && return 8 | ||||
| 	[[ ${#1} -eq 2 ]] || return 21 | ||||
| 	[[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||
| 		$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 | ||||
| 	# args are valid | ||||
| 	printf %d "0x$1" | ||||
| } | ||||
|  | ||||
| charToDec () { | ||||
| # converts single character to corresponding decimal value | ||||
| # stdin OR arg: one character | ||||
| #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] | ||||
| # out: decimal value from 0-255 | ||||
| #exit: 8=extraneous arg, 9=invalid stdin, | ||||
| #      11=missing stdin/arg, 21=invalid arg | ||||
| 	[[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } | ||||
| 	[[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } | ||||
| 	# arg/stdin is potentially valid (additional check below) | ||||
| 	charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" | ||||
| 	[[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) | ||||
| 	# above line verifies that arg/stdin is valid | ||||
| 	[[ ${#charX} -ne 2 ]] && { echo -n 0; return 0; } | ||||
| 	echo -n "${charX:0:1}" | od -t u1 | \ | ||||
| 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n' | ||||
| } | ||||
|  | ||||
| charToHex () { | ||||
| # converts single character to corresponding hexadecimal value | ||||
| # stdin OR arg: one character | ||||
| #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] | ||||
| # out: decimal value from 0-255 | ||||
| #exit: 8=extraneous arg, 9=invalid stdin, | ||||
| #      11=missing stdin/arg, 21=invalid arg | ||||
| 	[[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } | ||||
| 	[[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } | ||||
| 	# arg/stdin is potentially valid (additional check below) | ||||
| 	charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" | ||||
| 	[[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) | ||||
| 	# above line verifies that stdin/arg is valid | ||||
| 	[[ ${#charX} -ne 2 ]] && { echo -n "00"; return 0; } | ||||
| 	printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ | ||||
| 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | ||||
| } | ||||
|  | ||||
| decToChar () { | ||||
| # converts single-byte decimal value to equivalent character | ||||
| # arg: decimal number from 0-255 | ||||
| # out: one character | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $2 ]] && return 8 | ||||
| 	[[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ | ||||
| 		&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||
| 	# args are valid | ||||
| 	echo -n -e "\x$(printf %02X "$1")" | ||||
| } | ||||
|  | ||||
| hexToChar () { | ||||
| # converts single-byte hexadecimal value to corresponding character | ||||
| # arg: two-digit hexadecimal number from 00-FF | ||||
| # out: one character | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $2 ]] && return 8 | ||||
| 	[[ ${#1} -eq 2 ]] || return 21 | ||||
| 	[[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||
| 		$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 | ||||
| 	# args are valid | ||||
| 	echo -n -e "\x$1" | ||||
| } | ||||
|  | ||||
| readchars () { | ||||
| # read one or more characters from a file | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before reading) | ||||
| # arg3: (optional) # of chars to read (default is until end of file) | ||||
| #  out: sequence of characters | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       21=invalid arg1, 22=invalid arg2, 23=invalid arg3 | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $4 ]] && return 8 | ||||
| 	[[ -f $1 ]] || return 21 | ||||
| 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
| 		&& ( $2 -ge 0 ) ]] || return 22; } | ||||
| 	[[ $3 ]] && { [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ | ||||
| 		&& ( $3 -ge 0 ) ]] || return 23; } | ||||
| 	# args are valid | ||||
| 	dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \ | ||||
| 		2> /dev/null | tr -d ' \0' | ||||
| } | ||||
|  | ||||
| readcharDec () { | ||||
| # read one character from file & convert to equivalent decimal value | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before reading) | ||||
| #  out: decimal value from 0-255 | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       21=invalid arg1, 22=invalid arg2 | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $3 ]] && return 8 | ||||
| 	[[ -f $1 ]] || return 21 | ||||
| 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
| 		&& ( $2 -ge 0 ) ]] || return 22; } | ||||
| 	# args are valid | ||||
| 	charX="$(dd if="$1" bs=1 skip=$(($2)) \ | ||||
| 		count=1 2> /dev/null | tr -d '\0'; echo -n X)" | ||||
| 	[[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; } | ||||
| 	echo -n "${charX:0:1}" | od -t u1 | \ | ||||
| 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n' | ||||
| } | ||||
|  | ||||
| readcharHex () { | ||||
| # read one character from file & convert to corresponding hex value | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before reading) | ||||
| #  out: two-digit hex value from 00-FF | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       21=invalid arg1, 22=invalid arg2 | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $3 ]] && return 8 | ||||
| 	[[ -f $1 ]] || return 21 | ||||
| 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
| 		&& ( $2 -ge 0 ) ]] || return 22; } | ||||
| 	# args are valid | ||||
| 	charX="$(dd if="$1" bs=1 skip=$(($2)) \ | ||||
| 		count=1 2> /dev/null | tr -d '\0'; echo -n X)" | ||||
| 	[[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } | ||||
| 	printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ | ||||
| 		head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | ||||
| } | ||||
|  | ||||
| ### 2-15-11 above tested on OS X and Linux | ||||
|  | ||||
| writechars () { | ||||
| # write one or more characters (bytes) to file | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before writing) | ||||
| # arg3 OR stdin: sequence of characters | ||||
| #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] | ||||
| #  out: nothing | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       13=missing stdin/arg3, 22=invalid arg2 | ||||
| 	[[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } | ||||
| 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ | ||||
| 		( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } | ||||
| 	[[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } | ||||
| 	[[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } | ||||
| 	# args are valid | ||||
| 	if [[ -t 0 ]]; then | ||||
| 		echo -n "$3" | \ | ||||
| 			dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
| 	else | ||||
| 		dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| writecharDec () { | ||||
| # write corresponding character of single-byte decimal value into file | ||||
| # arg1: filename | ||||
| # arg2: offset (# of bytes to skip before writing) | ||||
| # arg3: decimal number from 0-255 | ||||
| # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, | ||||
| #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 | ||||
| #  out: nothing | ||||
| 	[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 | ||||
| 	[[ $4 ]] && return 8 | ||||
| 	[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
| 		&& ( $2 -ge 0 ) ]] || return 22 | ||||
| 	[[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ | ||||
| 		&& ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23 | ||||
| 	# args are valid | ||||
| 	echo -n -e "\x$(printf %02X "$3")" | \ | ||||
| 		dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
| } | ||||
|  | ||||
| writecharHex () { | ||||
| # write corresponding character of single-byte hex value into file | ||||
| # arg1: filename | ||||
| # arg2: offset (# of bytes to skip before writing) | ||||
| # arg3: two-digit hexadecimal number from 00-FF | ||||
| #  out: nothing | ||||
| # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, | ||||
| #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 | ||||
| 	[[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 | ||||
| 	[[ $4 ]] && return 8 | ||||
| 	[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
| 		&& ( $2 -ge 0 ) ]] || return 22 | ||||
| 	[[ $(printf %02X "0x$3" 2> /dev/null) == \ | ||||
| 		$(echo -n "$3" | tr [a-z] [A-Z]) ]] || return 23 | ||||
| 	# args are valid | ||||
| 	echo -n -e "\x$3" | \ | ||||
| 		dd of="$1" bs=1 seek=$2 conv=notrunc 2> /dev/null | ||||
| } | ||||
|  | ||||
|  | ||||
| # --- afptype is below this line | ||||
|  | ||||
| isHexByte () { | ||||
| 	[[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||
| 	$(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 1 | ||||
| } | ||||
|  | ||||
| # support 00 and 0A as filetype chars? | ||||
|  | ||||
| debug=1 | ||||
| ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" | ||||
|  | ||||
| quit () { | ||||
| 	if [[ $2 && $debug ]]; then | ||||
| 		echo "$1" "$2" | ||||
| 	else | ||||
| 		echo -e "Error: $1" | ||||
| 	fi | ||||
| 	exit_usage | ||||
| } | ||||
|  | ||||
| exit_usage () { | ||||
| 	echo "Usage:" | ||||
| 	echo | ||||
| 	echo "show types: afptype filename" | ||||
| 	echo "set Mac OS: afptype [-t 'type'] [-c 'creator'] [-q] filename" | ||||
| 	echo "set ProDOS: afptype [-p type] [-a auxtype] [-q] filename" | ||||
| 	echo "Mac OS type or creator must be four characters; use \x plus" | ||||
| 	echo "  two hex digits for untypeables (note: use '\xZZ' for 00)." | ||||
| 	echo "ProDOS type should be two hex digits, and auxtype should be four;" | ||||
| 	echo "  type can alternatively be BAS, BIN, INT, P16, S16, SHK, SYS, TXT." | ||||
| 	echo "-q skips recheck of file (show types) after setting" | ||||
| 	echo | ||||
| 	exit 1 | ||||
| } | ||||
|  | ||||
| lookupPdosType () { | ||||
| # looks up ProDOS hex type from code in list 'ptypes' | ||||
| # arg: three-character code | ||||
| # out: two-digit hex value | ||||
| #exit: 0=type found, 1=error, 2=type not found | ||||
| 	ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" | ||||
| 	[[ $1 ]] || quit "lookupPdosType:" "no argument supplied ($1)" | ||||
| 	[[ ${#1} -eq 3 ]] || return 1 | ||||
| 	arg=$(echo -n "$1" | tr [a-z] [A-Z]) | ||||
| 	for ptype in $ptypes; do | ||||
| 		if [[ ${ptype:3:3} == $arg ]]; then | ||||
| 			echo -n "${ptype:0:2}" | ||||
| 			return 0 | ||||
| 		fi | ||||
| 	done | ||||
| 	echo "$1" | ||||
| 	return 1 | ||||
| } | ||||
|  | ||||
| verifyTC () { | ||||
| 	[[ $1 ]] || return 1 | ||||
| 	tcX="$(echo -e -n "$1"X)" | ||||
| 	[[ ${#tcX} -eq 5 ]] || return 1 | ||||
| 	echo "$tcX" | ||||
| } | ||||
|  | ||||
| while [[ $1 && ( "${1:0:1}" == '-' ) ]]; do | ||||
| 	if [[ $1 == "-p" ]]; then | ||||
| 		[[ $p ]] && exit_usage | ||||
| 		shift | ||||
| 		p="$1" | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [[ $1 == "-a" ]]; then | ||||
| 		[[ $a ]] && exit_usage | ||||
| 		shift | ||||
| 		a="$1" | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [[ $1 == "-t" ]]; then | ||||
| 		[[ $t ]] && exit_usage | ||||
| 		shift | ||||
| 		t="$1" | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [[ $1 == "-c" ]]; then | ||||
| 		[[ $c ]] && exit_usage | ||||
| 		shift | ||||
| 		c="$1" | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [[ $1 == "-q" ]]; then | ||||
| 		[[ $q ]] && exit_usage | ||||
| 		q=1 | ||||
| 		shift | ||||
| 		continue | ||||
| 	else | ||||
| 		exit_usage | ||||
| 		break | ||||
| 	fi | ||||
| done | ||||
|  | ||||
| if [[ ( ( $p || $a ) && ( $t || $c ) ) || ( -z $1 ) ]]; then | ||||
| 	exit_usage | ||||
| fi | ||||
|  | ||||
| #filename="$1" | ||||
| #shift | ||||
|  | ||||
| for filename in $@; do | ||||
|  | ||||
| 	[[ ${#@} -gt 1 ]] && linestart="($filename) " | ||||
|  | ||||
| 	if [[ ! -f $filename ]]; then | ||||
| 		echo "${linestart}Not found." | ||||
| 		continue | ||||
| 	fi | ||||
|  | ||||
| 	adname="$(dirname "$filename")/.AppleDouble/$(basename "$filename")" | ||||
| 	[[ -f $adname ]] && filename=$adname | ||||
| 	ADversion=$(readcharDec "$filename" 5) | ||||
| 	if [[ ( ( $ADversion -ne 1 ) && ( $ADversion -ne 2 ) ) \ | ||||
| 		|| ( "$(readchars "$filename" 1 3)" != "$(echo -e -n "\x05\x16\x07")" ) \ | ||||
| 		|| ( $(readcharDec "$filename" 0) -ne 0 ) \ | ||||
| 		|| ( $(readcharDec "$filename" 4) -ne 0 ) \ | ||||
| 		|| ( $(readcharDec "$filename" 6) -ne 0 ) \ | ||||
| 		|| ( $(readcharDec "$filename" 7) -ne 0 ) ]]; then | ||||
| 		echo "${linestart}Not an AppleDouble file." | ||||
| 		continue | ||||
| 	fi | ||||
|  | ||||
| 	entrycount=`readcharDec "$filename" 25` | ||||
|  | ||||
| 	entry=1 | ||||
| 	offset=29 | ||||
|  | ||||
| 	while [[ $(readcharDec "$filename" $offset) -ne 9 ]]; do | ||||
| 		(( entry = entry + 1 )) | ||||
| 		if (( entry > entrycount )); then | ||||
| 			echo "${linestart}Finder Info entry not found in AppleDouble file." | ||||
| 			break | ||||
| 		fi | ||||
| 		(( offset = (entry * 12 + 29) - 12 )) | ||||
| 	done | ||||
| 	(( entry > entrycount )) && continue | ||||
|  | ||||
| 	(( offset = offset + 3 )) | ||||
| 	(( tposHi = $(readcharDec "$filename" $offset) * 256 )) | ||||
| 	(( offset = offset + 1 )) | ||||
| 	(( tpos = $(readcharDec "$filename" $offset) + tposHi )) | ||||
| 	(( cpos = tpos + 4 )) | ||||
| 	(( ppos = tpos + 1 )) | ||||
| 	(( apos = tpos + 2 )) | ||||
|  | ||||
| 	if [[ $p || $a || $t || $c ]]; then # set | ||||
| 		if [[ $p || $a ]]; then | ||||
| 			if [[ $p ]]; then | ||||
| 				[[ ${#p} -eq 3 ]] && { p=$(lookupPdosType $p) || quit "Invalid ProDOS type name ($p)."; } | ||||
| 				isHexByte "$p" || quit "Invalid ProDOS file type ($p)." | ||||
| 				writecharHex "$filename" $ppos "$p" | ||||
| 			fi | ||||
| 			if [[ $a ]]; then | ||||
| 				isHexByte "${a:0:2}" && isHexByte "${a:2:2}" || quit "Invalid ProDOS aux type ($a)." | ||||
| 				writecharHex "$filename" $apos "${a:0:2}" | ||||
| 				(( apos=apos+1 )) | ||||
| 				writecharHex "$filename" $apos "${a:2:2}" | ||||
| 			fi | ||||
| 			writechars "$filename" $tpos "p" | ||||
| 			writechars "$filename" $cpos "pdos" | ||||
| 		elif [[ $t || $c ]]; then | ||||
| 			if [[ $t ]]; then | ||||
| 				type=$(verifyTC "$t") || quit "$(echo -n "Invalid Mac file type ($t)."; [[ $t == *x* ]] && echo -n " Try quotes."; echo)" | ||||
| 				writechars "$filename" $tpos "${type:0:4}" | ||||
| 			fi | ||||
| 			if [[ $c ]]; then | ||||
| 				creator=$(verifyTC "$c") || quit "$(echo -n "Invalid Mac file creator ($c)."; [[ $c == *x* ]] && echo -n " Try quotes."; echo)" | ||||
| 				writechars "$filename" $cpos "${creator:0:4}" | ||||
| 			fi | ||||
| 		fi | ||||
| 		[[ $q ]] || { echo -n "${linestart}File changed: "; "$0" "$filename"; } | ||||
|  | ||||
| 	else # show | ||||
| 		[[ $q ]] && quit "Can only use -q when changing type." | ||||
|  | ||||
| 		type="$(readchars "$filename" $tpos 4)" | ||||
| 		creator="$(readchars "$filename" $cpos 4)" | ||||
|  | ||||
| 		echo -n "$linestart" | ||||
|  | ||||
| 		if [[ $creator != "pdos" || ( ( $type != "TEXT" ) \ | ||||
| 			&& ( $type != "PSYS" ) && ( ${type:0:1} != "p" ) ) ]]; then | ||||
| 			if [[ $creator || $type ]]; then | ||||
| 				echo "Mac file.   Type:$type   Creator:$creator" | ||||
| 			else | ||||
| 				echo "This file has no Mac or ProDOS file type information." | ||||
| 			fi | ||||
| 			continue | ||||
| 		fi | ||||
|  | ||||
| 		if [[ $type == "TEXT" ]]; then | ||||
| 			pdosType="\$04 [TXT]" | ||||
| 			pdosAuxType='$0000' | ||||
| 		elif [[ $type == "PSYS" ]]; then | ||||
| 			pdosType="\$FF [SYS]" | ||||
| 			pdosAuxType='$0000' | ||||
| 		else | ||||
| 			(( tpos=tpos+1 )) | ||||
| 			pdosType=$(readcharHex "$filename" $tpos) | ||||
| 			for ptype in $ptypes; do | ||||
| 				if [[ "${ptype:0:2}" == "$pdosType" ]]; then | ||||
| 					pdosType="$pdosType [${ptype:3:3}]" | ||||
| 					break | ||||
| 				fi | ||||
| 			done | ||||
|  | ||||
| 			(( tpos=tpos+1 )) | ||||
| 			auxTypeHi=$(readcharHex "$filename" $tpos) | ||||
| 			(( tpos=tpos+1 )) | ||||
| 			auxTypeLo=$(readcharHex "$filename" $tpos) | ||||
| 			pdosAuxType=$auxTypeHi$auxTypeLo | ||||
| 		fi | ||||
|  | ||||
| 		echo "ProDOS file.  Type:\$$pdosType   AuxType:\$$pdosAuxType" | ||||
| 	fi | ||||
|  | ||||
| done | ||||
|  | ||||
| # 7-19-11 | ||||
| # quick ProDOS testing/fixing on Linux, needs more | ||||
| # Mac Type testing not done yet, nor testing on a Mac | ||||
|  | ||||
| # test on lunix | ||||
| # test inside and outside of AD directory, and from other dirs (both cases) | ||||
| # finish conversion writebyte/readchar library | ||||
| # consider return 2 for missing parameters for subroutines | ||||
| @@ -1,498 +0,0 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
|  | ||||
| # 2-25-11: tested on 10.6.5 and Ubuntu 10.10. Final. | ||||
|  | ||||
| # to do: allow hex offsets | ||||
|  | ||||
| # These bash functions perform single-byte dec-hex-character conversions | ||||
| # and file read/write operations, and hopefully work identically across | ||||
| # different platforms. Each can operate by itself without the presence | ||||
| # of the others. They have been tested on Mac OS X 10.6 and | ||||
| # Ubuntu Linux 10.10. Your mileage may vary. | ||||
|  | ||||
| # You provide parameters to the functions as arguments, or alternatively | ||||
| # standard in (for the functions which accept characters). Examples: | ||||
| #   Write hex byte with value "F0" to offset 23 in file "myFile": | ||||
| # writecharHex myFile 23 F0 | ||||
| #   Write "ABCDE" to the beginning of file "myFile" | ||||
| # echo "ABCDE" | writechars myFile | ||||
|  | ||||
| # For functions which output something (all but the write operations), | ||||
| # you can call the functions with command substitution if you want to | ||||
| # assign the output to a variable rather than display it. Examples: | ||||
| #   Convert decimal value 65 to its hexadecimal equivalent: | ||||
| # val=$(decToHex 65) | ||||
| #   Get decimal value of the character/byte at offset 215 in "myFile": | ||||
| # val=$(readcharDec "myFile" 215) | ||||
|  | ||||
| # For functions which convert to or from a character, 0-127 will be | ||||
| # ASCII/UTF-8, while 128-255 will be system/locale/codepage dependent. | ||||
| # In this context, a character is effectively the same as a byte. | ||||
|  | ||||
| # The functions return a non-zero exit status for invalid or missing | ||||
| # arguments. If you don't need these checks, remove the lines | ||||
| # above the comment "args are valid" (or as otherwise noted). | ||||
| # The exit statuses are, generally: | ||||
| #    0 = no error | ||||
| #    8 = extraneous argument | ||||
| #    9 = standard input is invalid | ||||
| #   1x = missing required argument (e.g. 11 for missing argument 1) | ||||
| #   2x = argument is invalid (e.g. 22 for invalid argument 2) | ||||
| # any other exit status will originate from the final command in the | ||||
| # function (e.g. dd, printf) | ||||
|  | ||||
| # For the functions which output chars (readchars, decToChar, and | ||||
| # hexToChar), be aware that NUL (0) and trailing LF (10/0x0A) chars will | ||||
| # be stripped when assigned to a variable, and cannot appear in an | ||||
| # argument. To preserve them, pipe the output elsewhere, such as into | ||||
| # charToDec, charToHex, writechars, or a command. (readcharDec and | ||||
| # readcharHex handle these characters correctly.) | ||||
|  | ||||
| # questions/comments to ivan@ivanx.com | ||||
|  | ||||
| decToHex () { | ||||
| # converts single-byte decimal value to hexadecimal equivalent | ||||
| # arg: decimal value from 0-255 | ||||
| # out: two-digit hex value from 00-FF | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $2 ]] && return 8 | ||||
|     [[ ( $(printf %d "$1" 2> /dev/null) == $1 ) \ | ||||
|         && ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||
|     # args are valid | ||||
|     printf %02X "$1" | ||||
| } | ||||
|  | ||||
| hexToDec () { | ||||
| # converts single-byte hexadecimal value to decimal equivalent | ||||
| # arg: two-digit hex value from 00-FF | ||||
| # out: decimal value | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $2 ]] && return 8 | ||||
|     [[ ${#1} -eq 2 ]] || return 21 | ||||
|     [[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||
|         $(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 | ||||
|     # args are valid | ||||
|     printf %d "0x$1" | ||||
| } | ||||
|  | ||||
| charToDec () { | ||||
| # converts single character to corresponding decimal value | ||||
| # stdin OR arg: one character | ||||
| #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] | ||||
| # out: decimal value from 0-255 | ||||
| #exit: 8=extraneous arg, 9=invalid stdin, | ||||
| #      11=missing stdin/arg, 21=invalid arg | ||||
|     [[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } | ||||
|     [[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } | ||||
|     # arg/stdin is potentially valid (additional check below) | ||||
|     charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" | ||||
|     [[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) | ||||
|     # above line verifies that arg/stdin is valid | ||||
|     [[ ${#charX} -ne 2 ]] && { echo -n 0; return 0; } | ||||
|     echo -n "${charX:0:1}" | od -t u1 | \ | ||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n' | ||||
| } | ||||
|  | ||||
| charToHex () { | ||||
| # converts single character to corresponding hexadecimal value | ||||
| # stdin OR arg: one character | ||||
| #  [arg overrides stdin; stdin is required for NUL (0) or LF (0x0A)] | ||||
| # out: decimal value from 0-255 | ||||
| #exit: 8=extraneous arg, 9=invalid stdin, | ||||
| #      11=missing stdin/arg, 21=invalid arg | ||||
|     [[ ( ! -t 0 ) && $1 ]] && { cat > /dev/null; return 8; } | ||||
|     [[ ( -t 0 ) ]] && { [[ $2 ]] && return 8; [[ $1 ]] || return 11; } | ||||
|     # arg/stdin is potentially valid (additional check below) | ||||
|     charX="$1X"; [[ $1 ]] || charX="$(cat; echo -n 'X';)" | ||||
|     [[ ${#charX} -le 2 ]] || return $(( $([[ $1 ]]; echo $?) ? 9 : 21 )) | ||||
|     # above line verifies that stdin/arg is valid | ||||
|     [[ ${#charX} -ne 2 ]] && { echo -n "00"; return 0; } | ||||
|     printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ | ||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | ||||
| } | ||||
|  | ||||
| decToChar () { | ||||
| # converts single-byte decimal value to equivalent character | ||||
| # arg: decimal number from 0-255 | ||||
| # out: one character | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $2 ]] && return 8 | ||||
|     [[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ | ||||
|         && ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||
|     # args are valid | ||||
|     echo -n -e "\x$(printf %02X "$1")" | ||||
| } | ||||
|  | ||||
| hexToChar () { | ||||
| # converts single-byte hexadecimal value to corresponding character | ||||
| # arg: two-digit hexadecimal number from 00-FF | ||||
| # out: one character | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $2 ]] && return 8 | ||||
|     [[ ${#1} -eq 2 ]] || return 21 | ||||
|     [[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||
|         $(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 21 | ||||
|     # args are valid | ||||
|     echo -n -e "\x$1" | ||||
| } | ||||
|  | ||||
| readchars () { | ||||
| # read one or more characters from a file | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before reading) | ||||
| # arg3: (optional) # of chars to read (default is until end of file) | ||||
| #  out: sequence of characters | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       21=invalid arg1, 22=invalid arg2, 23=invalid arg3 | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $4 ]] && return 8 | ||||
|     [[ -f $1 ]] || return 21 | ||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
|         && ( $2 -ge 0 ) ]] || return 22; } | ||||
|     [[ $3 ]] && { [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ | ||||
|         && ( $3 -ge 0 ) ]] || return 23; } | ||||
|     # args are valid | ||||
|     dd if="$1" bs=1 skip=$(($2)) $([[ $3 ]] && echo -n "count=$3") \ | ||||
|         2> /dev/null | tr -d ' \0' | ||||
| } | ||||
|  | ||||
| readcharDec () { | ||||
| # read one character from file & convert to equivalent decimal value | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before reading) | ||||
| #  out: decimal value from 0-255 | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       21=invalid arg1, 22=invalid arg2 | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $3 ]] && return 8 | ||||
|     [[ -f $1 ]] || return 21 | ||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
|         && ( $2 -ge 0 ) ]] || return 22; } | ||||
|     # args are valid | ||||
|     charX="$(dd if="$1" bs=1 skip=$(($2)) \ | ||||
|         count=1 2> /dev/null | tr -d '\0'; echo -n X)" | ||||
|     [[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; } | ||||
|     echo -n "${charX:0:1}" | od -t u1 | \ | ||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n' | ||||
| } | ||||
|  | ||||
| readcharHex () { | ||||
| # read one character from file & convert to corresponding hex value | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before reading) | ||||
| #  out: two-digit hex value from 00-FF | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       21=invalid arg1, 22=invalid arg2 | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $3 ]] && return 8 | ||||
|     [[ -f $1 ]] || return 21 | ||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
|         && ( $2 -ge 0 ) ]] || return 22; } | ||||
|     # args are valid | ||||
|     charX="$(dd if="$1" bs=1 skip=$(($2)) \ | ||||
|         count=1 2> /dev/null | tr -d '\0'; echo -n X)" | ||||
|     [[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; } | ||||
|     printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \ | ||||
|         head -1 | sed 's/[0\ ]*//' | tr -d ' \n') | ||||
| } | ||||
|  | ||||
| ### 2-15-11 above tested on OS X and Linux | ||||
|  | ||||
| writechars () { | ||||
| # write one or more characters (bytes) to file | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before writing) | ||||
| # arg3 OR stdin: sequence of characters | ||||
| #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] | ||||
| #  out: nothing | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       13=missing stdin/arg3, 22=invalid arg2 | ||||
|     [[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } | ||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ | ||||
|         ( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } | ||||
|     [[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } | ||||
|     [[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } | ||||
|     # args are valid | ||||
|     if [[ -t 0 ]]; then | ||||
|         echo -n "$3" | \ | ||||
|             dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
|     else | ||||
|         dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
|     fi | ||||
| } | ||||
|  | ||||
| writecharDec () { | ||||
| # write corresponding character of single-byte decimal value into file | ||||
| # arg1: filename | ||||
| # arg2: offset (# of bytes to skip before writing) | ||||
| # arg3: decimal number from 0-255 | ||||
| # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, | ||||
| #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 | ||||
| #  out: nothing | ||||
|     [[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 | ||||
|     [[ $4 ]] && return 8 | ||||
|     [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
|         && ( $2 -ge 0 ) ]] || return 22 | ||||
|     [[ ( $(printf %d "$3" 2> /dev/null) == $3 ) \ | ||||
|         && ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23 | ||||
|     # args are valid | ||||
|     echo -n -e "\x$(printf %02X "$3")" | \ | ||||
|         dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
| } | ||||
|  | ||||
| writecharHex () { | ||||
| # write corresponding character of single-byte hex value into file | ||||
| # arg1: filename | ||||
| # arg2: offset (# of bytes to skip before writing) | ||||
| # arg3: two-digit hexadecimal number from 00-FF | ||||
| #  out: nothing | ||||
| # exit: 8=extraneous arg, 11=missing arg1, 12=missing arg2, | ||||
| #       13=missing arg3, 22=invalid arg2, 23=invalid arg3 | ||||
|     [[ $1 ]] || return 11; [[ $2 ]] || return 12; [[ $3 ]] || return 13 | ||||
|     [[ $4 ]] && return 8 | ||||
|     [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \ | ||||
|         && ( $2 -ge 0 ) ]] || return 22 | ||||
|     [[ $(printf %02X "0x$3" 2> /dev/null) == \ | ||||
|         $(echo -n "$3" | tr [a-z] [A-Z]) ]] || return 23 | ||||
|     # args are valid | ||||
|     echo -n -e "\x$3" | \ | ||||
|         dd of="$1" bs=1 seek=$2 conv=notrunc 2> /dev/null | ||||
| } | ||||
|  | ||||
|  | ||||
| # --- afptype is below this line | ||||
|  | ||||
| isHexByte () { | ||||
|     [[ $(printf %02X "0x$1" 2> /dev/null) == \ | ||||
|     $(echo -n "$1" | tr [a-z] [A-Z]) ]] || return 1 | ||||
| } | ||||
|  | ||||
| # support 00 and 0A as filetype chars? | ||||
|  | ||||
| debug=1 | ||||
| ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" | ||||
|  | ||||
| quit () { | ||||
|     if [[ $2 && $debug ]]; then | ||||
|         echo "$1" "$2" | ||||
|     else | ||||
|         echo -e "Error: $1" | ||||
|     fi | ||||
|     exit_usage | ||||
| } | ||||
|  | ||||
| exit_usage () { | ||||
|     echo "Usage:" | ||||
|     echo | ||||
|     echo "show types: afptype filename" | ||||
|     echo "set Mac OS: afptype [-t 'type'] [-c 'creator'] [-q] filename" | ||||
|     echo "set ProDOS: afptype [-p type] [-a auxtype] [-q] filename" | ||||
|     echo "Mac OS type or creator must be four characters; use \x plus" | ||||
|     echo "  two hex digits for untypeables (note: use '\xZZ' for 00)." | ||||
|     echo "ProDOS type should be two hex digits, and auxtype should be four;" | ||||
|     echo "  type can alternatively be BAS, BIN, INT, P16, S16, SHK, SYS, TXT." | ||||
|     echo "-q skips recheck of file (show types) after setting" | ||||
|     echo | ||||
|     exit 1 | ||||
| } | ||||
|  | ||||
| lookupPdosType () { | ||||
| # looks up ProDOS hex type from code in list 'ptypes' | ||||
| # arg: three-character code | ||||
| # out: two-digit hex value | ||||
| #exit: 0=type found, 1=error, 2=type not found | ||||
|     ptypes="04:TXT 06:BIN B3:S16 E0:SHK F9:P16 FA:INT FC:BAS FF:SYS" | ||||
|     [[ $1 ]] || quit "lookupPdosType:" "no argument supplied ($1)" | ||||
|     [[ ${#1} -eq 3 ]] || return 1 | ||||
|     arg=$(echo -n "$1" | tr [a-z] [A-Z]) | ||||
|     for ptype in $ptypes; do | ||||
|         if [[ ${ptype:3:3} == $arg ]]; then | ||||
|             echo -n "${ptype:0:2}" | ||||
|             return 0 | ||||
|         fi | ||||
|     done | ||||
|     echo "$1" | ||||
|     return 1 | ||||
| } | ||||
|  | ||||
| verifyTC () { | ||||
|     [[ $1 ]] || return 1 | ||||
|     tcX="$(echo -e -n "$1"X)" | ||||
|     [[ ${#tcX} -eq 5 ]] || return 1 | ||||
|     echo "$tcX" | ||||
| } | ||||
|  | ||||
| while [[ $1 && ( "${1:0:1}" == '-' ) ]]; do | ||||
|     if [[ $1 == "-p" ]]; then | ||||
|         [[ $p ]] && exit_usage | ||||
|         shift | ||||
|         p="$1" | ||||
|         shift | ||||
|         continue | ||||
|     elif [[ $1 == "-a" ]]; then | ||||
|         [[ $a ]] && exit_usage | ||||
|         shift | ||||
|         a="$1" | ||||
|         shift | ||||
|         continue | ||||
|     elif [[ $1 == "-t" ]]; then | ||||
|         [[ $t ]] && exit_usage | ||||
|         shift | ||||
|         t="$1" | ||||
|         shift | ||||
|         continue | ||||
|     elif [[ $1 == "-c" ]]; then | ||||
|         [[ $c ]] && exit_usage | ||||
|         shift | ||||
|         c="$1" | ||||
|         shift | ||||
|         continue | ||||
|     elif [[ $1 == "-q" ]]; then | ||||
|         [[ $q ]] && exit_usage | ||||
|         q=1 | ||||
|         shift | ||||
|         continue | ||||
|     else | ||||
|         exit_usage | ||||
|         break | ||||
|     fi | ||||
| done | ||||
|  | ||||
| if [[ ( ( $p || $a ) && ( $t || $c ) ) || ( -z $1 ) ]]; then | ||||
|     exit_usage | ||||
| fi | ||||
|  | ||||
| #filename="$1" | ||||
| #shift | ||||
|  | ||||
| for filename in $@; do | ||||
|  | ||||
|     [[ ${#@} -gt 1 ]] && linestart="($filename) " | ||||
|  | ||||
|     if [[ ! -f $filename ]]; then | ||||
|         echo "${linestart}Not found." | ||||
|         continue | ||||
|     fi | ||||
|  | ||||
|     adname="$(dirname "$filename")/.AppleDouble/$(basename "$filename")" | ||||
|     [[ -f $adname ]] && filename=$adname | ||||
|     ADversion=$(readcharDec "$filename" 5) | ||||
|     if [[ ( ( $ADversion -ne 1 ) && ( $ADversion -ne 2 ) ) \ | ||||
|         || ( "$(readchars "$filename" 1 3)" != "$(echo -e -n "\x05\x16\x07")" ) \ | ||||
|         || ( $(readcharDec "$filename" 0) -ne 0 ) \ | ||||
|         || ( $(readcharDec "$filename" 4) -ne 0 ) \ | ||||
|         || ( $(readcharDec "$filename" 6) -ne 0 ) \ | ||||
|         || ( $(readcharDec "$filename" 7) -ne 0 ) ]]; then | ||||
|         echo "${linestart}Not an AppleDouble file." | ||||
|         continue | ||||
|     fi | ||||
|  | ||||
|     entrycount=`readcharDec "$filename" 25` | ||||
|  | ||||
|     entry=1 | ||||
|     offset=29 | ||||
|  | ||||
|     while [[ $(readcharDec "$filename" $offset) -ne 9 ]]; do | ||||
|         (( entry = entry + 1 )) | ||||
|         if (( entry > entrycount )); then | ||||
|             echo "${linestart}Finder Info entry not found in AppleDouble file." | ||||
|             break | ||||
|         fi | ||||
|         (( offset = (entry * 12 + 29) - 12 )) | ||||
|     done | ||||
|     (( entry > entrycount )) && continue | ||||
|  | ||||
|     (( offset = offset + 3 )) | ||||
|     (( tposHi = $(readcharDec "$filename" $offset) * 256 )) | ||||
|     (( offset = offset + 1 )) | ||||
|     (( tpos = $(readcharDec "$filename" $offset) + tposHi )) | ||||
|     (( cpos = tpos + 4 )) | ||||
|     (( ppos = tpos + 1 )) | ||||
|     (( apos = tpos + 2 )) | ||||
|  | ||||
|     if [[ $p || $a || $t || $c ]]; then # set | ||||
|         if [[ $p || $a ]]; then | ||||
|             if [[ $p ]]; then | ||||
|                 [[ ${#p} -eq 3 ]] && { p=$(lookupPdosType $p) || quit "Invalid ProDOS type name ($p)."; } | ||||
|                 isHexByte "$p" || quit "Invalid ProDOS file type ($p)." | ||||
|                 writecharHex "$filename" $ppos "$p" | ||||
|             fi | ||||
|             if [[ $a ]]; then | ||||
|                 isHexByte "${a:0:2}" && isHexByte "${a:2:2}" || quit "Invalid ProDOS aux type ($a)." | ||||
|                 writecharHex "$filename" $apos "${a:0:2}" | ||||
|                 (( apos=apos+1 )) | ||||
|                 writecharHex "$filename" $apos "${a:2:2}" | ||||
|             fi | ||||
|             writechars "$filename" $tpos "p" | ||||
|             writechars "$filename" $cpos "pdos" | ||||
|         elif [[ $t || $c ]]; then | ||||
|             if [[ $t ]]; then | ||||
|                 type=$(verifyTC "$t") || quit "$(echo -n "Invalid Mac file type ($t)."; [[ $t == *x* ]] && echo -n " Try quotes."; echo)" | ||||
|                 writechars "$filename" $tpos "${type:0:4}" | ||||
|             fi | ||||
|             if [[ $c ]]; then | ||||
|                 creator=$(verifyTC "$c") || quit "$(echo -n "Invalid Mac file creator ($c)."; [[ $c == *x* ]] && echo -n " Try quotes."; echo)" | ||||
|                 writechars "$filename" $cpos "${creator:0:4}" | ||||
|             fi | ||||
|         fi | ||||
|         [[ $q ]] || { echo -n "${linestart}File changed: "; "$0" "$filename"; } | ||||
|  | ||||
|     else # show | ||||
|         [[ $q ]] && quit "Can only use -q when changing type." | ||||
|  | ||||
|         type="$(readchars "$filename" $tpos 4)" | ||||
|         creator="$(readchars "$filename" $cpos 4)" | ||||
|  | ||||
|         echo -n "$linestart" | ||||
|  | ||||
|         if [[ $creator != "pdos" || ( ( $type != "TEXT" ) \ | ||||
|             && ( $type != "PSYS" ) && ( ${type:0:1} != "p" ) ) ]]; then | ||||
|             if [[ $creator || $type ]]; then | ||||
|                 echo "Mac file.   Type:$type   Creator:$creator" | ||||
|             else | ||||
|                 echo "This file has no Mac or ProDOS file type information." | ||||
|             fi | ||||
|             continue | ||||
|         fi | ||||
|  | ||||
|         if [[ $type == "TEXT" ]]; then | ||||
|             pdosType="\$04 [TXT]" | ||||
|             pdosAuxType='$0000' | ||||
|         elif [[ $type == "PSYS" ]]; then | ||||
|             pdosType="\$FF [SYS]" | ||||
|             pdosAuxType='$0000' | ||||
|         else | ||||
|             (( tpos=tpos+1 )) | ||||
|             pdosType=$(readcharHex "$filename" $tpos) | ||||
|             for ptype in $ptypes; do | ||||
|                 if [[ "${ptype:0:2}" == "$pdosType" ]]; then | ||||
|                     pdosType="$pdosType [${ptype:3:3}]" | ||||
|                     break | ||||
|                 fi | ||||
|             done | ||||
|  | ||||
|             (( tpos=tpos+1 )) | ||||
|             auxTypeHi=$(readcharHex "$filename" $tpos) | ||||
|             (( tpos=tpos+1 )) | ||||
|             auxTypeLo=$(readcharHex "$filename" $tpos) | ||||
|             pdosAuxType=$auxTypeHi$auxTypeLo | ||||
|         fi | ||||
|  | ||||
|         echo "ProDOS file.  Type:\$$pdosType   AuxType:\$$pdosAuxType" | ||||
|     fi | ||||
|  | ||||
| done | ||||
|  | ||||
| # 7-19-11 | ||||
| # quick ProDOS testing/fixing on Linux, needs more | ||||
| # Mac Type testing not done yet, nor testing on a Mac | ||||
|  | ||||
| # test on lunix | ||||
| # test inside and outside of AD directory, and from other dirs (both cases) | ||||
| # finish conversion writebyte/readchar library | ||||
| # consider return 2 for missing parameters for subroutines | ||||
							
								
								
									
										1417
									
								
								scripts/tools/cppo
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1417
									
								
								scripts/tools/cppo
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										165
									
								
								scripts/tools/debupdate
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										165
									
								
								scripts/tools/debupdate
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| #!/bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # debupdate - Upgrades packages on a Debian-based system | ||||
| # Written in 2016 by T. Joseph Carter <tjcarter@spiritsubstance.com> | ||||
| # Based on raspbian-update by Ivan Drucker <ivan@ivanx.com> | ||||
| # | ||||
| # To the extent possible under law, the author(s) have dedicated all copyright | ||||
| # and related and neighboring rights to this software to the public domain | ||||
| # worldwide. This software is distributed without any warranty. | ||||
| # | ||||
| # You should have received a copy of the CC0 Public Domain Dedication along | ||||
| # with this software. If not, you may find a copy here: | ||||
| #  <http://creativecommons.org/publicdomain/zero/1.0/> | ||||
|  | ||||
| PROGNAME="$0" | ||||
| PROGRAM="debupdate" | ||||
| VERSION="0.9.0" | ||||
|  | ||||
| useAptGet= | ||||
| useAutoClean= | ||||
| autoYes= | ||||
|  | ||||
| aptitudeUpgradeArgs="--allow-new-upgrades --allow-new-installs safe-upgrade" | ||||
| aptGetUpgradeArgs="--with-new-pkgs --auto-remove upgrade" | ||||
|  | ||||
| ShowLicense() { | ||||
| 	printf "%s version %s | ||||
| Upgrades packages on a Debian-based system | ||||
|  | ||||
| Written in 2016 by T. Joseph Carter <tjcarter@spiritsubstance.com> | ||||
| Based on raspbian-update by Ivan Drucker <ivan@ivanx.com> | ||||
|  | ||||
| To the extent possible under law, the author(s) have dedicated all copyright | ||||
| and related and neighboring rights to this software to the public domain | ||||
| worldwide. This software is distributed without any warranty. | ||||
|  | ||||
| You should have received a copy of the CC0 Public Domain Dedication along | ||||
| with this software. If not, you may find a copy here: | ||||
|  <http://creativecommons.org/publicdomain/zero/1.0/> | ||||
| " $PROGRAM $VERSION | ||||
| 	exit 0 | ||||
| } | ||||
|  | ||||
| Run() { | ||||
| 	local cmd=( ) | ||||
| 	for i in "${@}"; do | ||||
| 		# Replace argument's spaces with ''; if different, quote the string | ||||
| 		if [ "$i" != "${i/ /}" ]; then | ||||
| 			cmd=( ${cmd[@]} "'${i}'" ) | ||||
| 		else | ||||
| 			cmd=( ${cmd[@]} $i ) | ||||
| 		fi | ||||
| 	done | ||||
| 	printf ">>> %s\n" "${cmd[@]}" | ||||
| 	${@} | ||||
| } | ||||
|  | ||||
|  | ||||
| ShowHelp() { | ||||
| 	# FIXME | ||||
| 	printf "\nHelp\n" | ||||
|  | ||||
| 	exit ${1:-0} | ||||
| } | ||||
|  | ||||
|  | ||||
| # Process command line arguments | ||||
| while getopts ":hvyacy" opt; do | ||||
| 	case "$opt" in | ||||
| 		h)	ShowHelp ;; | ||||
| 		v)	ShowLicense ;; | ||||
| 		y)	autoYes=1 ;; | ||||
| 		a)	useAptGet=1 ;; | ||||
| 		c)	useAutoClean=1 ;; | ||||
| 		\?) | ||||
| 			printf "Invalid argument: -%s\n" "$OPTARG" | ||||
| 			badArgument=1 | ||||
| 			;; | ||||
| 	esac | ||||
| done | ||||
| if [[ "$badArgument" ]]; then | ||||
| 	ShowHelp 1 | ||||
| fi | ||||
|  | ||||
| # Check for root access | ||||
| if [[ "$UID" != "0" ]]; then | ||||
| 	if hash sudo 2>/dev/null; then | ||||
| 		Run sudo $0 "$@" | ||||
| 		exit $? | ||||
| 	else | ||||
| 		printf "%s requires \"root\" administrator access to upgrade your system.\n" "$PROGRAM" | ||||
| 		exit 1 | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # Determine if aptitude is installed (unless we're not using it) | ||||
| if [[ -z "$useAptGet" ]]; then | ||||
| 	if ! hash aptitude 2>/dev/null; then | ||||
| 		useAptGet=1 | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # Clean apt package cache | ||||
| printf "\nCleaning apt package cache...\n" | ||||
| if [[ $useAptGet ]]; then | ||||
| 	Run apt-get ${useAutoClean:+auto}clean | ||||
| else | ||||
| 	Run aptitude ${useAutoClean:+auto}clean | ||||
| fi | ||||
|  | ||||
| # Update package lists | ||||
| printf "\nUpdating list of available packages...\n" | ||||
| if [[ $useAptGet ]]; then | ||||
| 	Run apt-get update | ||||
| else | ||||
| 	Run aptitude update | ||||
| fi | ||||
| if [[ $? -ne 0 ]]; | ||||
| 	printf "Package list update failed.\n" | ||||
| 	exit 1 | ||||
| fi | ||||
|  | ||||
| # Check to see if we even need to upgrade | ||||
| if [[ $useAptGet ]]; then | ||||
| 	apt-get --trivial-only $aptGetUpgradeArgs &>/dev/null | ||||
| else | ||||
| 	aptitude $aptitudeUpgradeArgs <<<"n" &>/dev/null | ||||
| fi | ||||
| if [[ $? -eq 0 ]]; then | ||||
| 	printf "Your packages are already up to date.\n" | ||||
| 	exit 0 | ||||
| fi | ||||
|  | ||||
| # Do the upgrade itself | ||||
| if [[ $useAptGet ]]; then | ||||
| 	Run apt-get ${autoYes:+-y} $aptGetUpgradeArgs | ||||
| else | ||||
| 	Run aptitude ${autoYes:+-y} $aptitudeUpgradeArgs | ||||
| fi | ||||
| if [[ $? -ne 0 ]]; then | ||||
| 	# FIXME | ||||
| 	printf "System upgrade failed.  Something about a log should be here.\n" | ||||
| 	exit 1 | ||||
| fi | ||||
|  | ||||
| # apt-get needs explicit autoremove (aptitude doesn't) | ||||
| if [[ $useAptGet ]]; then | ||||
| 	Run apt-get autoremove | ||||
| 	if [[ $? -ne 0 ]]; then | ||||
| 		printf "Failure attempting to auto-remove unneeded packages.\n" | ||||
| 		exit 1 | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # Clean apt package cache (again) | ||||
| printf "Cleaning apt package cache...\n" | ||||
| if [[ $useAptGet ]]; then | ||||
| 	Run apt-get autoclean | ||||
| else | ||||
| 	Run aptitude autoclean | ||||
| fi | ||||
|  | ||||
| printf "\nIt is generally recommended that you reboot your system after upgrades.  You | ||||
| can do this with the \"reboot\" command, which must be run as root.\n\n" | ||||
							
								
								
									
										286
									
								
								scripts/tools/mkatinit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										286
									
								
								scripts/tools/mkatinit
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,286 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # mkatinit by Ivan Drucker, http://appleii.ivanx.com | ||||
| # not licensed; please modify and redistribute as you like | ||||
| # 1.0b4 1-30-11 | ||||
|  | ||||
| # 1.1d1 -- uses bashByter. NOT TESTED. | ||||
|  | ||||
| # This script creates the ATINIT file required for netbooting Apple IIe and | ||||
| #   IIGS clients from a netatalk server. ATINIT is put in the in the | ||||
| #   (sharename)/USERS hierarchy, or the current directory if it can't. | ||||
| #   The user can specify the ProDOS startup system program and default prefix. | ||||
| #   If an argument is supplied, it is used as the username and the prompt is | ||||
| #   skipped. | ||||
|  | ||||
| # The ATINIT file is not as complete as the ones generated by AppleShare 3.0, | ||||
| #   and features such as default printer are not used. | ||||
|  | ||||
| # to do | ||||
| # possibly require confirmation if AFPD_GUEST is not set correctly | ||||
| #  or offer to change it | ||||
|  | ||||
| # from ID-bashByter library | ||||
| decToChar () { | ||||
| # converts single-byte decimal value to equivalent character | ||||
| # arg: decimal number from 0-255 | ||||
| # out: one character | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
| 	[[ $1 ]] || return 11 | ||||
| 	[[ $2 ]] && return 8 | ||||
| 	[[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ | ||||
| 		&& ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||
| 	# args are valid | ||||
| 	echo -n -e "\x$(printf %02X "$1")" | ||||
| } | ||||
|  | ||||
| writechars () { | ||||
| # write one or more characters (bytes) to file | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before writing) | ||||
| # arg3 OR stdin: sequence of characters | ||||
| #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] | ||||
| #  out: nothing | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       13=missing stdin/arg3, 22=invalid arg2 | ||||
| 	[[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } | ||||
| 	[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ | ||||
| 		( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } | ||||
| 	[[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } | ||||
| 	[[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } | ||||
| 	# args are valid | ||||
| 	if [[ -t 0 ]]; then | ||||
| 		echo -n "$3" | \ | ||||
| 			dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
| 	else | ||||
| 		dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| #---- mkatinit starts here | ||||
| IFS='' | ||||
|  | ||||
| #defaults | ||||
| sharepath=$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) | ||||
| prefix=/$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f2) | ||||
| gsprefix=$prefix | ||||
| startprog="$prefix/BASIC.SYSTEM" | ||||
| gsstartprog="$prefix/SYSTEM/FINDER" | ||||
| filename="ATINIT" | ||||
| user=$(whoami) | ||||
|  | ||||
| echo | ||||
|  | ||||
| usersfolder=1 | ||||
| while [ -n "$1" ] && [ "${1:0:1}" = '-' ]; do | ||||
| 	flag="$1" | ||||
| 	if [ $flag = "-gs" ]; then | ||||
| 		gs=1 | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [ $flag = "-d" ]; then | ||||
| 		noprompt=1 | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [ $flag = "-f" ]; then | ||||
| 		overwrite=1 | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [ $flag = "-g" ]; then | ||||
| 		alsoguest=1 | ||||
| 		shift | ||||
| 		continue | ||||
| 	elif [ $flag = "-c" ]; then | ||||
| 		usersfolder=0 | ||||
| 		shift | ||||
| 		continue | ||||
| 	else | ||||
| 		badflag=1 | ||||
| 		break | ||||
| 	fi | ||||
| done | ||||
|  | ||||
| if [ $usersfolder -eq 0 ] && [ -n "$alsoguest" ]; then | ||||
| 	badflag=1 | ||||
| fi | ||||
|  | ||||
| if [ $badflag ]; then | ||||
| 	echo "usage: mkatinit [-gs] [-d] [-f] [-g | -c] [<username>|guest]" | ||||
| 	echo | ||||
| 	echo "<username> should be the name of a netatalk user, or 'guest'" | ||||
| 	echo "-gs sets the default ProDOS netboot system startup program and" | ||||
| 	echo "    prefix for GS/OS (if omitted, ProDOS 8 defaults are used)" | ||||
| 	echo "-d  use the default start program and prefix, without prompting" | ||||
| 	echo "-f  overwrite existing ATINIT file if present, without warning" | ||||
| 	echo "-g  create an ATINIT file for Guest as well as the specified user" | ||||
| 	echo "-c  write ATNIT to current directory instead of USERS hierarchy" | ||||
| 	echo | ||||
| 	exit | ||||
| fi | ||||
|  | ||||
| arg="$1" | ||||
|  | ||||
| [[ -z $arg ]] && arg=$user | ||||
|  | ||||
| while : ; do | ||||
|  | ||||
| 	if [ ${#arg} -gt 32 ]; then | ||||
| 		echo "User name is too long. Exiting with no action." | ||||
| 		exit | ||||
| 	elif [ -n "$arg" ]; then | ||||
| 		if [ `echo $arg | tr '[:upper:]' '[:lower:]'` = "guest" ]; then | ||||
| 			username='<Any User>' | ||||
| 			alsoguest= | ||||
| 			if [[ ! $(grep -F -s $(ls -1 /home) /etc/default/netatalk) ]]; then | ||||
| 				echo 'Warning: The AFPD_GUEST setting in /etc/default/netatalk is not assigned to a' | ||||
| 				echo 'user with a folder in /home. Guest users may be able to boot over the network' | ||||
| 				echo 'into ProDOS 8 for read-only access, but will not be able to boot into GS/OS.' | ||||
| 				if [ $gs ]; then | ||||
| 					echo ' Using ProDOS 8 defaults.' | ||||
| 					gs= | ||||
| 				else | ||||
| 					echo | ||||
| 				fi | ||||
| 				echo | ||||
| 			fi | ||||
| 		else | ||||
| 			username="$arg" | ||||
| 			if [[ ! $(ls -1 /home | grep -F -s $username) ]]; then | ||||
| 				echo "Warning: This username ($username) does not have a folder in /home. This user may" | ||||
| 				echo "not be able to boot over the network into ProDOS 8 or GS/OS." | ||||
| 				echo | ||||
| 			fi | ||||
| 		fi | ||||
| 		if [ $gs ]; then | ||||
| 			startprog="$gsstartprog" | ||||
| 			prefix="$gsprefix" | ||||
| 		fi | ||||
| 	fi | ||||
|  | ||||
| 	# make username all caps | ||||
| 	username=`echo $username | tr '[:lower:]' '[:upper:]'` | ||||
|  | ||||
| 	# prompt for folders | ||||
| 	if [ ! $doalsoguest ] && [ ! $noprompt ]; then | ||||
| 		while : ; do | ||||
| 			echo "Enter the ProDOS path to the startup system program." | ||||
| 			echo "default (CR to accept): $startprog" | ||||
| 			read | ||||
| 			if [ ${#REPLY} -gt 64 ]; then | ||||
| 				continue | ||||
| 			elif [ -n "$REPLY" ]; then | ||||
| 				startprog="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" | ||||
| 				echo | ||||
| 			fi | ||||
| 			break | ||||
| 		done | ||||
|  | ||||
| 		while : ; do | ||||
| 			echo "Enter the initial ProDOS prefix:" | ||||
| 			echo "default (CR to accept): $prefix" | ||||
| 			read | ||||
| 			if [ ${#REPLY} -gt 64 ]; then | ||||
| 				continue | ||||
| 			elif [ -n "$REPLY" ]; then | ||||
| 				prefix="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" | ||||
| 				echo | ||||
| 			fi | ||||
| 			break | ||||
| 		done | ||||
| 	fi | ||||
|  | ||||
| 	# create folders if needed | ||||
| 	filepath="$PWD/$filename" | ||||
|  | ||||
| 	while [ $usersfolder -eq 1 ]; do | ||||
| 		# create folders for ATINIT | ||||
| 		while [ ! -d "$sharepath" ]; do | ||||
| 			echo "Shared volume '$sharepath' not found. Edit mkatinit to change the default." | ||||
| 			echo "Enter the local path to the netatalk shared volume used for netboot:" | ||||
| 			read sharepath | ||||
| 		done | ||||
|  | ||||
| 		if [ ! -d "$sharepath/USERS" ]; then | ||||
| 			mkdir "$sharepath/USERS" | ||||
| 			if [ $? -ne 0 ]; then | ||||
| 				break | ||||
| 			fi | ||||
| 		fi | ||||
| 		if [ ! -d "$sharepath/USERS/$username" ]; then | ||||
| 			mkdir "$sharepath/USERS/$username" | ||||
| 			if [ $? -ne 0 ]; then | ||||
| 				break | ||||
| 			fi | ||||
| 		fi | ||||
| 		if [ ! -d "$sharepath/USERS/$username/SETUP" ]; then | ||||
| 			mkdir "$sharepath/USERS/$username/SETUP" | ||||
| 			if [ $? -ne 0 ]; then | ||||
| 				break | ||||
| 			fi | ||||
| 		else | ||||
| 			if [ ! -w "$sharepath/USERS/$username/SETUP" ]; then | ||||
| 				break | ||||
| 			fi | ||||
| 		fi | ||||
|  | ||||
| 		# we have a valid USERS folder target for ATINIT | ||||
| 		filepath="$sharepath/USERS/$username/SETUP/$filename" | ||||
| 		usersfolder=2 | ||||
| 	done | ||||
|  | ||||
| 	if [ $usersfolder -eq 1 ]; then | ||||
| 		echo "Could not write to shared volume. Creating ATINIT in current directory." | ||||
| 		if [ -n "$alsoguest" ]; then | ||||
| 			echo "ATINIT for Guest user will not be created." | ||||
| 		fi | ||||
| 		echo | ||||
| 		alsoguest= | ||||
| 	fi | ||||
|  | ||||
| 	if [ ! $doalsoguest ]; then | ||||
| 		echo "netboot start program: $startprog" | ||||
| 		echo "netboot start prefix : $prefix" | ||||
| 		echo | ||||
| 	fi | ||||
|  | ||||
| 	#remove ATINIT if present | ||||
| 	if [ ! $overwrite ] && [ -f "$filepath" ]; then | ||||
| 		echo -n "$filepath already exists. Overwrite? " | ||||
| 		while read -s -n 1 > /dev/null 2>&1; do | ||||
| 			if [ -z "$REPLY" ]; then | ||||
| 				continue | ||||
| 			elif [ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ]; then | ||||
| 				echo | ||||
| 				break | ||||
| 			elif [ "$REPLY" = "N" ] || [ "$REPLY" = "n" ]; then | ||||
| 				echo | ||||
| 				echo "Exiting with no action." | ||||
| 				exit | ||||
| 			fi | ||||
| 		done | ||||
| 	fi | ||||
|  | ||||
| 	#write the file. start with zeroes | ||||
| 	dd if=/dev/zero of="$filepath" bs=1 count=276 2> /dev/null | ||||
| 	#put in startprog, prefix, username (first byte of each field is length) | ||||
| 	# ( echo -n "${#startprog}" | awk '{printf("%c",$0);}'; echo -n "$startprog"; ) | dd of="$filepath" bs=1 seek=7 conv=notrunc 2> /dev/null | ||||
| 	# ( echo -n "${#prefix}" | awk '{printf("%c",$0);}'; echo -n "$prefix"; ) | dd of="$filepath" bs=1 seek=78 conv=notrunc 2> /dev/null | ||||
| 	# ( echo -n "${#username}" | awk '{printf("%c",$0);}'; echo -n "$username"; ) | dd of="$filepath" bs=1 seek=143 conv=notrunc 2> /dev/null | ||||
| 	( decToChar "${#startprog}"; echo -n "$startprog"; ) | writechars "$filepath" 7 | ||||
| 	( decToChar "${#prefix}"; echo -n "$prefix"; ) | writechars "$filepath" 78 | ||||
| 	( decToChar "${#username}"; echo -n "$username"; ) | writechars "$filepath" 143 | ||||
|  | ||||
| 	echo "Created $filepath" | ||||
| 	if [ ! $alsoguest ]; then | ||||
| 		break | ||||
| 	fi | ||||
|  | ||||
| 	if [ $usersfolder -eq 2 ]; then | ||||
| 		usersfolder=1 | ||||
| 	fi | ||||
| 	doalsoguest=1 | ||||
| 	arg='guest' | ||||
| done | ||||
|  | ||||
| echo | ||||
| @@ -1,286 +0,0 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
|  | ||||
| # mkatinit by Ivan Drucker, http://appleii.ivanx.com | ||||
| # not licensed; please modify and redistribute as you like | ||||
| # 1.0b4 1-30-11 | ||||
|  | ||||
| # 1.1d1 -- uses bashByter. NOT TESTED. | ||||
|  | ||||
| # This script creates the ATINIT file required for netbooting Apple IIe and | ||||
| #   IIGS clients from a netatalk server. ATINIT is put in the in the | ||||
| #   (sharename)/USERS hierarchy, or the current directory if it can't. | ||||
| #   The user can specify the ProDOS startup system program and default prefix. | ||||
| #   If an argument is supplied, it is used as the username and the prompt is | ||||
| #   skipped. | ||||
|  | ||||
| # The ATINIT file is not as complete as the ones generated by AppleShare 3.0, | ||||
| #   and features such as default printer are not used. | ||||
|  | ||||
| # to do | ||||
| # possibly require confirmation if AFPD_GUEST is not set correctly | ||||
| #  or offer to change it | ||||
|  | ||||
| # from ID-bashByter library | ||||
| decToChar () { | ||||
| # converts single-byte decimal value to equivalent character | ||||
| # arg: decimal number from 0-255 | ||||
| # out: one character | ||||
| #exit: 8=extraneous arg, 11=missing arg, 21=invalid arg | ||||
|     [[ $1 ]] || return 11 | ||||
|     [[ $2 ]] && return 8 | ||||
|     [[ ( $(printf %d "$1" 2> /dev/null ) == $1 ) \ | ||||
|         && ( $1 -ge 0 ) && ( $1 -le 255 ) ]] || return 21 | ||||
|     # args are valid | ||||
|     echo -n -e "\x$(printf %02X "$1")" | ||||
| } | ||||
|  | ||||
| writechars () { | ||||
| # write one or more characters (bytes) to file | ||||
| # arg1: filename | ||||
| # arg2: (optional) offset (# of bytes to skip before writing) | ||||
| # arg3 OR stdin: sequence of characters | ||||
| #  [stdin required if writing NUL (0) or trailing LF (0x0A) chars] | ||||
| #  out: nothing | ||||
| # exit: 8=extraneous arg, 11=missing arg1, | ||||
| #       13=missing stdin/arg3, 22=invalid arg2 | ||||
|     [[ $1 ]] || { [[ -t 0 ]] || cat > /dev/null; return 11; } | ||||
|     [[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && \ | ||||
|         ( $2 -ge 0 ) ]] || { [[ -t 0 ]] || cat > /dev/null; return 22; } } | ||||
|     [[ ( ! -t 0 ) && $3 ]] && { cat > /dev/null; return 8; } | ||||
|     [[ ( -t 0 ) ]] && { [[ $4 ]] && return 8; [[ $3 ]] || return 13; } | ||||
|     # args are valid | ||||
|     if [[ -t 0 ]]; then | ||||
|         echo -n "$3" | \ | ||||
|             dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
|     else | ||||
|         dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null | ||||
|     fi | ||||
| } | ||||
|  | ||||
| #---- mkatinit starts here | ||||
| IFS='' | ||||
|  | ||||
| #defaults | ||||
| sharepath=$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) | ||||
| prefix=/$(grep options:prodos /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f2) | ||||
| gsprefix=$prefix | ||||
| startprog="$prefix/BASIC.SYSTEM" | ||||
| gsstartprog="$prefix/SYSTEM/FINDER" | ||||
| filename="ATINIT" | ||||
| user=$(whoami) | ||||
|  | ||||
| echo | ||||
|  | ||||
| usersfolder=1 | ||||
| while [ -n "$1" ] && [ "${1:0:1}" = '-' ]; do | ||||
|     flag="$1" | ||||
|     if [ $flag = "-gs" ]; then | ||||
|         gs=1 | ||||
|         shift | ||||
|         continue | ||||
|     elif [ $flag = "-d" ]; then | ||||
|         noprompt=1 | ||||
|         shift | ||||
|         continue | ||||
|     elif [ $flag = "-f" ]; then | ||||
|         overwrite=1 | ||||
|         shift | ||||
|         continue | ||||
|     elif [ $flag = "-g" ]; then | ||||
|         alsoguest=1 | ||||
|         shift | ||||
|         continue | ||||
|     elif [ $flag = "-c" ]; then | ||||
|         usersfolder=0 | ||||
|         shift | ||||
|         continue | ||||
|     else | ||||
|         badflag=1 | ||||
|         break | ||||
|     fi | ||||
| done | ||||
|  | ||||
| if [ $usersfolder -eq 0 ] && [ -n "$alsoguest" ]; then | ||||
|     badflag=1 | ||||
| fi | ||||
|  | ||||
| if [ $badflag ]; then | ||||
|     echo "usage: mkatinit [-gs] [-d] [-f] [-g | -c] [<username>|guest]" | ||||
|     echo | ||||
|     echo "<username> should be the name of a netatalk user, or 'guest'" | ||||
|     echo "-gs sets the default ProDOS netboot system startup program and" | ||||
|     echo "      prefix for GS/OS (if omitted, ProDOS 8 defaults are used)" | ||||
|     echo "-d  use the default start program and prefix, without prompting" | ||||
|     echo "-f  overwrite existing ATINIT file if present, without warning" | ||||
|     echo "-g  create an ATINIT file for Guest as well as the specified user" | ||||
|     echo "-c  write ATNIT to current directory instead of USERS hierarchy" | ||||
|     echo | ||||
|     exit | ||||
| fi | ||||
|  | ||||
| arg="$1" | ||||
|  | ||||
| [[ -z $arg ]] && arg=$user | ||||
|  | ||||
| while : ; do | ||||
|  | ||||
|     if [ ${#arg} -gt 32 ]; then | ||||
|         echo "User name is too long. Exiting with no action." | ||||
|         exit | ||||
|     elif [ -n "$arg" ]; then | ||||
|         if [ `echo $arg | tr '[:upper:]' '[:lower:]'` = "guest" ]; then | ||||
|             username='<Any User>' | ||||
|             alsoguest= | ||||
|             if [[ ! $(grep -F -s $(ls -1 /home) /etc/default/netatalk) ]]; then | ||||
|                 echo 'Warning: The AFPD_GUEST setting in /etc/default/netatalk is not assigned to a' | ||||
|                 echo 'user with a folder in /home. Guest users may be able to boot over the network' | ||||
|                 echo 'into ProDOS 8 for read-only access, but will not be able to boot into GS/OS.' | ||||
|                 if [ $gs ]; then | ||||
|                     echo ' Using ProDOS 8 defaults.' | ||||
|                     gs= | ||||
|                 else | ||||
|                     echo | ||||
|                 fi | ||||
|                 echo | ||||
|             fi | ||||
|         else | ||||
|             username="$arg" | ||||
|             if [[ ! $(ls -1 /home | grep -F -s $username) ]]; then | ||||
|                 echo "Warning: This username ($username) does not have a folder in /home. This user may" | ||||
|                 echo "not be able to boot over the network into ProDOS 8 or GS/OS." | ||||
|                 echo | ||||
|             fi | ||||
|         fi | ||||
|         if [ $gs ]; then | ||||
|             startprog="$gsstartprog" | ||||
|             prefix="$gsprefix" | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     # make username all caps | ||||
|     username=`echo $username | tr '[:lower:]' '[:upper:]'` | ||||
|  | ||||
|     # prompt for folders | ||||
|     if [ ! $doalsoguest ] && [ ! $noprompt ]; then | ||||
|         while : ; do | ||||
|             echo "Enter the ProDOS path to the startup system program." | ||||
|             echo "default (CR to accept): $startprog" | ||||
|             read | ||||
|             if [ ${#REPLY} -gt 64 ]; then | ||||
|                 continue | ||||
|             elif [ -n "$REPLY" ]; then | ||||
|                 startprog="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" | ||||
|                 echo | ||||
|             fi | ||||
|             break | ||||
|         done | ||||
|  | ||||
|         while : ; do | ||||
|             echo "Enter the initial ProDOS prefix:" | ||||
|             echo "default (CR to accept): $prefix" | ||||
|             read | ||||
|             if [ ${#REPLY} -gt 64 ]; then | ||||
|                 continue | ||||
|             elif [ -n "$REPLY" ]; then | ||||
|                 prefix="`echo $REPLY | tr '[:lower:]' '[:upper:]'`" | ||||
|                 echo | ||||
|             fi | ||||
|             break | ||||
|         done | ||||
|     fi | ||||
|  | ||||
|     # create folders if needed | ||||
|     filepath="$PWD/$filename" | ||||
|  | ||||
|     while [ $usersfolder -eq 1 ]; do | ||||
|         # create folders for ATINIT | ||||
|         while [ ! -d "$sharepath" ]; do | ||||
|             echo "Shared volume '$sharepath' not found. Edit mkatinit to change the default." | ||||
|             echo "Enter the local path to the netatalk shared volume used for netboot:" | ||||
|             read sharepath | ||||
|         done | ||||
|  | ||||
|         if [ ! -d "$sharepath/USERS" ]; then | ||||
|             mkdir "$sharepath/USERS" | ||||
|             if [ $? -ne 0 ]; then | ||||
|                 break | ||||
|             fi | ||||
|         fi | ||||
|         if [ ! -d "$sharepath/USERS/$username" ]; then | ||||
|             mkdir "$sharepath/USERS/$username" | ||||
|             if [ $? -ne 0 ]; then | ||||
|                 break | ||||
|             fi | ||||
|         fi | ||||
|         if [ ! -d "$sharepath/USERS/$username/SETUP" ]; then | ||||
|             mkdir "$sharepath/USERS/$username/SETUP" | ||||
|             if [ $? -ne 0 ]; then | ||||
|                 break | ||||
|             fi | ||||
|         else | ||||
|             if [ ! -w "$sharepath/USERS/$username/SETUP" ]; then | ||||
|                 break | ||||
|             fi | ||||
|         fi | ||||
|  | ||||
|         # we have a valid USERS folder target for ATINIT | ||||
|         filepath="$sharepath/USERS/$username/SETUP/$filename" | ||||
|         usersfolder=2 | ||||
|     done | ||||
|  | ||||
|     if [ $usersfolder -eq 1 ]; then | ||||
|         echo "Could not write to shared volume. Creating ATINIT in current directory." | ||||
|         if [ -n "$alsoguest" ]; then | ||||
|             echo "ATINIT for Guest user will not be created." | ||||
|         fi | ||||
|         echo | ||||
|         alsoguest= | ||||
|     fi | ||||
|  | ||||
|     if [ ! $doalsoguest ]; then | ||||
|         echo "netboot start program: $startprog" | ||||
|         echo "netboot start prefix : $prefix" | ||||
|         echo | ||||
|     fi | ||||
|  | ||||
|     #remove ATINIT if present | ||||
|     if [ ! $overwrite ] && [ -f "$filepath" ]; then | ||||
|         echo -n "$filepath already exists. Overwrite? " | ||||
|         while read -s -n 1 > /dev/null 2>&1; do | ||||
|             if [ -z "$REPLY" ]; then | ||||
|                 continue | ||||
|             elif [ "$REPLY" = "Y" ] || [ "$REPLY" = "y" ]; then | ||||
|                 echo | ||||
|                 break | ||||
|             elif [ "$REPLY" = "N" ] || [ "$REPLY" = "n" ]; then | ||||
|                 echo | ||||
|                 echo "Exiting with no action." | ||||
|                 exit | ||||
|             fi | ||||
|         done | ||||
|     fi | ||||
|  | ||||
|     #write the file. start with zeroes | ||||
|     dd if=/dev/zero of="$filepath" bs=1 count=276 2> /dev/null | ||||
|     #put in startprog, prefix, username (first byte of each field is length) | ||||
|     # ( echo -n "${#startprog}" | awk '{printf("%c",$0);}'; echo -n "$startprog"; ) | dd of="$filepath" bs=1 seek=7 conv=notrunc 2> /dev/null | ||||
|     # ( echo -n "${#prefix}" | awk '{printf("%c",$0);}'; echo -n "$prefix"; ) | dd of="$filepath" bs=1 seek=78 conv=notrunc 2> /dev/null | ||||
|     # ( echo -n "${#username}" | awk '{printf("%c",$0);}'; echo -n "$username"; ) | dd of="$filepath" bs=1 seek=143 conv=notrunc 2> /dev/null | ||||
|     ( decToChar "${#startprog}"; echo -n "$startprog"; ) | writechars "$filepath" 7 | ||||
|     ( decToChar "${#prefix}"; echo -n "$prefix"; ) | writechars "$filepath" 78 | ||||
|     ( decToChar "${#username}"; echo -n "$username"; ) | writechars "$filepath" 143 | ||||
|  | ||||
|     echo "Created $filepath" | ||||
|     if [ ! $alsoguest ]; then | ||||
|         break | ||||
|     fi | ||||
|  | ||||
|     if [ $usersfolder -eq 2 ]; then | ||||
|         usersfolder=1 | ||||
|     fi | ||||
|     doalsoguest=1 | ||||
|     arg='guest' | ||||
| done | ||||
|  | ||||
| echo | ||||
							
								
								
									
										83
									
								
								scripts/tools/mkvolinfo
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								scripts/tools/mkvolinfo
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # mkvolinfo -- creates a (share)/.AppleDesktop/.volinfo file | ||||
|  | ||||
| makeVolInfoFile () { | ||||
| 	[[ -d $sharepath/.AppleDesktop ]] || mkdir $sharepath/.AppleDesktop | ||||
| 	touch $volinfo | ||||
| 	echo 'MAC_CHARSET:MAC_ROMAN' >> $volinfo | ||||
| 	echo 'VOL_CHARSET:UTF8' >> $volinfo | ||||
| 	echo 'ADOUBLE_VER:v2' >> $volinfo | ||||
| 	echo 'CNIDBACKEND:dbd' >> $volinfo | ||||
| 	echo 'CNIDDBDHOST:localhost' >> $volinfo | ||||
| 	echo 'CNIDDBDPORT:4700' >> $volinfo | ||||
| 	echo "CNID_DBPATH:$sharepath" >> $volinfo | ||||
| 	echo 'VOLUME_OPTS:PRODOS CACHEID' >> $volinfo | ||||
| 	if (( $mixedcase )); then | ||||
| 		echo 'VOLCASEFOLD:' >> $volinfo | ||||
| 	else | ||||
| 		echo 'VOLCASEFOLD:MTOULOWER UTOMUPPER' >> $volinfo | ||||
| 	fi | ||||
| 	echo 'EXTATTRTYPE:AFPVOL_EA_AD' >> $volinfo | ||||
| 	echo ".volinfo for $sharepath has been created." | ||||
| } | ||||
|  | ||||
| while [[ $1 == "-f" || $1 == "-c" ]]; do | ||||
| 	if [[ $1 == "-f" ]]; then | ||||
| 		force=1 | ||||
| 		shift | ||||
| 	fi | ||||
|  | ||||
| 	if [[ $1 == "-c" ]]; then | ||||
| 		mixedcase=1 | ||||
| 		shift | ||||
| 	fi | ||||
| done | ||||
|  | ||||
| if [[ ${1:0:1} == "-" ]]; then | ||||
|  | ||||
| 	echo "usage: mkvolinfo [-f] [-c] [shared volume path]" | ||||
| 	echo | ||||
| 	echo "-c will create the .volinfo file to specify no uppercase filename conversion" | ||||
| 	echo "-f will create the .volinfo file without prompting, if none exists" | ||||
| 	echo "If a path is specified, that is what is used, otherwise the last entry" | ||||
| 	echo "in /usr/local/etc/netatalk/AppleVolumes.default is used." | ||||
|  | ||||
| else | ||||
| 	sudo true | ||||
| 	if [[ $1 ]]; then | ||||
| 		sharepath=$(readlink -m $1) | ||||
| 	else | ||||
| 		sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) | ||||
| 	fi | ||||
|  | ||||
| 	volinfo=$sharepath/.AppleDesktop/.volinfo | ||||
|  | ||||
| 	if [[ ! -d $sharepath ]]; then | ||||
| 		echo "$sharepath does not exist." | ||||
| 	else | ||||
| 		if [[ -f $volinfo ]]; then | ||||
| 			echo "$volinfo already exists." | ||||
| 		else | ||||
| 			if [[ $force ]]; then | ||||
| 				makeVolInfoFile | ||||
| 			else | ||||
| 				echo "The .volinfo file is automatically generated when you first" | ||||
| 				echo "log in from an AFP (Apple II or Mac) client machine." | ||||
| 				echo "If you can't do this, you can create a .volinfo file now" | ||||
| 				echo "based on assumed defaults; proceed with caution if you have" | ||||
| 				echo "customized your AppleVolumes files." | ||||
| 				echo | ||||
| 				echo "If the path shown below is incorrect, you can specify" | ||||
| 				echo "the path to your shared volume as an argument to mkvolinfo." | ||||
| 				echo | ||||
| 				echo -n "Make .volinfo for shared volume $sharepath now? " | ||||
| 				read | ||||
| 				if [[ ${REPLY:0:1} == "y" ]] || [[ ${REPLY:0:1} == "Y" ]]; then | ||||
| 					makeVolInfoFile | ||||
| 				fi | ||||
| 			fi | ||||
| 		fi | ||||
| 	fi | ||||
| fi | ||||
| @@ -1,83 +0,0 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
|  | ||||
| # mkvolinfo -- creates a (share)/.AppleDesktop/.volinfo file | ||||
|  | ||||
| makeVolInfoFile () { | ||||
|     [[ -d $sharepath/.AppleDesktop ]] || mkdir $sharepath/.AppleDesktop | ||||
|     touch $volinfo | ||||
|     echo 'MAC_CHARSET:MAC_ROMAN' >> $volinfo | ||||
|     echo 'VOL_CHARSET:UTF8' >> $volinfo | ||||
|     echo 'ADOUBLE_VER:v2' >> $volinfo | ||||
|     echo 'CNIDBACKEND:dbd' >> $volinfo | ||||
|     echo 'CNIDDBDHOST:localhost' >> $volinfo | ||||
|     echo 'CNIDDBDPORT:4700' >> $volinfo | ||||
|     echo "CNID_DBPATH:$sharepath" >> $volinfo | ||||
|     echo 'VOLUME_OPTS:PRODOS CACHEID' >> $volinfo | ||||
|     if (( $mixedcase )); then | ||||
|         echo 'VOLCASEFOLD:' >> $volinfo | ||||
|     else | ||||
|         echo 'VOLCASEFOLD:MTOULOWER UTOMUPPER' >> $volinfo | ||||
|     fi | ||||
|     echo 'EXTATTRTYPE:AFPVOL_EA_AD' >> $volinfo | ||||
|     echo ".volinfo for $sharepath has been created." | ||||
| } | ||||
|  | ||||
| while [[ $1 == "-f" || $1 == "-c" ]]; do | ||||
|     if [[ $1 == "-f" ]]; then | ||||
|         force=1 | ||||
|         shift | ||||
|     fi | ||||
|  | ||||
|     if [[ $1 == "-c" ]]; then | ||||
|         mixedcase=1 | ||||
|         shift | ||||
|     fi | ||||
| done | ||||
|  | ||||
| if [[ ${1:0:1} == "-" ]]; then | ||||
|  | ||||
|     echo "usage: mkvolinfo [-f] [-c] [shared volume path]" | ||||
|     echo | ||||
|     echo "-c will create the .volinfo file to specify no uppercase filename conversion" | ||||
|     echo "-f will create the .volinfo file without prompting, if none exists" | ||||
|     echo "If a path is specified, that is what is used, otherwise the last entry" | ||||
|     echo "in /usr/local/etc/netatalk/AppleVolumes.default is used." | ||||
|  | ||||
| else | ||||
|     sudo true | ||||
|     if [[ $1 ]]; then | ||||
|         sharepath=$(readlink -m $1) | ||||
|     else | ||||
|         sharepath=$(grep ^/srv/A2SERVER /usr/local/etc/netatalk/AppleVolumes.default | tail -1 | cut -d" " -f1) | ||||
|     fi | ||||
|  | ||||
|     volinfo=$sharepath/.AppleDesktop/.volinfo | ||||
|  | ||||
|     if [[ ! -d $sharepath ]]; then | ||||
|         echo "$sharepath does not exist." | ||||
|     else | ||||
|         if [[ -f $volinfo ]]; then | ||||
|             echo "$volinfo already exists." | ||||
|         else | ||||
|             if [[ $force ]]; then | ||||
|                 makeVolInfoFile | ||||
|             else | ||||
|                 echo "The .volinfo file is automatically generated when you first" | ||||
|                 echo "log in from an AFP (Apple II or Mac) client machine." | ||||
|                 echo "If you can't do this, you can create a .volinfo file now" | ||||
|                 echo "based on assumed defaults; proceed with caution if you have" | ||||
|                 echo "customized your AppleVolumes files." | ||||
|                 echo | ||||
|                 echo "If the path shown below is incorrect, you can specify" | ||||
|                 echo "the path to your shared volume as an argument to mkvolinfo." | ||||
|                 echo | ||||
|                 echo -n "Make .volinfo for shared volume $sharepath now? " | ||||
|                 read | ||||
|                 if [[ ${REPLY:0:1} == "y" ]] || [[ ${REPLY:0:1} == "Y" ]]; then | ||||
|                     makeVolInfoFile | ||||
|                 fi | ||||
|             fi | ||||
|         fi | ||||
|     fi | ||||
| fi | ||||
							
								
								
									
										415
									
								
								setup/index.txt
									
									
									
									
									
								
							
							
						
						
									
										415
									
								
								setup/index.txt
									
									
									
									
									
								
							| @@ -1,358 +1,93 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # A2SERVER master setup script, last update 15-Jul-20 | ||||
| # it downloads and executes several scripts related to the setup of | ||||
| # netatalk configured for Apple II use on Debian or Raspbian. | ||||
| # more info is at http://ivanx.com/a2server | ||||
| # setup/index.txt - upgrade path from Ivan's a2server tree | ||||
| # | ||||
| # Ivan's a2server installed with a single copy-paste of a command line that | ||||
| # downloaded a script and ran it sight-unseen.  People are going to continue | ||||
| # to run that command (they shouldn't, but they will), and we can support | ||||
| # them doing it for now. | ||||
|  | ||||
| # to download and execute, type: | ||||
| # wget ivanx.com/a2server/setup; source setup | ||||
| a2sBranch="master" | ||||
| a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/${a2sBranch}" | ||||
| a2sTarball="https://github.com/RasppleII/a2server/archive/${a2sBranch}.tar.gz" | ||||
|  | ||||
| a2serverVersion="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 / | ||||
| case "$A2SERVER_SCRIPT_URL" in | ||||
| 	*/) scriptURL="$A2SERVER_SCRIPT_URL" ;; | ||||
| 	*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | ||||
| esac | ||||
| case "$A2SERVER_BINARY_URL" in | ||||
| 	*/) binaryURL="$A2SERVER_BINARY_URL" ;; | ||||
| 	*) binaryURL="${A2SERVER_BINARY_URL:-http://ivanx.com/a2server/files}/" ;; | ||||
| esac | ||||
| useExternalURL=1 | ||||
| [[ $A2SERVER_NO_EXTERNAL ]] && useExternalURL= | ||||
| 	cat <<-EOT | ||||
| 	This script exists solely for backward-compatibility with IvanX's a2server | ||||
| 	website and aliases installed by older versions.  You appear to have an | ||||
| 	a2server source directory here: | ||||
| 	 	$a2sSource | ||||
|  | ||||
| isRpi= | ||||
| [[ -f /usr/bin/raspi-config ]] && isRpi=1 | ||||
| 	Please run ./install.sh in that directory.  Thanks! | ||||
|  | ||||
| isDebian= | ||||
| lsb_release -a 2> /dev/null | grep -q 'Distributor ID:.Debian' && [[ ( -f /etc/debian_version ) && ( $(cut -d . -f 1 < /etc/debian_version) -ge "7" ) ]] && isDebian=1 | ||||
|  | ||||
| installedVersion= | ||||
| if [ -f /usr/local/etc/A2SERVER-version ]; then | ||||
|     installedVersion="$(cat /usr/local/etc/A2SERVER-version)" | ||||
| 	EOT | ||||
| 	exit 1 | ||||
| fi | ||||
| echo "A2SERVER version available: $a2serverVersion" | ||||
| echo "A2SERVER version installed: ${installedVersion:=None}" | ||||
|  | ||||
| echo | ||||
| [[ $scriptURL != *"ivanx.com"* && $scriptURL != *"raw.githubusercontent.com/RasppleII/a2server"* ]] && echo "Using script URL: $scriptURL" | ||||
| [[ $binaryURL != *"ivanx.com"* ]] && echo "Using binary URL: $binaryURL" | ||||
| [[ ! $useExternalURL ]] && echo -e "Not using external URLs. Downloads must be available from:\n  ${binaryURL}external/appleii/\n  ${binaryURL}external/source/\n  (See the A2SERVER developer page for more information.)" | ||||
| # Find the version in the install script | ||||
| newVersion=$(wget -qO- "${a2sScriptURL}/install.sh" | grep '^a2serverVersion' | cut -d '"' -f 2) | ||||
|  | ||||
| skipRepoUpdate= | ||||
| # It almost never is, but this script could be run with command line arguments, | ||||
| # of which -y we can use, so we should check for it.  We'll pass them all to | ||||
| # the install script later | ||||
| autoAnswerYes= | ||||
| installAll= | ||||
| setupNetBoot= | ||||
| setupWindowsSharing= | ||||
| compileAlways= | ||||
| rm /tmp/a2server-* 2> /dev/null | ||||
| while [[ $1 ]]; do | ||||
|     if [[ $1 == "-r" ]]; then | ||||
|         shift | ||||
|         skipRepoUpdate="-r" | ||||
|         touch /tmp/a2server-packageReposUpdated | ||||
|     elif [[ $1 == "-i" ]]; then | ||||
|         shift | ||||
|         installAll="-i" | ||||
|     elif [[ $1 == "-y" ]]; then | ||||
|         shift | ||||
|         autoAnswerYes="-y" | ||||
|         touch /tmp/a2server-autoAnswerYes | ||||
|     elif [[ $1 == "-b" ]]; then | ||||
|         shift | ||||
|         setupNetBoot="-b" | ||||
|         touch /tmp/a2server-setupNetBoot | ||||
|     elif [[ $1 == "-w" ]]; then | ||||
|         shift | ||||
|         setupWindowsSharing="-w" | ||||
|         touch /tmp/a2server-setupWindowsSharing | ||||
|     elif [[ $1 == "-c" ]]; then | ||||
|         shift | ||||
|         compileAlways="-c" | ||||
|         touch /tmp/a2server-compileAlways | ||||
|     elif [[ $1 == "-v" ]]; then | ||||
|         shift | ||||
|         # Version was already printed | ||||
|         [[ $0 == "-bash" ]] && return 1 || exit 1 | ||||
|     elif [[ $1 ]]; then | ||||
|         echo "options:" | ||||
|         echo "-v: display installed and available versions, then exit" | ||||
|         echo "-i: reinstall A2SERVER software (but not Apple II software)" | ||||
|         echo "-y: auto-answer yes to all prompts" | ||||
|         echo "-r: don't update package repositories" | ||||
|         echo "-b: auto-setup network boot (use with -y)" | ||||
|         echo "-w: auto-setup Windows file sharing (use with -y)" | ||||
|         echo "-c: compile non-package items, rather than downloading binaries" | ||||
|         [[ $0 == "-bash" ]] && return 1 || exit 1 | ||||
|     fi | ||||
| for arg in $@; do | ||||
| 	if [[ $arg == "-y" ]]; then | ||||
| 		autoAnswerYes=1 | ||||
| 		break | ||||
| 	fi | ||||
| done | ||||
|  | ||||
| if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 110 )); }; then | ||||
|     echo | ||||
|     echo "WARNING: The current A2SERVER installer scripts haven't been tested for" | ||||
|     echo "updating the earlier version of A2SERVER that you have. A fresh install" | ||||
|     echo "is suggested. Continuing is not recommended and could make A2SERVER" | ||||
|     echo "no longer work properly, or cause data to be lost." | ||||
| cat <<EOT | ||||
|  | ||||
| Hello, you've reached the single wget command version of the a2server install | ||||
| script.  This script is being phased out for a number of reasons.  The most | ||||
| important is that it is not repeatable.  This script will download things | ||||
| behind the scenes, run them without much verification, and then delete what it | ||||
| ran, no matter if the installation finished successfully or not.  The next | ||||
| time you run the same command, you may get a different (hopefully better) | ||||
| version. | ||||
|  | ||||
| Right now, a2server ${newVersion} is available. | ||||
|  | ||||
| If you are seeing this text, iKarith (Joseph Carter) hasn't bothered to write | ||||
| publicly-facing end-user documentation for downloading and installing a2server | ||||
| a more preferred way.  He's filed an issue about this, please do follow the | ||||
| instructions there: | ||||
| 	https://github.com/RasppleII/a2server/issues/60 | ||||
|  | ||||
| For now, this script does what the old installer used to. | ||||
|  | ||||
| EOT | ||||
|  | ||||
| if [[ ! $autoAnswerYes ]]; then | ||||
| 	printf "Do you want to install a2server with this script? " | ||||
| 	read | ||||
| 	if [[ ${REPLY:0:1} != "y" && ${REPLY:0:1} != "Y" ]]; then | ||||
| 		printf "\nOkay, not installing anything now!\n\n" | ||||
| 		exit 1 | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| a2server_update=0 | ||||
| doSetup=1 | ||||
| a2sSource=$(mktemp -d /tmp/a2server.XXXXXXXXXXXX) | ||||
|  | ||||
| if { [[ -f /usr/local/etc/A2SERVER-version ]] && (( $(head -c 3 /usr/local/etc/A2SERVER-version) < 152 )); }; then | ||||
|     a2server_update=1 | ||||
| fi | ||||
| # Normally tarballs unpack in a subdirectory, but we want it to unpack into | ||||
| # $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" | ||||
|  | ||||
| unsupportedOS=1 | ||||
| if [[ $isRpi ]]; then #supported Raspbian? (16-Feb-15, 20-Jun-14, 09-Jan-14, etc) | ||||
|     fwhash=$(zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | grep -m 1 'as of' | awk '{print $NF}') | ||||
|     fwsupported="-8aca5762- -462f3e3f476f7b6- -c32bc633039cd9- -9d34d0475f9- | ||||
|             -d4f5315cfac4e- -6f4a90c8cb8817f- -5dd9b4962e- -17c8799375- | ||||
|             -960832a6c2590635216c296b6ee0bebf67b21d50- | ||||
|             -2a329e0c7d8ea19c085bac5633aa4fccee0f21be- | ||||
|             -b2420fc150ae4616f5d9ec24bdaedc630586a529-" | ||||
|     [[ "$fwsupported" == *-$fwhash-* ]] && unsupportedOS= | ||||
|     # [[ ($fwhash == "8aca5762") || ($fwhash == "462f3e3f476f7b6") || ($fwhash == "c32bc633039cd9") || ($fwhash == "9d34d0475f9") || ($fwhash == "d4f5315cfac4e") || ($fwhash == "6f4a90c8cb8817f") || ($fwhash == "5dd9b4962e") || ($fwhash == "17c8799375") ]] && unsupportedOS= | ||||
| elif [[ $isDebian ]]; then # supported Debian? | ||||
|      debianVersion=$(cat /etc/debian_version) | ||||
|      debianSupported="-10.4- -9.2- -8.2- -7.9- -7.8- -7.6- -7.3-" | ||||
|      [[ $debianSupported == *-$debianVersion-* ]] && unsupportedOS= | ||||
| fi | ||||
| # Now we actually run the installer as if we were installing it by hand | ||||
| printf "\na2server: Running the installer now.\n" | ||||
| "${a2sSource}/install.sh" "$@" | ||||
|  | ||||
| if [[ $unsupportedOS && $isRpi ]]; then | ||||
|     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 | ||||
|     echo | ||||
|     echo "WARNING: A2SERVER and its installer scripts have only been tested on" | ||||
|     echo "Debian and Raspbian. Continuing is probably fine, but might not be." | ||||
|     echo "Theoretical worst case would be your operating system no longer works" | ||||
|     echo "properly or data is lost, so consider backing up first." | ||||
| fi | ||||
|  | ||||
| doSetup=1 | ||||
| if [[ $installAll || ! -f /usr/local/etc/a2server-help.txt ]] || (( $a2server_update )); then | ||||
|     echo | ||||
|     echo "Setting up A2SERVER will take up to 60 minutes, during which" | ||||
|     echo "you'll see a bunch of stuff spit out across the screen." | ||||
|     echo | ||||
|     if [[ ! $autoAnswerYes ]]; then | ||||
|         echo -n "Ready to set up A2SERVER? " | ||||
|         read | ||||
|         [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? )) | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| if (( $doSetup )); then | ||||
|  | ||||
|     echo | ||||
|     echo "a2server-setup modifies files and performs actions as the root user." | ||||
|     echo "For details, visit http://ivanx.com/a2server." | ||||
|     echo | ||||
|     if [[ ! $autoAnswerYes ]]; then | ||||
|         echo -n "Continue? " | ||||
|         read | ||||
|         [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; doSetup=$(( 1 - $? )) | ||||
|     fi | ||||
|  | ||||
|     if (( $doSetup )); then | ||||
|  | ||||
|         checkPw=1 | ||||
|         while [[ $checkPw ]] ; do | ||||
|             userPw=$(sudo grep "^$USER" /etc/shadow | cut -f 2 -d ':') | ||||
|             [[ $userPw == "$(echo 'apple2' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isApple2Pw=1 || isApple2Pw= | ||||
|             [[ $userPw == "$(echo 'raspberry' | perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "${userPw%"${userPw#\$*\$*\$}"}")" ]] && isRaspberryPw=1 || isRaspberryPw= | ||||
|      | ||||
|             password="your password" | ||||
|             [[ $isApple2Pw ]] && password="apple2" | ||||
|             [[ $isRaspberryPw ]] && password="raspberry" | ||||
|             checkPw= | ||||
|      | ||||
|             [[ $isRpi ]] && a2server="your Raspberry Pi" || a2server="A2SERVER" | ||||
|             if [[ ! $isApple2Pw && ! -f /usr/local/etc/A2SERVER-version ]]; then | ||||
|                 if [[ ! $autoAnswerYes ]]; then | ||||
|                     echo | ||||
|                     echo "To ensure that all client computers are able to connect to" | ||||
|                     echo "${a2server} using the same password, you probably want" | ||||
|                     echo "to change your user password to 'apple2'." | ||||
|                     echo | ||||
|                     echo -n "Do you want to change the password for user '$USER' to 'apple2' now? " | ||||
|                     read | ||||
|                 fi | ||||
|                 if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||
|                     echo "A2SERVER: changing password for user '$USER' to 'apple2'..." | ||||
|                     echo "$USER:apple2" | sudo chpasswd | ||||
|                     checkPw=1 | ||||
|                 fi | ||||
|             fi | ||||
|         done | ||||
|  | ||||
|         echo | ||||
|         echo "During this installation, enter '${password}' if prompted for passwords." | ||||
|         echo | ||||
|  | ||||
|         sudo true | ||||
|  | ||||
|         echo | ||||
|         echo "A2SERVER: Downloading scripts..." | ||||
|  | ||||
|         wget -q -O /tmp/1.storage "${scriptURL}scripts/a2server-1-storage.txt" | ||||
|         chmod ugo+x /tmp/1.storage | ||||
|  | ||||
|         wget -q -O /tmp/2.tools "${scriptURL}scripts/a2server-2-tools.txt" | ||||
|         chmod ugo+x /tmp/2.tools | ||||
|  | ||||
|         wget -q -O /tmp/3.sharing "${scriptURL}scripts/a2server-3-sharing.txt" | ||||
|         chmod ugo+x /tmp/3.sharing | ||||
|  | ||||
|         wget -q -O /tmp/5.netboot "${scriptURL}scripts/a2server-5-netboot.txt" | ||||
|         chmod ugo+x /tmp/5.netboot | ||||
|  | ||||
|         wget -q -O /tmp/6.samba "${scriptURL}scripts/a2server-6-samba.txt" | ||||
|         chmod ugo+x /tmp/6.samba | ||||
|  | ||||
|         wget -q -O /tmp/7.console "${scriptURL}scripts/a2server-7-console.txt" | ||||
|         chmod ugo+x /tmp/7.console | ||||
|  | ||||
|         echo "A2SERVER: Scripts have been downloaded. Installing..." | ||||
|  | ||||
|         if [[ $installAll ]]; then | ||||
|             sudo rm /usr/local/etc/A2SERVER-version 2> /dev/null | ||||
|             sudo rm /usr/local/bin/nulib2 2> /dev/null | ||||
|             sudo rm /usr/local/bin/unar 2> /dev/null | ||||
|             sudo rm /usr/local/sbin/macipgw 2> /dev/null | ||||
|             sudo rm /usr/local/bin/ciopfs 2> /dev/null | ||||
|             sudo rm /usr/local/etc/netatalk/afppasswd 2> /dev/null | ||||
|             sudo rm /usr/local/etc/netatalk/a2boot/p8 /usr/local/etc/netatalk/a2boot/ProDOS16\ Image 2> /dev/null | ||||
|         fi | ||||
|  | ||||
|         /tmp/1.storage | ||||
|         rm /tmp/1.storage | ||||
|         /tmp/2.tools | ||||
|         rm /tmp/2.tools | ||||
|         /tmp/3.sharing | ||||
|         rm /tmp/3.sharing | ||||
|         /tmp/5.netboot | ||||
|         rm /tmp/5.netboot | ||||
|         /tmp/6.samba | ||||
|         rm /tmp/6.samba | ||||
|         /tmp/7.console | ||||
|         rm /tmp/7.console | ||||
|         rm /tmp/a2server-packageReposUpdated &> /dev/null | ||||
|  | ||||
|         if [[ ! -f /usr/local/etc/A2SERVER-version ]] \ | ||||
|             || (( $(head -c 3 /usr/local/etc/A2SERVER-version) < ${a2serverVersion:0:3} )); then | ||||
|             echo "$a2serverVersion" | sudo tee /usr/local/etc/A2SERVER-version &> /dev/null | ||||
|         fi | ||||
|  | ||||
|         source /usr/local/etc/a2serverrc | ||||
|  | ||||
|         # get Kernel release (e.g. 3.6.11+) and version (e.g. #557) | ||||
|         kernelRelease=$(uname -r) | ||||
|         kernelMajorRelease=$(cut -d '.' -f 1 <<< $kernelRelease) | ||||
|         kernelMinorRelease=$(cut -d '.' -f 2 <<< $kernelRelease | sed 's/\(^[0-9]*\)[^0-9].*$/\1/') | ||||
|  | ||||
|         echo | ||||
|         # all done, see if AppleTalk is available and notify either way | ||||
|         if [[ $(ps aux | grep [a]talkd) ]]; then | ||||
|             echo "You now have a fully functional file server for Apple II clients." | ||||
|             echo "On an Apple IIe, it should be accessible via \"Log In\" on the" | ||||
|             echo "Workstation Card software. For IIgs users, it should be accessible" | ||||
|             echo "via the AppleShare control panel." | ||||
|             if [[ -f /srv/A2SERVER/A2FILES/System/Start.GS.OS ]]; then | ||||
|                 echo                 | ||||
|                 echo "You can network boot GS/OS." | ||||
|                 echo "On a ROM 01 IIgs, set slot 1 (printer port), or slot 2 (modem port)" | ||||
|                 echo "to Your Card, and slot 7 to AppleTalk, and Startup Slot to 7 or Scan." | ||||
|                 echo "On a ROM 3 IIgs, set slot 1 or 2, and Startup Slot, to AppleTalk." | ||||
|             fi | ||||
|             if [[ -f /srv/A2SERVER/A2FILES/BASIC.System ]]; then | ||||
|                 echo | ||||
|                 echo "You can network boot ProDOS 8. On an Apple IIe, put your Workstation Card" | ||||
|                 echo "in a slot above your disk controller card, or type PR#X with open-apple" | ||||
|                 echo "held down, with X being the slot of your Workstation Card." | ||||
|                 echo 'On a IIgs, press "8" during the initial procession of periods.' | ||||
|             fi | ||||
|             echo | ||||
|             echo "A2SERVER setup is complete! Go connect from your Apple II!" | ||||
|             echo | ||||
|         elif [[ -f /tmp/rpiUpdate ]]; then | ||||
|             echo "A2SERVER is now configured, but Apple II clients will not be able" | ||||
|             echo "to connect until you restart your Raspberry Pi." | ||||
|             echo | ||||
|             if [[ ! $autoAnswerYes ]]; then | ||||
|                 echo -n "Restart now? " | ||||
|                 read | ||||
|             fi | ||||
|             if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||
|                 sudo shutdown -r now | ||||
|                 echo | ||||
|                 echo "A2SERVER: Preparing to restart..." | ||||
|                 while :; do sleep 60; done | ||||
|             fi | ||||
|             rm /tmp/rpiUpdate | ||||
|             echo | ||||
|         elif [[ $kernelMajorRelease -eq 3 && $kernelMinorRelease -ge 12 && $kernelMinorRelease -le 15 ]]; then | ||||
|             echo "A2SERVER is now configured, but Apple II clients cannot connect" | ||||
|             echo "because of a kernel-crashing bug in Linux kernel 3.12 through 3.15." | ||||
|             echo "You have kernel version $kernelMajorRelease.$kernelMinorRelease." | ||||
|             echo "A2SERVER has disabled AppleTalk networking to prevent crashes." | ||||
|             echo "Please use kernel 3.11 or earlier, or kernel 3.16 or later." | ||||
|             echo | ||||
|         else | ||||
|             echo "A2SERVER is now configured, but Apple II clients cannot connect because" | ||||
|             echo "AppleTalk networking is unavailable. Please make sure that" | ||||
|             echo "your Linux distribution has a loadable AppleTalk kernel module or" | ||||
|             echo "has AppleTalk built into the kernel, and restart your server." | ||||
|             echo "Or, if you previously disabled AppleTalk in A2SERVER, re-enable it" | ||||
|             echo "by typing 'appletalk-on'." | ||||
|             echo | ||||
|         fi | ||||
|          | ||||
|         if [[ -f /tmp/noMacIP ]]; then | ||||
|             echo | ||||
|             echo "MacIP connections may be unavailable. If you know how, try" | ||||
|             echo "recompiling the AppleTalk kernel module with IPDDP options disabled." | ||||
|             echo | ||||
|             rm /tmp/noMacIP | ||||
|         fi | ||||
|  | ||||
|         if [[ -f /tmp/singleUser ]]; then | ||||
|             if [[ ! $autoAnswerYes ]]; then | ||||
|                 echo | ||||
|                 echo "Your Raspberry Pi was started in single-user mode in order to" | ||||
|                 echo -n "fix a problem. You should restart to operate normally. Restart now? " | ||||
|                 read | ||||
|             fi | ||||
|             if [[ $autoAnswerYes || ${REPLY:0:1} == "Y" || ${REPLY:0:1} == "y" ]]; then | ||||
|                 sudo shutdown -r now | ||||
|                 echo | ||||
|                 echo "A2SERVER: Preparing to restart..." | ||||
|                 while :; do sleep 60; done | ||||
|             fi | ||||
|             rm /tmp/singleUser | ||||
|             echo | ||||
|         fi | ||||
|  | ||||
|         echo | ||||
|         echo "Type 'system-shutdown' to turn off A2SERVER." | ||||
|         echo "Type 'a2server-setup' to configure network boot." | ||||
|         echo "Type 'a2server-help' for a list of other commands." | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| unset a2server_update 2> /dev/null | ||||
| unset doSetup 2> /dev/null | ||||
| rm /tmp/a2server-* 2> /dev/null | ||||
| rm setup &> /dev/null | ||||
| # Clean up and delete the installer we downloaded | ||||
| printf "\na2server: Finished with installer, now deleting ${a2sSource}.\n" | ||||
| rm -rf "$a2sSource" | ||||
|   | ||||
							
								
								
									
										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; | ||||
|                  os option (Raspbian update) removed from a2server-setup | ||||
|  | ||||
| 1.5.3a1: July 2020: initial support for Debian/Raspbian Buster | ||||
|   | ||||
							
								
								
									
										131
									
								
								update/index.txt
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								update/index.txt
									
									
									
									
									
								
							| @@ -1,45 +1,114 @@ | ||||
| #! /bin/bash | ||||
| # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: | ||||
| # vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=sh: | ||||
|  | ||||
| # Ensure URL we'll use ends in a / | ||||
| case "$A2SERVER_SCRIPT_URL" in | ||||
| 	*/) scriptURL="$A2SERVER_SCRIPT_URL" ;; | ||||
| 	*) scriptURL="${A2SERVER_SCRIPT_URL:-https://raw.githubusercontent.com/RasppleII/a2server/current}/" ;; | ||||
| esac | ||||
| # update/index.txt - upgrade path from Ivan's a2server tree | ||||
| # | ||||
| # Ivan's a2server installed with a single copy-paste of a command line that | ||||
| # downloaded a script and ran it sight-unseen.  It also installed an alias | ||||
| # command that would perform a similar one-liner to upgrade a2server to the | ||||
| # latest version.  This script provides that interface for upgrades. | ||||
|  | ||||
| currentVersion=$(wget -qO- "${scriptURL}setup/index.txt" | grep '^a2serverVersion' | cut -d '"' -f 2) | ||||
| a2sBranch="master" | ||||
| a2sScriptURL="https://raw.githubusercontent.com/RasppleII/a2server/${a2sBranch}" | ||||
| a2sTarball="https://github.com/RasppleII/a2server/archive/${a2sBranch}.tar.gz" | ||||
|  | ||||
| # Set 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 | ||||
|     installedVersion=$(cat /usr/local/etc/A2SERVER-version) | ||||
| else | ||||
|     installedVersion=100 | ||||
| 	read installedVersion < /usr/local/etc/A2SERVER-version | ||||
| 	# Convert old three-digit version if needed | ||||
|     if [[ $installedVersion != *.*.* ]]; then | ||||
|         installedVersion="${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2}" | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| autoAnswerYes= | ||||
| for arg in $@; do | ||||
|     if [[ $arg == "-y" ]]; then | ||||
|         autoAnswerYes=1 | ||||
|         break | ||||
|     fi | ||||
| 	if [[ $arg == "-y" ]]; then | ||||
| 		autoAnswerYes=1 | ||||
| 		break | ||||
| 	fi | ||||
| done | ||||
|  | ||||
| echo | ||||
| echo "Update history:" | ||||
| wget -qO- "${scriptURL}update/versionhistory.txt" | ||||
| echo | ||||
| echo "installed version: ${installedVersion:0:1}.${installedVersion:1:1}.${installedVersion:2:1}" | ||||
| echo "current version: ${currentVersion:0:1}.${currentVersion:1:1}.${currentVersion:2:1}" | ||||
| echo | ||||
| if [[ $autoAnswerYes ]]; then | ||||
|     REPLY="y" | ||||
| printf "\na2server web update\n\n" | ||||
|  | ||||
| if (( $a2sWebUpdate )); then | ||||
| 	newVersion=$(wget -qO- "${a2sScriptURL}/install.sh" | grep '^a2serverVersion' | cut -d '"' -f 2) | ||||
| 	cat <<-EOT | ||||
| 	You've started the single command a2server update script.  This script will | ||||
| 	download things behind the scenes, run them without much verification, and | ||||
| 	then it will delete what it ran whether the upgrade finished successfully or | ||||
| 	not.  For this reason, we are going to be phasing this script out in the | ||||
| 	future. | ||||
| 	EOT | ||||
| else | ||||
|     echo -n "Do you want to update (or reinstall) A2SERVER? " | ||||
|     read | ||||
| fi | ||||
| if [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]]; then | ||||
|     # sudo rm /usr/local/etc/netatalk/a2boot/* &> /dev/null | ||||
|     wget -q -O /tmp/setup "${scriptURL}setup/index.txt"; source /tmp/setup -i "$@" | ||||
| 	newVersion=$(grep '^a2serverVersion' "$a2sSource/install.sh" | cut -d '"' -f 2) | ||||
| 	cat <<-EOT | ||||
| 	You've started the single command a2server update script from inside the | ||||
| 	a2server source directory for version $newVersion.  This script will only | ||||
| 	upgrade to or reinstall that version. | ||||
| 	EOT | ||||
| fi | ||||
|  | ||||
| unset currentVersion 2> /dev/null | ||||
| unset installedVersion 2> /dev/null | ||||
| if [[ $installedVersion ]]; then | ||||
| 	printf "\nRight now you have a2server %s installed\n" "$installedVersion" | ||||
| else | ||||
| 	printf "\nRight now you don't appear to have a2server installed\n" | ||||
| fi | ||||
|  | ||||
| if [[ ! $autoAnswerYes ]]; then | ||||
| 	printf "\nPress Enter to continue " | ||||
| 	read | ||||
| fi | ||||
|  | ||||
| # If running from local source tree, that's what you'll be upgrading to | ||||
| printf "\nProject history:\n" | ||||
| if (( $a2sWebUpdate )); then | ||||
| 	wget -qO- "${a2sScriptURL}/update/versionhistory.txt" | ||||
| else | ||||
| 	cat "$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; | ||||
|                  source code at GitHub (thanks Joseph) | ||||
|  | ||||
| 1.5.0r2: Jan 16: fixed GitHub URLs to prevent https errors during installation | ||||
|                  (thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html) | ||||
|  | ||||
| 1.5.1: Jan 2016: fixed GitHub URLs to prevent https errors during installation | ||||
|                  (thanks to http://blogs.yahoo.co.jp/ushi_cow/57459736.html); | ||||
|                  bug fixes and minor text changes | ||||
| @@ -77,8 +80,6 @@ | ||||
|                  install; enable SSH server if disabled on Raspberry Pi; fixes | ||||
|                  changed download links for GS/OS communication software | ||||
|  | ||||
| 1.5.3a2: July 2020: initial support for Debian/Raspbian Buster | ||||
|  | ||||
| Big thanks to: Anthony Martino, Henry Courbis, Joseph Carter, Jason King, | ||||
| Andy McFadden, Steven Hirsch, Geoff Body, Peter Wong, Tony Diaz, David Schmidt, | ||||
| David Schmenk, Ewen Wannop, Andrew Roughan, Antoine Vignau, Martin Haye, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user