[comp.sources.amiga] v90i208: Free 1.01 - show how much free space is remaining on disk volumes, Part01/01

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/16/90)

Submitted-by: barrett@crabcake.cs.jhu.edu
Posting-number: Volume 90, Issue 208
Archive-name: util/free-1.01/part01

[ uuencoded executable enclosed  ...tad ]

	This program will display how much free space is remaining
on your disk volumes.  It runs from the CLI only.  The syntax is:

	1>  Free [<OPTIONS>] [volume1] [volume2] ... [volumeN]

o	Does not use self-modifying code, so it should work on
	ALL Amigas, not just 68000-based systems.
o	You can specify a device list on the command line.
o	You can specify a device list using an environment variable.
o	Requestors are turned off, so non-mounted devices are just
	skipped.  (See -r option.)
o	Data is written in correct columns, regardless of the 
	lengths of the volume names.  (See -l option.)
o	Total memory free is shown, along with CHIP and FAST
	subtotals.
o	Command-line options added so the user can customize the
	program.
o	Written in ANSI C, in a modular and easy-to-read style.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  CONTENTS Free.DOC Free.uu Source Source/Makefile
#   Source/dos.c Source/env.c Source/errors.c Source/free.h
#   Source/getopt.c Source/main.c Source/output.c Source/strings.c
# Wrapped by tadguy@xanth on Sun Jul 15 17:48:38 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'CONTENTS' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CONTENTS'\"
else
echo shar: Extracting \"'CONTENTS'\" \(354 characters\)
sed "s/^X//" >'CONTENTS' <<'END_OF_FILE'
XFree:		Display how much free space (in bytes) you have on any or
X		all of your mounted disk volumes.  Runs from CLI only.
X		Based on "Free" by Tom Smythe on Fish Disk 66, but totally
X		rewritten and enhanced.  Includes source code in C.
X		Also includes a newly written "getopt()" function for 
X		programmers.  Version 1.01.
X		Author:  Daniel Jay Barrett
END_OF_FILE
if test 354 -ne `wc -c <'CONTENTS'`; then
    echo shar: \"'CONTENTS'\" unpacked with wrong size!
fi
chmod +x 'CONTENTS'
# end of 'CONTENTS'
fi
if test -f 'Free.DOC' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Free.DOC'\"
else
echo shar: Extracting \"'Free.DOC'\" \(7289 characters\)
sed "s/^X//" >'Free.DOC' <<'END_OF_FILE'
XFREE:		Display free space on your mounted disk volumes.
X
XAuthor:		Daniel Jay Barrett, barrett@cs.jhu.edu.
X		April, 1990.
X		Inspired by "Free" by Tom Smythe on Fish Disk 66.
X		For a list of improvements over Smythe's program,
X		 see the end of this file.
X
XDistribution:	This program is Freely Distributable.
X		Make as many copies as you want.
X		Give this program to anybody, without cost.
X		Use my source code in any programs of your own.
X		(Please give me credit in your program -- thanks!)
X
X
X	----------------------------------------------------------------
X
XINTRODUCTION
X------------
X
X	This program will display how much free space is remaining
Xon your disk volumes.  It runs from the CLI only.  The syntax is:
X
X	1>  Free [<OPTIONS>] [volume1] [volume2] ... [volumeN]
X
X
XHOW TO USE "Free"
X------------------
X
XThere are three different ways that Free may behave.
X
X(1)	You can specify volume names on the command line.  Free will
X	display the free space on those volumes only.
X
X	Example:
X
X		1>  Free df0: df1: RAM:
X
X	Of course, you can use the Commodore Shell (or similar shell) to
X	define aliases, if you want to see disk space on your favorite
X	volumes:
X
X		1>  alias floppies Free df0: df1:
X		1>  floppies
X
X(2)	If you specify NO volume names on the command line, Free will then
X	look for an environment variable called FREE_DRIVES.  This is a
X	standard Commodore ENV: variable, whose value is set using the
X	"setenv" command.
X
X	The value of FREE_DRIVES is a list of volumes, separated by
X	commas.  There is no whitespace between volumes and commas,
X	and each volume must end (as usual) with a colon.  For
X	example:
X
X		1>  setenv FREE_DRIVES "df0:,df1:,dh0:,dh1:,RAM:,RAD:"
X
X	You can put a line like this in your startup-sequence.
X
X	REMEMBER:  In order to use environment variables and setenv, you
X	must have ENV: assigned somewhere.  (Under AmigaDOS 1.4 and up,
X	you must explicitly mount ENV:, I think.)  See your Amiga 
X	documentation about ENV: and environment variables.
X
X(3)	If you specify no volume names on the command line, and the
X	variable FREE_DRIVES does not exist, then Free will use a
X	default list of volumes:
X
X		RAD:
X		DF0:
X		DF1:
X
X	You can change this default list by modifying the value of
X	DEFAULT_VOLUMES in the header file of the source code.
X	I see no reason to do this, however, since you can use FREE_DRIVES
X	or Shell aliases (adding command-line arguments) to make an
X	equivalent change without recompiling.
X
X
XGETTING HELP
X------------
X
XType:
X		1>  Free ?
X
Xfor a summary of usage information.
X
X
XDISPLAYING FREE MEMORY
X----------------------
X
X	If you give the volume name "RAM:" (case doesn't matter), you will
Xbe shown how much free memory you have.  If you have FAST RAM, the number
Xwill be broken up into separate CHIP and FAST amounts, plus a TOTAL.
X
XCOMMAND-LINE OPTIONS
X--------------------
X
X	Command-line options always begin with a dash '-'.  You may specify
Xeach option with its own dash, or group several options under each dash.
XHowever, all options must preceed all volume names on the command line.
X
X	-b	Give answers in blocks instead of bytes.
X
X	-r	Turn on volume requestors (turned off by default).
X
X		NOTE:  If you use -r and "ENV:" is not available, you
X		will get a requestor asking for ENV:.  This is not a
X		bug... but I wanted you to be aware of it.  It's a VERY
X		good idea ALWAYS to have ENV: available, since more and
X		more programs are going to use it.
X
X	-m	[Advanced.]  Allocate memory for the output of Free.
X		To speed up screen output, everything is stored in a single
X		character array and then written to the screen.
X		The default array length is BUFSIZ (1024) bytes.
X		You can override this number with "-m BYTES", where BYTES
X		is the size of the output array.
X
X		I doubt you will ever need to use the -m option, but I
X		have included it for completeness.
X
X	-l	Specify the maximum length of a volume name (including
X		the colon).  Free assumes that all your volume names are
X		four characters long (df1:, rad:, etc.) or less.
X		Use this option to override this default.
X
X		The value you specify must be between 1 and 255, inclusive.
X
X	Examples:
X
X		1>  Free -r -b dh0:
X		1>  Free -br df1: df2:
X		1>  Free -m 10000 -rbl 8 df1:
X		1>  Free -m10000 -bl8
X
X
XERROR HANDLING
X--------------
X
X	If you specify a volume name illegally, Free will complain about
Xit.  For example:
X
X		1>  Free df1
X
XSince "df1" does not end with a colon (should be df1:), it is not a valid 
Xvolume name.
X
X	If you specify a legal volume name, but the volume is not mounted,
Xthen Free will display the volume name with the symbol "--" next to it.
XThis indicates that a floppy drive has no disk in it, or that a volume is
Xnot mounted.
X
X	Example:
X
X		1>  Free Nonexistent:
X		Nonexistent:     --
X
X	Non-existent volumes will not cause any volume requestors to pop up,
Xsince Free turns them off while it runs.  (You can enable volume requestors
Xwith the -r option.)
X
X
XLIMITATIONS OF THIS PROGRAM
X---------------------------
X
X	The following is a list of limitations on how this program
Xworks, due to the way it was designed.  If you don't like these decisions
Xthat I made, just modify the source code and recompile.  (Honestly, these
Xare such minor issues that I think nobody will care about them.)
X
X1)	If you specify your volume names using FREE_DRIVES, no device
X	name may have a comma in it.  The comma is used as a delimiter
X	character for separating volume names.
X
X	However, this is a simple problem to get around.  You can ASSIGN
X	an alternate name for your volume, or you can specify the volume
X	on the command line (where there are no "comma" restrictions).
X
X2)	The "free space" displayed must fit into 10 digits, or else
X	the indenting may not be correct.  (You don't have to worry about
X	this, unless you have more than 10 Gigabytes of space on a volume!)
X
X	If you want to change this limit in the source code, just change
X	the value of DEFAULT_SPACING in the file free.h.
X
X3)	The length of the value of FREE_DRIVES must be 1023 characters or
X	less, or else FREE_DRIVES will be ignored.  I think this is enough
X	space.
X
X	You can increase this limit in the source code; change the size of 
X	array envString in function TheEnvValue() in file env.c.
X
X4)	Free RAM: space is always in bytes, even if the -b option is
X	specified.  "Blocks" makes no sense when you're talking about
X	RAM:.
X
X
XCHANGES/IMPROVEMENTS OVER TOM SMYTHE'S PROGRAM
X----------------------------------------------
X
Xo	Does not use self-modifying code, so it should work on
X	ALL Amigas, not just 68000-based systems.
Xo	You can specify a device list on the command line.
Xo	You can specify a device list using an environment variable.
Xo	Requestors are turned off, so non-mounted devices are just
X	skipped.  (See -r option.)
Xo	Data is written in correct columns, regardless of the 
X	lengths of the volume names.  (See -l option.)
Xo	Total memory free is shown, along with CHIP and FAST
X	subtotals.
Xo	Command-line options added so the user can customize the
X	program.
Xo	Written in ANSI C, in a modular and easy-to-read style.
X
X
XSTUPID DISCLAIMER
X-----------------
X
XDaniel Jay Barrett makes no claims about the suitability of this program
Xfor any particular purpose.  Any damages incurred through the use of
Xthis program are entirely the responsibility of the USER.  Use at your
Xown risk.  So there!   :-)
END_OF_FILE
if test 7289 -ne `wc -c <'Free.DOC'`; then
    echo shar: \"'Free.DOC'\" unpacked with wrong size!
fi
chmod +x 'Free.DOC'
# end of 'Free.DOC'
fi
if test -f 'Free.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Free.uu'\"
else
echo shar: Extracting \"'Free.uu'\" \(14794 characters\)
sed "s/^X//" >'Free.uu' <<'END_OF_FILE'
Xbegin 700 Free
XM```#\P`````````#``````````(```EU```!U0````$```/I```)=4[Z$6A(#
XMYR`@E<I(YR`"=/XB+P`4+&R&ZDZN_ZQ,WT`$)$!*@&<8+PIA'B0`+PXB"BQL6
XMANI.KO^F+%]83V`"=/\@`DS?!`1.=4CG("!T`"\.<@%P)"QLANY.KO\Z+%\D'
XM0$CG(`(D"B(O`!0L;(;J3J[_CDS?0`0D*@`,E*H`$`@L``"&]68,(BH`%"`"O
XM3KH7$"0`+PYP)")*+&R&[DZN_RXL7R`"3-\$!$YU2.<`,"1O``PF;P`00I-"B
XMDB\.+&R&[DZN_WPL7R\.<@(L;(;N3J[_*"Q?)(`O#G($+&R&[DZN_R@L7R:`_
XM+PXL;(;N3J[_=BQ?3-\,`$YU2.<`("1O``@O#I/)+&R&[DZN_MHL7R2`(%(BE
XM;P`,(J@`N"!2(7S_____`+A,WP0`3G4@;P`$(6\`"`"X3G5.5?[X2.<@`"\M<
XM``A(>@"\2&W_`$ZZ%2!([4`$_O@D/````^U![?\`(@@L;(;J3J[_XDSM0`3^M
XM^"0`3^\`#&8*<`!,WP`$3EU.=2\"80183V#P2.<P`"8O``QT`$CG,`(F/```G
XM!`!![(+F)`@B+P`$+&R&ZDZN_]9,WT`,2H!O*$(LAN5![(+F##``("@`;012`
XM@F#P#((```/_9`I![(+F0C`H`&`"=``O#B(#+&R&ZDZN_]PL7TJ"9PA![(+FQ
XM(`A@`G``3-\`#$YU14Y6.B5S``!(YP`@)&\`"$AZ`EE(>@)0+PI(>@)$2'H"/
XM%DAL@5!.N@Z"2'H"1$AL@5!.N@YV2'H":$AL@5!.N@YJ2'@`;$AX`&U(>`!R(
XM2'@`8DAZ`A(O"DAZ`@9(>@)J2&R!4$ZZ#D1/[P!,2'@`8DAZ`I](;(%03KH.R
XM,$AX`')(>@*W2&R!4$ZZ#B!(>`!M2'H"R$AL@5!.N@X02'@`_TAX`&Q(>@+D/
XM2&R!4$ZZ#?Q/[P`T2'H##4AL@5!.N@WL2'H#0$AZ`R1(;(%03KH-W$AZ`S!(!
XM>@,X2&R!4$ZZ#<Q(>@,@2'H#5$AL@5!.N@V\2'H#7TAL@5!.N@VP3^\`-$AZ1
XM`XE(>@-_2&R!4$ZZ#9Q/[P`,3-\$`$YU2.<@`"0O``A*@F<.2'H#<DAL@5!.W
XMN@UZ4$\@`F```(Y@``"<2'H#Q4AZ`Y](>`!M2'H#A2\LAOI(>@-;2'H#2DAL/
XM@5!.N@U*3^\`(&!P2'H#R4AL@5!.N@TX4$]@8$AZ!!=(>`#_2'H#YDAX`&Q(8
XM>@/72'H#QTAL@5!.N@T43^\`'&`Z2'H#\TAL@5!.N@T"2'H$`DAL@5!.N@SVM
XM3^\`$&`<_V3_:/^2_Z+_R`R`````!60*T$`P.P#J3OL``$S?``1.=4CG`"`D?
XM;P`(#)(````!;0@,D@```/]O$$AX``-.NO\>)+P````$6$],WP0`3G5(YR`@[
XM)&\`#"\*3KH8I"0`2H)83V\,##(`.BC_9@1P`6`"<`!,WP0$3G4E<R5S)7,@8
XM5F5R<VEO;B`E<R!B>2!$86YI96P@2F%Y($)A<G)E='0N"@`;6S,S;0`;6S!M2
XM`#$N,#$`26YS<&ER960@8GD@5&]M(%-M>71H92=S($92144@;VX@1FES:"!$*
XM:7-K(#8V+@H`5&AI<R!P<F]G<F%M(&ES($9R965L>2!$:7-T<FEB=71A8FQEL
XM+@H*`%5S86=E.B`E<R5S)7,@6RTE8R5C72!;+25C($)95$5372!;+25C($Q%#
XM3D=42%T@6W9O;'5M93%=(%MV;VQU;64R72`N+BX*"@`)+25C.@E$:7-P;&%YF
XM(&)L;V-K<R!I;G-T96%D(&]F(&)Y=&5S+@H`"2TE8SH)16YA8FQE('9O;'5MU
XM92!R97%U97-T;W)S+@H`"2TE8SH)06QL;V-A=&4@0EE415,@;V8@;65M;W)Y5
XM(&9O<B!T:&4@;W5T<'5T+@H`"2TE8SH)4W!E8VEF>2!T:&4@;6%X($Q%3D=4&
XM2"!O9B!A('9O;'5M92!N86UE("@Q("T@)60I+@H`"DEF(&YO('9O;'5M97,@(
XM9VEV96XL('1H92!E;G9I<F]N;65N="``=F%R:6%B;&4@8"5S)R!I<R!U<V5DM
XM+@H`1E)%15]$4DE615,`17AA;7!L93H@('-E=&5N=B`E<R`B9&8P.BQD9C$ZP
XM+')A;3HL9&@P.B(*"@!)9B`E<R!D;V5S(&YO="!E>&ES="P*`'1H96X@=&AET
XM(&9O;&QO=VEN9R!D979I8V5S(&%R92!C:&5C:V5D(&)Y(&1E9F%U;'0Z"@`)`
XM)7,*"@!2040Z+$1&,#HL1$8Q.@!%4E)/4B$@`"5S)60E<R5C)7,E<P!4:&4@[
XM;W5T<'5T(&ES('1O;R!L;VYG('1O(&9I="!I;B``(&)Y=&5S+@I5<V4@=&AEY
XM("T`(&]P=&EO;B!T;R!I;F-R96%S92!M96UO<GD@<VEZ92X*`$]U='!U="!4$
XM4E5.0T%4140@86YD('!O<W-I8FQY(&YO="!A8V-U<F%T92X*"@!#86XG="!A'
XM;&QO8V%T92!T:&%T(&UU8V@@;65M;W)Y(0H`)7,E8R5S)60E<PH`66]U<B`M%
XM`"!V86QU92!M=7-T(&)E(&%N(&EN=&5G97(@8F5T=V5E;B`Q(&%N9"``+@!4:
XM:&ES('-H;W5L9"!N979E<B!H87!P96XA"@!4:&5R92!M=7-T(&)E(&$@8G5GA
XM(&EN('1H:7,@<')O9W)A;2X*`$Y5__Q(YR`@)"T`""1M``Q"K?_\3KH"B`R"L
XM`````F8<2'H"DB\J``1.N@UB2H!03V8*+Q).NOG^6$]@#DAM__PO"B\"81Q/"
XM[P`,0J="IR\M__Q.N@(63^\`#$S?!`1.74YU3E7_Y$CG,#`F+0`()FT`#"1M/
XM`!`O"R\#3KH!.B0`3KH$]B2`""P``8;U4$]F#DAM__A(;?_\3KKXBE!/2&W_%
XM\$AM__1.NO@NM(-03VT2+Q(O+?_P+RW_]&%P3^\`#&`:+Q(O+?_P+RW_]"`"(
XMY8#0BR\`3KH`L$_O`!!([4`,_^0O$DZZ%`)83R8`)!(O`R\"+&R&ZDZN_\0B'
XM`"0?)A\L;(;J3J[_T$SM0`S_Y`@L``&&]68.+RW_^"\M__Q.NO@V4$],WPP,I
XM3EU.=4CG,#(D+P`8)B\`'"QO`"!(>@&'3KKX("9`(`M83V8$)FR``DAZ`7\OG
XM"TZZ!Z@D0%!/(`IG'B\.+P,O`B\*3KH!;DAZ`6%"ITZZ!XHD0$_O`!A@WDS?-
XM3`Q.=4CG,#`D;P`4)"\`&"8O`!PF;P`@2I)G$B\++P,O`B\:3KH!,D_O`!!@&
XMZDS?#`Q.=4CG."`H+P`4)&\`&$AZ`0\O"B\$3KH$I!0`#```_T_O``QG``"&1
XM$`)(@$C`8%P([```AO5@<`CL``&&]6!H".P``H;U+RR`"DZZ#.8F`%A/;P0I.
XM0X;Z8$X([``#AO4O+(`*3KH,S"E`AO9(;(;V3KKYY%!/8#!@+DAX`!1(>``$W
XM0J=A,$_O``Q@'`1``#]GY@1``"-GF`1```IGO%-`9YY;0&>28-)@`/]D("R`4
XM#DS?!!Q.=4CG("`D;P`,)"\`$"`*9P@O"DZZ%HY83TJ"9P@O`DZZ^+Q83R\O?
XM`!1.NAF"6$],WP0$3G5"K(;R*7P```0`AOHI?`````2&]DYU/P!2040Z+$1&1
XM,#HL1$8Q.@!&4D5%7T12259%4P`L`&)L.G)M.@!(YP`P)&\`#"9O`!@O"DZZ2
XM^4Y*@%A/9RY(>@%\+PI.N@'82H!03V82+PLO+P`8+R\`&&$N3^\`#&`*+PLO9
XM"DZZ`,)03V`62'@`.B\*2'H!34AL@5!.N@6F3^\`$$S?#`!.=4Y5^YQ(YS`@E
XM)BT`""0M``PD;0`00J<?/`!D2&W[G$AZ`3M.N@)>+P-(>@$\2'H!+4AZ`2Y(-
XM;?N<2&W\`$ZZ"QY(;?P`+PI.N@&<2H)/[P`N9SH@`]""+P!(>@$,2'H!+DAZT
XM`/XO`DAZ`/Y(>@$;2'H`\$AZ`/=(;?P`3KH*X$AM_``O"DZZ`5Y/[P`P2'H`<
XMRR\*3KH!4%!/3-\$#$Y=3G5.5?N<2.<@("1M``@O"DZZ]$0D``R"_____UA/U
XM9S!(>``!'SP`9$AM^YPO"DZZ`;0O`DAZ`)(O"DAZ`(9(;?N<2&W\`$ZZ"G9/S
XM[P`F8#!(>``!'SP`<TAM^YPO"DZZ`81(>@"02'H`8"\*2'H`5$AM^YQ(;?P`&
XM3KH*1$_O`"9(;?P`+RT`#$ZZ`+Q03TS?!`1.74YU4D%-.@!%4E)/4B$@("(EC
XM<R(@35535"!%3D0@5TE42"`G)6,G+@H`0VAI<``;6S,S;0`;6S!M`"`@("5S7
XM)7,E<R4Q,&QD("`@)7,E<R5S)3EL9`!&87-T`%1O=&%L`"TM``!(YP`P)&\`Z
XM#"9O`!!*$F<Z2A-G-A`22(!(P"\`3KH#REA/+P`0$TB`2,`O`$ZZ`[I83R(?#
XMLH!G"'`!3-\,`$YU($I2BB!+4HM@PG``8.Q(YR`P)&\`$"9O`!1*K(`&9T`O5
XM"DZZ#[(D`"\+3KH/JM""L*R&^E!/9`PO"R\*3KH*&%!/8!Q(>``!3KKUZDJ";
XM6$]O"!6\``HH_V`"0A)"K(`&3-\,!$YU2.<`()7*2JR&^F\0+RR&^DZZ$_HD_
XM0$J`6$]F%$AX`!1(>``"0J=.NOS*3^\`#&`42'H`H"\*3KH4'B`*4$],WP0`#
XM3G5@^$Y5_YQ(YR``%"T`$`P"`&1F$$AZ`'E(;?^<3KH3]%!/8"`,`@!S9A!(9
XM>@!U2&W_G$ZZ$]Y03V`*2'@`!$ZZ]4I83TJM`!)G"$'Z`&8@"&`&0?H`.B`(W
XM+P`@+(;V!H`````*+P`O+0`(3KH.P%A/(A^2@"\!2&W_G"\M``Q.N@A<3^\`\
XM$$S?``1.74YU`"4E<R4E<R4E<R4E)61L9"5S`"4E<R4E<R4E<R4E)61S)7,`T
XM"@!"K(`*("R`#K"O``1L#B\O``PO+P`,80A03TYU</]@^DCG`"`D;P`(("R`7
XM#N6`('((``P0`"UF3"`L@!8B+(`.Y8$@<A@`$#`(`4B`2,`I0(;^9S`,K```K
XM`"V&_F8,4JR`#G#_3-\$`$YU+RR&_DAL@`Y(;(`6+R\`&"\*80I/[P`48.!P7
XM_V#<2.<P,B9O`!@D;P`@+&\`)"0O`"A2DB\"+R\`($ZZ`>8F`%!/9RP@0PPH7
XM`#H``68,+PHO#B\+831/[P`,+PHO#B\+3KH`]"`"3^\`#$S?3`Q.=2\"2'@`+
XM`6%T+PHO#B\+3KH`UG`_3^\`%&#@2.<`,B9O`!`D;P`4+&\`&"`6(A+E@2!SH
XM&`!*,`@!9Q0@$N6`(A;2LP@`*4&`"E*L@`I@)"`2Y8!*LP@$9PX@$N6`*7,("
XM!(`*4I)@#"\LAOY(>``"80Q03T*64I),WTP`3G5(YS``)B\`#"0O`!!*K(`2L
XM9U(,@P````%F&"\L@!HO`DAZ`*I(;(%03KH`YD_O`!!@,@R#`````F88+RR`6
XM'B\"2'H`BDAL@5!.N@#&3^\`$&`2+P)(>@!^2&R!4$ZZ`+)/[P`,3-\`#$YUB
XM2.<`,"1O`!`F;P`4(!,B$N6!(&\`#"!P&`!*,`@!9@12DD*33-\,`$YU26QL\
XM96=A;"!O<'1I;VXN"@!!;B!A<F=U;65N="!I<R!R97%U:7)E9"P@8G5T(&UI&
XM<W-I;F<N"@`M)6,Z("5S`"TE8SH@86X@=6YK;F]W;B!E<G)O<B!O8V-U<G)EN
XM9`H`("\`!`R`````8&,.#(````!Z8@8$@````"!.=4CG("!![P`4)$@O"B\OI
XM`!0O+P`43KH'`B0`(`)/[P`,3-\$!$YU3OH&?DSO`P``!"`(9@P@;(;F2A!F]
XM!'``3G5(YP#`2.<`P$ZZ`%)03TS?`P#0P$H09^0O"$CG`,!.N@`64$]*@&<&+
XM($!"$%*`*4"&YB`?3G4O`DSO`P``""0)$AAG$B)"$!EG]K`!9O@D'U-((`A.O
XM=20?<`!.=2\*3.\#```(8`HD21(:9PBR`&;X$!AF\E.((`B0KP`()%].=2I/U
XM87)#[(+F1>R"YK7)9@XR/`$;:PAT`"+"4<G__"E/AP(L>``$*4Z&[DCG@(`(J
XM+@`$`2EG$$OZ``A.KO_B8`9"I_-?3G-#^@`B3J[^:"E`ANIF#"X\``.`!TZN;
XM_Y1@!BI/3KH`&E!/3G5D;W,N;&EB<F%R>0!)^0``?_Y.=4CG`"`O#B(\``$`,
XM`"\!,"R"W$C`(@#CB-"!XX@B'RQLANY.KO\Z+%\I0(<&9AY(YP$&F\TN/``!+
XM```L;(;N3J[_E$S?8(`N;(<"3G4@;(<&0F@`!"!LAP8Q?``!`!`@;(<&,7P`P
XM`0`*(&R'`B`LAP*0J``$4(`I0(<*(&R'"B"\34%.6"\.D\DL;(;N3J[^VBQ?L
XM)$!*J@"L9S0O+P`,+R\`#"\*3KH`\"E\`````8<.(&R'!EB(`%"``"!LAP;12
XM_`````H`4(``3^\`#&!>+PX@2M'\````7"QLANY.KOZ`+%\O#B!*T?P```!</
XM+&R&[DZN_HPL7RE`AQ(@;(<22J@`)&<B+PX@;(<2(&@`)"(0+&R&ZDZN_X(L4
XM7R\LAQ(O"DZZ`GI03RELAQ*'%B\.+&R&ZDZN_\HL7R!LAP8@@"\.+&R&ZDZN)
XM_\0L7R!LAP8A0``&9R1(YR`")#P```/M0?H`-"((+&R&ZDZN_^),WT`$(&R'Z
XM!B%```PO+(<6+RR'&DZZ]&I03R\`3KH0>%A/3-\$`$YU*@!(YS@R)B\`'"@O/
XM`"`F;P`D($-*J`"L9Q0@0R`H`*SE@"Q`("X`$.6`)$!@!"1L@MX0$DB`2,#0Z
XMA%2`*4"''B\.<@`@+(<>+&R&[DZN_SHL7RE`AR)F!DS?3!Q.=1`22(!(P"0`\
XM+P(@2E*(+P@O+(<B3KH#?DAZ`48@0M'LAR(O"$ZZ#:(O!"\++RR'(DZZ`3`@"
XM;(<B0C`H`"E\`````8<:)$+5[(<B4HHF2D_O`"`0$DB`2,`D``R`````(&<@Y
XM#((````)9Q@,@@````QG$`R"````#6<(#((````*9@12BF#,#!(`(&UV#!(`Z
XM(F8J4HH0&DB`2,`D`&<<%L(,@@```")F$`P2`")F!%**8`9"*___8`)@VF`XX
XM$!I(@$C`)`!G+`R"````(&<D#((````)9QP,@@````QG%`R"````#6<,#((`U
XM```*9P06PF#*0AM*@F8"4XI2K(<:8`#_4D(3+PYR`"`LAQKE@%B`+&R&[DZNK
XM_SHL7RE`AQ9F"$*LAQI@`/[4=``D;(<B8!H@`N6`(&R'%B&*"``O"DZZ!Z+5"
XMP%**6$]2@K2LAQIMX"`"Y8`@;(<60K`(`&``_IP@`$SO`P``!"`((B\`#$H82
XM9OQ3B!#95\G__`2!``$``&KR0B!.=4SO`P``!+/(9PQP`!`8L!E6R/_Z9@1P*
XM`$YU8P1P`4YU</].=4CG,#(L;P`8+PYP`$/Z`,0L;(;N3J[]V"Q?*4"')F8&L
XM3-],#$YU+PX@;P`@(&@`)"!H``0L;(<F3J[_LBQ?)$!*@&=V+PY#^@"7(&H`-
XM-BQLAR9.KO^@+%\D`&=02.<@`B0\```#[2(7+&R&ZDZN_^),WT`$)D!*@&<RS
XM(`OE@"8`($,M:``(`*0M2P"<2.<@`B0\```#[4'Z`$XB""QLANI.KO_B3-]`2
XM!"U``*`O#B!*+&R')DZN_Z8L7R\.(FR')BQLANY.KOYB+%]"K(<F8`#_4&ECJ
XM;VXN;&EB<F%R>0!724Y$3U<`*@!.5?_J2.<@,"1M``A![0`0)D@[?$0(__8KU
XM2O_J*TK_\BM*_^X&K0``?___[B\++RT`#$AM_^I.N@$>)`!",B@`(`)/[P`,L
XM3-\,!$Y=3G5(YS`@)&\`$!`22(`,0``@9PH0$DB`#$``"68$4HI@Z'8`$!)(_
XM@`Q``"UF!G8!4HI@#!`22(`,0``K9@)2BG0`8!H@`B(`Y8C0@>.($AI(@4C!B
XMT($D``2"````,!`22(!![(`C$#```$B`"````F;22H-G!B`"1(!@`B`"3-\$"
XM#$YU3.\#```$(`A*&&;\4T@0V6;\3G4@;P`$<``2+P`+$!BP`5?(__IG!'``!
XM3G532"`(3G5,[P,```0@""(O``Q@`A#95\G__&<,!($``0``:O!.=4(84<G__
XM_`2!``$``&KR3G5(YW``-`'$P"8!2$/&P$A#0D/4@TA`P,%(0$)`T(),WP`.V
XM3G5.5?WT2.<_,B9M``@L;0`0?@`D;0`,%A)F"B`'3-],_$Y=3G52B@P#`"5GM
XM2"0'(%.QZP`$9!`@4U*3$(,"@P```/\@`V`0`H,```#_+P,O"TZZ!.!03PR`#
XM_____V<`!'12@A829@0@`F"R4HH,`P`E9KPN`G@`*WP````@__P6&@*#````&
XM_R`#8&H(Q```8.X(Q``!8.@(Q``"8.((Q``#8-Q8CB0N__Q*@FP&",0``$2"Y
XM%AI@6BM\````,/_\=`!@&B`"YX`"@P```/_0@]""T((D``2"````,!8:`H,`]
XM``#_0>R`(Q`P,`!(@`@```)FT&`<!$``(&><5T!GGE]`9Z!30&>*54!G@%=`#
XM9ZA@KBM"__@D/```?<8,`P`N9F`6&@P#`"IF%%B.)"[__$J";`8D/```?<86T
XM&F`T=`!@&B`"YX`"@P```/_0@]""T((D``2"````,!8:`H,```#_0>R`(Q`P^
XM,`!(@`@```)FT`R"``!]QF<(*WP````@__PJ`@P#`&AF!@C$``=@%@P#`&QFS
XM!@C$``9@"@P#`$QF!@C$``@6&BM*``P"@P```/\@`V```8Y@``,:"`0`!V<*E
XM6(X@;O_\,(=@&`@$``9G"EB.(&[__""'8`A8CB!N__P@AW0`8``!J%B.)&[_I
XM_"\*3KH#""0`#(4``'W&6$]G!K2%;P(D!6```898CA8N__]![?WX)$@0@W0!-
XM8``!<G0(8!``1`!(=GAT$&`&",0`!'0*#`,`6&8(0?H"GB`(8`9!^@*G(`@KF
XM0/WT"`0`!F<(6(XL+O_\8!0(!``$9PA8CBPN__Q@!EB.+"[__`@$``1G"DJ&-
XM;`9$A@C$``5![?_X)$@,A0``?<9F`GH!2H9F!$J%9QPB`B`&3KH%JB!M_?05U
XM,`@`(@(@!DZZ!:8L`&;D0>W_^)'*)`@(!``#9VX,`P!O9A1*@F<*#!(`,&<(M
XMM(5M!"H"4H5@5`P#`'AG!@P#`%AF2$J"9T0,$@`P9SZTA6P00>W]^K'*9`@5J
XM/``P4H)@[`@$``!F'`RM````,/_\9A(@`E2`L*W_^&P(*BW_^%6%8,H5`Q4\O
XM`#!4@K2%;!!![?WXL<ID"!4\`#!2@F#L8$P$0``E9P#^R`1``#-G`/[8!$``@
XM"V<`_K)30&<`_LY;0&<`_LA;0&<`_E!30&<`_JY30&<`_JQ70&<`_FQ50&<`N
XM_JY70&<`_J!@`/XJ"`0`!&<H"`0`!6<&%3P`+6`:"`0``6<&%3P`*V`."`0`5
XM`F<&%3P`(&`"4X)2@MZ""`0``&8``)`,K0```##__&9""`0`!&<\,`0"0``FH
XM9S0@4['K``1D#B!34I,0FG``$"K__V`.<``0&B\`+PM.N@$T4$\,@/____]G&
XM``#(4ZW_^%."8#0@4['K``1D$"!34I,0K?__<``0+?__8!!P`!`M__\O`"\+Q
XM3KH`^E!/#(#_____9P``CE*'("W_^%.M__BP@F[`*@(@`E."2H!G+B!3L>L`C
XM!&0.(%-2DQ":<``0*O__8`YP`!`:+P`O"TZZ`+103PR`_____V=(8,H(!```9
XM9SPD!6`L(%.QZP`$9`X@4U*3$+P`('``<"!@#$AX`"`O"TZZ`'Y03PR`____5
XM_V<24H<@+?_X4ZW_^+"";LA@`/M"</]@`/M&,#$R,S0U-C<X.4%"0T1%1@`PS
XM,3(S-#4V-S@Y86)C9&5F`"!O``0@"$H89OQ32)'`(`A.=4CG`"!![($D)$@O$
XM"DZZ`;A83]7\````%D'L@MRUR&7J3-\$`$YU2.<\("1O`!@H+P`<(`IG``&*G
XM-"H`#&<``8((`@`)9@`!>@@"``-F``%R($K1_`````P"4._]2JH`"&8<#(3_\
XM____9@AP`$S?!#Q.=2\*3KH#*#0J``Q83P@"``YF-"!2L>H`"&,>2'@``2`2!
XMD*H`!"\`$"H`#DB`2,`O`$ZZ!*!/[P`,)*H`""!J`!#1TB5(``0,A/____]F@
XM!'8`8`(6!"`2D*H`""H`,`("0`"@9TX,A/____]G'B!24I(0@R!*T?P````,:
XM"-``!C000?K_#"E(ARI2A0R$_____V<,#`,`"F<&NJH`$&4$>/]@$"52``0"G
XM@P```/\@`V``_TH(`@`.9RQ*A6<<+P4O*@`($"H`#DB`2,`O`$ZZ!,"PA4_OF
XM``QF7B!*T?P````,")``!@R$_____V86)*H`""5J``@`!`*#````_R`#8`#^O
XM^D'Z_HHI2(<J($K1_`````P(T``&)*H`""!J`!#1TB5(``0@4E*2$(,"@P``R
XM`/\@`V``_L8@2M'\````#`CH``(``25J``@`!"2J``AP_V``_JA.5?_V2.<XA
XM("1M``AT`"`*9P9*:@`,9@IP_TS?!!Q.74YU""H``0`,9@HO"DZZ`*2$@%A/;
XM$"H`#DB`2,`O`$ZZ!JB$@`@J````#5A/9PHO*@`(3KH!^%A/2FH`%&=22'H`D
XM;DAM__=.N@*F."H`%'8`4$\"A```__\@!'(*3KH`V@:`````,'('DH-![?_W"
XM$8`8`$C$B?P`"E*##(,````%;=!"+?__2&W_]TZZ`V)83T*20JH`!$*J``A"0
XM:@`,2H)G!G#_8`#_5'``8`#_3E1-4`!(YP`@)&\`""`*9D1![($D)$A*:@`,;
XM9R8P*@`,`D`""&8<2'C__R\*3KK]9`R`_____U!/9@AP_TS?!`!.==7\````H
XM%D'L@MRUR&7&<`!@Z$AX__\O"DZZ_3903V#:2.=(`$*$2H!J!$2`4D1*@6H&6
XM1($*1``!83Y*1&<"1(!,WP`22H!.=4CG2`!"A$J`:@1$@%)$2H%J`D2!81H@>
XM`6#8+P%A$B`!(A]*@$YU+P%A!B(?2H!.=4CG,`!(04I!9B!(038!-`!"0$A`G
XM@,,B`$A`,@*"PS`!0D%(04S?``Q.=4A!)@$B`$)!2$%(0$)`=`_0@-.!MH%B%
XM!)*#4D!1RO_R3-\`#$YU2.<@("1O``QT01`J``Y(@$C`+P!.N@$N2H!83V<",
XM="$E?```!```$$AX!`!.N@"^)4``"%A/9A@E?`````$`$"!*T?P````/)4@`+
XM"#0\`(`@2M'\````#'``,!`R`DC!@($P@"5J``@`!"2J``A,WP0$3G5(YP`P?
XME\LD;(<N8!`@2E"((F\`#+/(9PXF2B12(`IF[$S?#`!.=2`+9P0FDF`$*5*'V
XM+B\.("H`!%"`(DHL;(;N3J[_+BQ?8-A(YP`P)&R'+F`8)E(O#B`J``10@")*(
XM+&R&[DZN_RXL7R1+(`IFY$*LARY,WPP`3G5(YR`@)"\`#$J"9@AP`$S?!`1.Y
XM=2\.<@`@`E"`+&R&[DZN_SHL7R1`2H!F!'``8-Y!^O^>*4B',B2LARXE0@`$:
XM*4J'+B`*4(!@Q$SO`P``!"`($-EF_$YU2.<@("0O``P@`B(`XXC0@>.()$#5P
XM[(<&2H)M##!L@MRQPF\$2I)F$"E\`````X<V</],WP0$3G4O#B`"(@#CB-"!W
XMXX@@;(<&(C`(`"QLANI.KO\H+%]*@&<$<`%@`G``8-!(YS`@)"\`$$ZZ`5X@E
XM`B(`XXC0@>.()$#5[(<&2H)M##!L@MRQPF\$2I)F$"E\`````X<V</],WP0,#
XM3G5(YS`"("\`)%.`)@`D+P`@(A(L;(;J3J[_ODS?0`PF``R`_____V84+PXL`
XM;(;J3J[_?"Q?*4"'-G#_8+Y(YS`"=@!T`"(2+&R&ZDZN_[Y,WT`,8*8O#B(O<
XM``@L;(;J3J[_N"Q?2H!F%"\.+&R&ZDZN_WPL7RE`AS9P_TYU<`!@^DCG,"`D>
XM+P`03KH`HB`"(@#CB-"!XX@D0-7LAP9*@FT,,&R"W+'";P1*DF80*7P````#E
XMAS9P_TS?!`Q.=3`J``0"0``#9@PI?`````:'-G#_8.0(*@`#``1G%DCG,`)VG
XM`70`(A(L;(;J3J[_ODS?0`Q(YS`")B\`)"0O`"`B$BQLANI.KO_03-]`#"8`2
XM#(#_____9A0O#BQLANI.KO]\+%\I0(<V</]@CB`#8(I(YR``+PXB/```$`!P#
XM`"QLANY.KO[.+%\D``@```QG$DJLAPYF""`"3-\`!$YU3KH`!G``8/)(YS`".
XM=@1!^@`N)`@O`R\"+&R&ZDZN_\0B`"0?)A\L;(;J3J[_T$S?0`Q(>``!3KH`V
XM"EA/3G5>0PH`2JR'.F<4(&R'.B!H``1.D"!LASHI4(<Z8.9*K(<J9P8@;(<JF
XM3I`O+P`$3KH`!EA/3G5(YS``)B\`#$JLAP9G-'0`8`HO`DZZ`4I83U*",&R"1
XMW+'";NXO#C`L@MQ(P"(`XXC0@>.((FR'!BQLANY.KO\N+%]*K(<R9P8@;(<RO
XM3I!*K(+B9Q`O#B(L@N(L;(;J3J[_IBQ?2JR'/F<((&R'/B"LAT)*K(=&9Q`O+
XM#B)LAT8L;(;N3J[^8BQ?2JR'2F<0+PXB;(=*+&R&[DZN_F(L7TJLATYG$"\.H
XM(FR'3BQLANY.KOYB+%]*K(=29Q`O#B)LAU(L;(;N3J[^8BQ?2.<`!BQX``0(8
XM+@`$`2EG$$OZ``A.KO_B8`9"I_-?3G,J7TJLAQ)F-$JLAR)G+"\.("R''B)L_
XMAR(L;(;N3J[_+BQ?+PX@+(<:Y8!8@")LAQ8L;(;N3J[_+BQ?8!PO#BQLANY..
XMKO]\+%\O#B)LAQ(L;(;N3J[^ABQ?+PXB;(;J+&R&[DZN_F(L7R`#+FR'`DYUF
XM3-\`#$YU2.<@("0O``P@`B(`XXC0@>.()$#5[(<&2H)M##!L@MRQPF\$2I)F,
XM$"E\`````X<V</],WP0$3G4P*@`$`D"``&8.+PXB$BQLANI.KO_<+%]"DG``-
XM8-P``````^P````!`````0``$>(````````#\@```^H```"Y```*B@````$`0
XM`````````0````$````````0+@``$#\`("`@("`@("`@,#`P,#`@("`@("`@_
XM("`@("`@("`@(""00$!`0$!`0$!`0$!`0$!`#`P,#`P,#`P,#$!`0$!`0$`)Q
XM"0D)"0D!`0$!`0$!`0$!`0$!`0$!`0$!`4!`0$!`0`H*"@H*"@("`@("`@("-
XM`@("`@("`@("`@("0$!`0"``````````````````````````````````````X
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM```````````````````````````````"`````````0``````````````````#
XM!``!``````$```````````````````0``@`````!````````````````````-
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM```4``````````````/L`````P``````````````&````!P````````#\@``O
X*`^L````!```#\@``D
X``
Xend
Xsize 10540
END_OF_FILE
if test 14794 -ne `wc -c <'Free.uu'`; then
    echo shar: \"'Free.uu'\" unpacked with wrong size!
fi
# end of 'Free.uu'
fi
if test ! -d 'Source' ; then
    echo shar: Creating directory \"'Source'\"
    mkdir 'Source'
fi
if test -f 'Source/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/Makefile'\"
else
echo shar: Extracting \"'Source/Makefile'\" \(830 characters\)
sed "s/^X//" >'Source/Makefile' <<'END_OF_FILE'
X#############################################################################
X# Makefile for FREE2 by Daniel Barrett.
X# Intended for Manx Aztec C version 5.0a.
X#############################################################################
X
XPROGRAM		= free
XSRC		= dos.c env.c errors.c getopt.c main.c output.c strings.c
XOBJ		= dos.o env.o errors.o main.o output.o strings.o
XFREEOBJ		= $(OBJ) getopt.o
XINC		= free.h
XCOMP_INC	= headers.comp
XLIBS		= -lc
XOPTIMIZE	= -so
XDEBUGGING	= 
XCFLAGS		= $(OPTIMIZE) -hi $(COMP_INC) $(DEBUGGING)
XLFLAGS		= +Q 
X
X$(PROGRAM):	$(COMP_INC) $(FREEOBJ)
X		ln $(LFLAGS) $(FREEOBJ) -o $(PROGRAM) $(LIBS)
X
X$(COMP_INC):	free.h
X		cc $(OPTIMIZE) -ho $(COMP_INC) free.h
X
X$(OBJ):		$(INC)
X
Xgetopt.o:	getopt.c
X		cc $(OPTIMIZE) $(DEBUGGING) getopt.c -o getopt.o
X
Xclean:
X		delete $(FREEOBJ) $(COMP_INC) $(PROGRAM).dbg
END_OF_FILE
if test 830 -ne `wc -c <'Source/Makefile'`; then
    echo shar: \"'Source/Makefile'\" unpacked with wrong size!
fi
chmod +x 'Source/Makefile'
# end of 'Source/Makefile'
fi
if test -f 'Source/dos.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/dos.c'\"
else
echo shar: Extracting \"'Source/dos.c'\" \(2287 characters\)
sed "s/^X//" >'Source/dos.c' <<'END_OF_FILE'
X/***************************************************************************
X * dos.c:	AmigaDOS and Requestor related functions.
X *
X * Part of...
X *
X *	FREE:	Display free space on your disk volumes.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X***************************************************************************/
X
X
X#include "free.h"
X
X/* Given a disk volume name, return how much space is on it.  The units
X * of space are either bytes or blocks, depending on whether the user
X * specified the option OPT_BLOCKS or not. */
X
Xlong GetMem(char *volume)
X{
X	long freeSpace;
X	struct FileLock *lock;
X
X	lock = NULL;
X	if (lock = (struct FileLock *)Lock(volume, ACCESS_READ))
X	{
X		freeSpace = AvailSpace(lock);
X		UnLock((BPTR)lock);
X	}
X	else
X		freeSpace = NO_DRIVE;
X	return(freeSpace);
X}
X
X
X/* This function comes from Tom Smythe's "avail()" function.
X * Given a lock on a disk, calculate how much space is left on the disk
X * and return that value.  The value is in bytes, by default; but if the
X * user specified the option OPT_BLOCKS on the command-line, it's in 
X * blocks. */
X
Xlong AvailSpace(struct FileLock *disk)
X{
X	struct InfoData *info;
X	long answer = 0L;
X
X	info = AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC);
X	Info((BPTR)disk, info);
X	answer = (info->id_NumBlocks - info->id_NumBlocksUsed);
X	if (!(flags & FLAG_BLOCKS))
X		answer *= info->id_BytesPerBlock;
X	FreeMem(info, (long)sizeof(struct InfoData));
X	return(answer);
X}
X
X
X/* Return the amount of free RAM on the system, broken into CHIP and
X * FAST RAM. */
X
Xvoid GetFreeRam(long *chip, long *fast)
X{
X	(*chip) = (*fast) = 0L;
X	Forbid();
X	*chip = AvailMem(MEMF_CHIP);
X	*fast = AvailMem(MEMF_FAST);
X	Permit();
X}
X
X
X/* Turn off system requestors for this process. */
X
Xvoid DisableRequestors(struct Process **proc, APTR *oldWindowPtr)
X{
X	*proc = (struct Process *)FindTask(NULL);
X	*oldWindowPtr = (*proc)->pr_WindowPtr;
X	(*proc)->pr_WindowPtr = (APTR)(-1L);
X}
X
X
X/* Turn on system requestors for this process, after they have been
X * turned off by DisableRequestors(), above. */
X
Xvoid EnableRequestors(struct Process *proc, APTR oldWindowPtr)
X{
X	proc->pr_WindowPtr = oldWindowPtr;
X}
X
X
END_OF_FILE
if test 2287 -ne `wc -c <'Source/dos.c'`; then
    echo shar: \"'Source/dos.c'\" unpacked with wrong size!
fi
chmod +x 'Source/dos.c'
# end of 'Source/dos.c'
fi
if test -f 'Source/env.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/env.c'\"
else
echo shar: Extracting \"'Source/env.c'\" \(1723 characters\)
sed "s/^X//" >'Source/env.c' <<'END_OF_FILE'
X/***************************************************************************
X * env.c:	Environment variable functions.
X *
X * Part of...
X *
X *	FREE:	Display free space on your disk volumes.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X***************************************************************************/
X
X#include "free.h"
X
X/* Return the value of ENV: environment variable "variableName", if it
X * exists. */
X
Xchar *GetEnv(char *variableName)
X{
X	char envVar[ENV_NAME_LENGTH];
X	BPTR fileHandle;
X
X	sprintf(envVar, "ENV:%s", variableName);
X	if ((fileHandle = Open(envVar, MODE_OLDFILE)) == 0)
X		return(NULL);
X	else
X		return(TheEnvValue(fileHandle));
X}
X
X
X/* Given a fileHandle on an environment variable, read the "file" and
X * find the value of the variable.
X * As far as I can tell, the value may have some garbage (control)
X * characters after it.  I make sure to put a null ('\0') in place of
X * the first such control character (if any).
X *
X * If the value is too large (>= BUFSIZ-1), then we can't handle it.
X * Return NULL.
X * Otherwise, terminate the value with a null and return a pointer to
X * it.  We use a static array for this. */
X	
Xchar *TheEnvValue(BPTR fileHandle)
X{
X	static char envString[BUFSIZ];
X	int numChars;
X
X	numChars = 0;
X
X	if (Read(fileHandle, envString, (long)sizeof(envString)) > 0)
X	{
X		envString[BUFSIZ-1] = '\0';	/* Terminate for safety. */
X		while (envString[numChars] >= ' ')
X			numChars++;
X		if (numChars < sizeof(envString)-1)
X			envString[numChars] = '\0';
X		else
X			numChars = 0;
X	}
X	Close(fileHandle);
X	return(numChars ? envString : NULL);
X}
END_OF_FILE
if test 1723 -ne `wc -c <'Source/env.c'`; then
    echo shar: \"'Source/env.c'\" unpacked with wrong size!
fi
chmod +x 'Source/env.c'
# end of 'Source/env.c'
fi
if test -f 'Source/errors.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/errors.c'\"
else
echo shar: Extracting \"'Source/errors.c'\" \(3248 characters\)
sed "s/^X//" >'Source/errors.c' <<'END_OF_FILE'
X/***************************************************************************
X * errors.c:	Error-handling functions.
X *
X * Part of...
X *
X *	FREE:	Display free space on your disk volumes.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X***************************************************************************/
X
X#include "free.h"
X
X/* The user made a mistake in invoking the program.  Give 'em hell. */
X
Xvoid Usage(char *prog)
X{
X	fprintf(stderr, "%s%s%s Version %s by Daniel Jay Barrett.\n",
X		HI_ON, prog, HI_OFF, VERSION);
X	fprintf(stderr, "Inspired by Tom Smythe's FREE on Fish Disk 66.\n");
X	fprintf(stderr, "This program is Freely Distributable.\n\n");
X
X	fprintf(stderr,
X"Usage: %s%s%s [-%c%c] [-%c BYTES] [-%c LENGTH] [volume1] [volume2] ...\n\n",
X	   HI_ON, prog, HI_OFF, OPT_BLOCKS, OPT_REQUESTORS, OPT_MALLOC,
X	   OPT_VOLUME_NAME_LEN);
X
X	fprintf(stderr, "\t-%c:\tDisplay blocks instead of bytes.\n",
X		OPT_BLOCKS);
X	fprintf(stderr, "\t-%c:\tEnable volume requestors.\n", OPT_REQUESTORS);
X	fprintf(stderr, "\t-%c:\tAllocate BYTES of memory for the output.\n",
X		OPT_MALLOC);
X	fprintf(stderr,
X	   "\t-%c:\tSpecify the max LENGTH of a volume name (1 - %d).\n",
X	   OPT_VOLUME_NAME_LEN, MAX_NAME_LEN);
X	
X	fprintf(stderr, "\nIf no volumes given, the environment ");
X	fprintf(stderr, "variable `%s' is used.\n", ENV_VARIABLE);
X	fprintf(stderr, "Example:  setenv %s \"df0:,df1:,ram:,dh0:\"\n\n",
X		ENV_VARIABLE);
X
X	fprintf(stderr, "If %s does not exist,\n", ENV_VARIABLE);
X	fprintf(stderr, "then the following devices are checked by default:\n");
X	fprintf(stderr, "\t%s\n\n", DEFAULT_VOLUMES);
X}
X
X
X/* Given a particular error code, print the appropriate error message. */
X
Xvoid ErrorMsg(ERROR code)
X{
X	if (code)
X		fprintf(stderr, "ERROR! ");
X	switch (code)
X	{
X		case NO_ERROR:
X			break;
X		case ERROR_TOO_SMALL:
X			fprintf(stderr,
X			   "%s%d%s%c%s%s",
X			   "The output is too long to fit in ",
X			   memSize, " bytes.\nUse the -", OPT_MALLOC,
X			   " option to increase memory size.\n",
X			   "Output TRUNCATED and possibly not accurate.\n\n");
X			break;
X		case ERROR_CANT_MALLOC:
X			fprintf(stderr, "Can't allocate that much memory!\n");
X			break;
X		case ERROR_FORMAT_STRING:
X			fprintf(stderr, "%s%c%s%d%s\n",
X				"Your -", OPT_VOLUME_NAME_LEN,
X				 " value must be an integer between 1 and ",
X				MAX_NAME_LEN, ".");
X			break;
X		case ERROR_IMPOSSIBLE:
X		   fprintf(stderr, "This should never happen!\n");
X		   fprintf(stderr, "There must be a bug in this program.\n");
X		   break;
X	}
X}
X
X
X/* If the user specified an illegal value (0 or less) as the argument of
X * the option OPT_VOLUME_NAME_LEN, complain!  Then use the default value. */
X
Xvoid CheckVolumeNameLen(int *nameLen)
X{
X	if (*nameLen < 1 || *nameLen > MAX_NAME_LEN)
X	{
X		ErrorMsg(ERROR_FORMAT_STRING);
X		*nameLen = DEFAULT_NAME_LEN;
X	}
X}
X
X
X/* If the user specified an invalid volume name, complain!  A valid name
X * must have at least 1 character (really two, but...), and its last
X * character must be VOLUME_END_CHAR. */
X
Xint ValidDriveName(char *drive)
X{
X	int len = strlen(drive);
X
X	return((len > 0)  &&  (drive[len-1] == VOLUME_END_CHAR));
X}
END_OF_FILE
if test 3248 -ne `wc -c <'Source/errors.c'`; then
    echo shar: \"'Source/errors.c'\" unpacked with wrong size!
fi
chmod +x 'Source/errors.c'
# end of 'Source/errors.c'
fi
if test -f 'Source/free.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/free.h'\"
else
echo shar: Extracting \"'Source/free.h'\" \(3822 characters\)
sed "s/^X//" >'Source/free.h' <<'END_OF_FILE'
X/***************************************************************************
X * free.h:	Header file with definitions.
X *
X * Part of...
X *
X *	FREE:	Display free space on your disk volumes.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X***************************************************************************/
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <ctype.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <functions.h>
X
X
X/* Macros dealing with environment variables. */
X
X#define	ENV_SEPARATOR		","
X#define ENV_VARIABLE		"FREE_DRIVES"
X#define	ENV_NAME_LENGTH		256
X#define	VOLUME_END_CHAR		':'
X#define	DEFAULT_VOLUMES		"RAD:,DF0:,DF1:"
X
X/* Macros dealing with output. */
X
X#define	HI_ON			"\033[33m"	/* Turn on highlighting. */
X#define	HI_OFF			"\033[0m"	/* Turn off highlighting. */
X#define	NONE			"--"		/* Drive is empty. */
X#define	NO_DRIVE		(-1L)		/* Volume does not exist. */
X#define	VERSION			"1.01"		/* Version of this program. */
X
X/* Macros representing default and maximum sizes of things. */
X
X#define	DEFAULT_MEMORY_LIMIT	BUFSIZ	/* Memory allocated for output. */
X#define	DEFAULT_SPACING		10	/* Space to print free memory. */
X#define	DEFAULT_NAME_LEN	4	/* Default length of a volume name. */
X#define MAX_NAME_LEN		255	/* Maximum length of a volume name. */
X
X/* Macros for MakeFormatString(). */
X
X#define	CR			1	/* Print a carriage return. */
X#define	NO_CR			0	/* Do not print a carriage return. */
X#define	FORMAT_LENGTH		100	/* Space to store a format string. */
X
X/* Macros for command-line options. */
X
X#define	FLAG_BLOCKS		(1     )
X#define	FLAG_REQUESTORS		(1 << 1)
X#define	FLAG_MALLOC		(1 << 2)
X#define	FLAG_VOLUME_NAME_LEN	(1 << 3)
X
X#define	OPT_BLOCKS		'b'
X#define	OPT_VOLUME_NAME_LEN	'l'
X#define	OPT_REQUESTORS		'r'
X#define	OPT_MALLOC		'm'
X#define	OPT_UNKNOWN		'?'
X
X#define	HELP_ARG		"?"
X
X/* Human-readable names for our error codes. */
X
X#define	NO_ERROR		0
X#define	ERROR_TOO_SMALL		1
X#define	ERROR_CANT_MALLOC	2
X#define	ERROR_FORMAT_STRING	3
X#define	ERROR_IMPOSSIBLE	4
X
Xtypedef	int ERROR;
X
X/* Miscellaneous macros. */
X
X#define	EQUAL			!strcmp
X
X/* Our global variables. */
X
Xlong	flags;			/* Bit mask for user's options. */
Xint	memSize;		/* Maximum number of bytes in the output. */
Xint	volumeNameLen;		/* Length of longest volume name. */
X
X/* Defines, global variables, and function prototype for getopt(). */
X
X#define	OPTSTRING		"bl:rm:"
Xextern char *optarg;
Xextern int optind, opterr, optopt;
Xint getopt(int argc, char *argv[], const char *optString);
X
X/* Function prototypes, in alphabetical order. */
X
Xlong	AvailSpace(struct FileLock *disk);	
Xvoid	CheckVolumeNameLen(int *nameLen);
Xint	Concat(char s1[], char s2[]);
Xvoid	DisableRequestors(struct Process **proc, APTR *oldWindowPtr);
Xvoid	DoFree(int argc, char *argv[], char **out);
Xvoid	DoNormalDrive(char *volume, char out[]);
Xvoid	EnableRequestors(struct Process *proc, APTR oldWindowPtr);
Xvoid	ErrorMsg(ERROR err);
Xvoid	ExitCleanly(char *arr, ERROR error, int code);
Xvoid	FreeFromArgs(char *argv[], long chip, long fast, char out[]);
Xvoid	FreeUsingEnv(long chip, long fast, char out[]);
Xchar *	GetEnv(char *envVariable);
Xvoid	GetFreeRam(long *chipRam, long *fastRam);
Xlong	GetMem(char *drive);
Xint	GetOptions(int argc, char *argv[]);
Xvoid	InitializeGlobals(void);
Xvoid	MakeFormatString(char *volume, char format[], char d_or_s, int cr);
Xchar *	MakeOutArray(void);
Xvoid	ShowFree(char *volume, long chipRam, long fastRam, char out[]);
Xvoid	ShowFreeRam(long chip, long fast, char out[]);
Xint	StrCaseCmp(char *s1, char *s2);
Xchar *	TheEnvValue(BPTR fileh);
Xvoid	Usage(char *prog);
Xint	ValidDriveName(char *drive);
END_OF_FILE
if test 3822 -ne `wc -c <'Source/free.h'`; then
    echo shar: \"'Source/free.h'\" unpacked with wrong size!
fi
chmod +x 'Source/free.h'
# end of 'Source/free.h'
fi
if test -f 'Source/getopt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/getopt.c'\"
else
echo shar: Extracting \"'Source/getopt.c'\" \(6121 characters\)
sed "s/^X//" >'Source/getopt.c' <<'END_OF_FILE'
X/****************************************************************************
X * getopt():	Return the next user option on each iteration. 
X *		This is a clone of the usual UNIX getopt() function.
X *		If you have never used a getopt() before, you'll have to
X * 		 read about it on any UNIX machine or other C system that
X * 		 documents it.
X *
X * Author:	Daniel Barrett, barrett@cs.jhu.edu.
X * Date:	April 12, 1990.
X * Version:	1.0.
X *
X * License:	This code is placed in the Public Domain.
X *		Give it away to anybody for free!
X *		Use it for any purpose you like!
X *
X *		If you use this code in a program, please give me credit
X *		for my work.  Thanks!
X *
X * Why I wrote it:
X *
X *		Because every other getopt() function I have ever seen
X *		 had source code that was difficult to understand.
X *		I wrote this code to be very modular and readable.
X *		I hope you find it instructive and/or helpful.
X *
X ****************************************************************************/
X
X#ifndef __STDIO_H	/* If we haven't already included stdio.h, do it. */
X#include <stdio.h>	/* Maybe someday I'll eliminate this. */
X#endif
X
X/************************************************************************
X* Some constants.
X************************************************************************/
X
X#define	DASH		'-'	/* This preceeds an option. */
X#define	ARG_COMING	':'	/* In the option string, this indicates that
X				 * that the option requires an argument. */
X#define	UNKNOWN_OPT	'?'	/* The char returned for unknown option. */
X
X/************************************************************************
X* Internal error codes.
X************************************************************************/
X
X#define	ERROR_BAD_OPTION	1
X#define	ERROR_MISSING_ARGUMENT	2
X
X/************************************************************************
X* ANSI function prototypes.
X************************************************************************/
X
Xint		getopt(int argc, char *argv[], char *optString);
Xstatic int	g_NextOption(char *argv[], char *optString);
Xstatic int	g_RealOption(char *argv[], char *str, int *skip, int *ind,
X			     int opt);
Xstatic void	g_HandleArgument(char *argv[], int *optind, int *skip);
Xstatic void	g_Error(int err, int c);
Xstatic void	g_Pass(char *argv[], int *optind, int *optsSkipped);
X
Xextern char	*index();
X
X/************************************************************************
X* Global variables.  You must declare these externs in your program
X* if you want to see their values!
X************************************************************************/
X	
Xchar	*optarg	= NULL;	/* This will point to a required argument, if any. */
Xint	optind	= 1;	/* The index of the next argument in argv. */
Xint	opterr	= 1;	/* 1 == print internal error messages.  0 else. */
Xint	optopt;		/* The actual option letter that was found. */
X
X
Xint getopt(int argc, char *argv[], char *optString)
X{
X	optarg = NULL;
X	if (optind < argc)		/* More arguments to check. */
X		return(g_NextOption(argv, optString));
X	else				/* We're done. */
X		return(EOF);
X}
X
X
X/* If the current argument does not begin with DASH, it is not an option.
X * Return EOF.
X * If we have ONLY a DASH, and nothing after it... return EOF as well.
X * If we have a DASH followed immediately by another DASH, this is the
X * special "--" option that means "no more options follow."  Return EOF.
X * Otherwise, we have an actual option or list of options.  Process it. */
X	
Xstatic int g_NextOption(char *argv[], char *optString)
X{
X	static int optsSkipped = 0;	/* In a single argv[i]. */
X	
X	if ((argv[optind][0] == DASH)
X	&&  ((optopt = argv[optind][1+optsSkipped]) != '\0'))
X	{
X		if (optopt == DASH)
X		{
X			optind++;
X			return(EOF);
X		}
X		else
X			return(g_RealOption(argv, optString, &optsSkipped,
X					    &optind, optopt));
X	}
X	else
X		return(EOF);
X}
X
X
X/* At this point, we know that argv[optind] is an option or list of
X * options.  If this is a list of options, *optsSkipped tells us how
X * many of those options have ALREADY been parsed on previous calls
X * to getopt().
X * If the option is not legal (not in optString), complain and return
X * UNKNOWN_OPT.
X * If the option requires no argument, just return the option letter.
X * If the option requires an argument, call g_HandleArgument and return
X * the option letter. */
X	
Xstatic int g_RealOption(char *argv[], char *optString, int *optsSkipped,
X			int *optind, int optopt)
X{
X	char *where;
X
X	(*optsSkipped)++;
X	if (where = index(optString, optopt))
X	{
X		if (*(where+1) == ARG_COMING)
X			g_HandleArgument(argv, optind, optsSkipped);
X
X		g_Pass(argv, optind, optsSkipped);
X		return(optopt);
X	}
X	else
X	{
X		g_Error(ERROR_BAD_OPTION, optopt);
X		g_Pass(argv, optind, optsSkipped);
X		return(UNKNOWN_OPT);
X	}
X}
X
X
X/* We have an option in argv[optind] that requires an argument.  If there
X * is no whitespace after the option letter itself, take the rest of
X * argv[optind] to be the argument.
X * If there IS whitespace after the option letter, take argv[optind+1] to
X * be the argument.
X * Otherwise, if there is NO argument, complain! */
X
Xstatic void g_HandleArgument(char *argv[], int *optind, int *optsSkipped)
X{
X	if (argv[*optind][1+(*optsSkipped)])
X		optarg = argv[*optind] + 1 + (*optsSkipped);
X	else if (argv[(*optind)+1])
X	{
X		optarg = argv[(*optind)+1];
X		(*optind)++;
X	}
X	else
X		g_Error(ERROR_MISSING_ARGUMENT, optopt);
X
X	(*optsSkipped) = 0;
X	(*optind)++;
X}
X
X
X/* Print an appropriate error message. */
X
Xstatic void g_Error(int err, int c)
X{
X	static char *optmsg = "Illegal option.\n";
X	static char *argmsg = "An argument is required, but missing.\n";
X
X	if (opterr)
X	{
X		if (err == ERROR_BAD_OPTION)
X			fprintf(stderr, "-%c: %s", c, optmsg);
X		else if (err == ERROR_MISSING_ARGUMENT)
X			fprintf(stderr, "-%c: %s", c, argmsg);
X
X		else	/* Sanity check! */
X			fprintf(stderr, "-%c: an unknown error occurred\n",
X				c);
X	}
X}
X
X
X/* We have reached the end of argv[optind]... there are no more options
X * in it to parse.  Skip to the next item in argv. */
X
Xstatic void g_Pass(char *argv[], int *optind, int *optsSkipped)
X{
X	if ( !(argv[*optind][1+(*optsSkipped)]) )
X	{
X		(*optind)++;
X		(*optsSkipped) = 0;
X	}
X}
END_OF_FILE
if test 6121 -ne `wc -c <'Source/getopt.c'`; then
    echo shar: \"'Source/getopt.c'\" unpacked with wrong size!
fi
chmod +x 'Source/getopt.c'
# end of 'Source/getopt.c'
fi
if test -f 'Source/main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/main.c'\"
else
echo shar: Extracting \"'Source/main.c'\" \(4717 characters\)
sed "s/^X//" >'Source/main.c' <<'END_OF_FILE'
X/***************************************************************************
X * FREE:	Display free space on your disk devices.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *		Inspired by "FREE" by Tom Smythe on Fred Fish Disk #66,
X *		 but totally rewritten.  One function, AvailSpace(), is an
X *		 updated version of Smythe's function avail().
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X *
X * Changes/Improvements over Tom Smythe's program are:
X *
X *	o	Does not use self-modifying code, so it should work on
X *		ALL Amigas, not just 68000-based systems.
X *	o	You can specify a device list on the command line.
X *	o	You can specify a device list using a Manx/ARP environment
X *		variable.
X *	o	Requestors are turned off, so non-mounted devices are just
X *		skipped.  (See -m option.)
X *	o	Data is written in correct columns, regardless of the 
X *		lengths of the volume names.  (See -l option.)
X *	o	Total memory free is shown, along with CHIP and FAST
X *		subtotals.
X *	o	Command-line options added so the user can customize the
X *		program.
X *	o	Written in ANSI C, in a modular and easy-to-read style.
X *
X * Daniel Jay Barrett makes no claims about the suitability of this program
X * for any particular purpose.  Any damages incurred through the use of
X * this program are entirely the responsibility of the USER.  Use at your
X * own risk.  So there!   :-)
X *
X ***************************************************************************/
X
X#include "free.h"
X	
Xmain(int argc, char *argv[])
X{
X	char *outArray = NULL;
X
X	InitializeGlobals();
X
X	if ((argc == 2) && (EQUAL(argv[1], HELP_ARG)))
X		Usage(argv[0]);
X	else
X		DoFree(argc, argv, &outArray);
X
X	ExitCleanly(outArray, NO_ERROR, RETURN_OK);
X}
X
X
X/* Process the user's command-line options.
X * Allocate the out[] array for output.
X * Disable requestors, if necessary.
X * Measure the available RAM.
X * Then, measure free space on each desired device. 
X * Print the output in a quick manner, using Write().
X * Turn requestors back on, if they were turned off.
X */
X
Xvoid DoFree(int argc, char *argv[], char **out)
X{
X	struct Process *proc;
X	APTR oldWindowPtr;
X	long chipRam, fastRam;
X	int argIndex;
X
X	argIndex = GetOptions(argc, argv);
X	*out = MakeOutArray();
X
X	if (!(flags & FLAG_REQUESTORS))
X	 	DisableRequestors(&proc, &oldWindowPtr);
X
X	GetFreeRam(&chipRam, &fastRam);
X
X	if (argIndex >= argc)
X		FreeUsingEnv(chipRam, fastRam, *out);
X	else
X		FreeFromArgs(argv+argIndex, chipRam, fastRam, *out);
X
X	Write(Output(), *out, (long)strlen(*out));	/* For speed. */
X
X	if (!(flags & FLAG_REQUESTORS))
X	 	EnableRequestors(proc, oldWindowPtr);
X}
X
X
X/* The user specified no volumes as command-line arguments.  So, check
X * the environment variable.  If it has no value, then use DEFAULT_VOLUMES
X * instead.
X * We use the WONDERFUL function strtok() iteratively, to get the name of
X * each volume, one at a time. */
X
Xvoid FreeUsingEnv(long chipRam, long fastRam, char out[])
X{
X	static char *defaultVolumes = DEFAULT_VOLUMES;
X	char *volume, *volumeList;
X	
X	volumeList = GetEnv(ENV_VARIABLE);
X	if (!volumeList)
X		volumeList = defaultVolumes;
X
X	volume = strtok(volumeList, ENV_SEPARATOR);
X	while (volume)
X	{
X		ShowFree(volume, chipRam, fastRam, out);
X		volume = strtok(NULL, ENV_SEPARATOR);
X	}
X}
X
X
X/* The user specified volumes on the command-line.  Check each one. */
X
Xvoid FreeFromArgs(char *argv[], long chipRam, long fastRam, char out[])
X{
X	while (*argv)
X		ShowFree(*argv++, chipRam, fastRam, out);
X}
X
X
X/* Process the user's command-line options.
X * Return the index of the first argument appearing AFTER all options. */
X
Xint GetOptions(int argc, char *argv[])
X{
X	register char c;
X	long m;
X
X	while ((c = getopt(argc, argv, OPTSTRING)) != EOF)
X	{
X		switch (c)
X		{
X			case OPT_BLOCKS:
X				flags |= FLAG_BLOCKS;
X				break;
X			case OPT_REQUESTORS:
X				flags |= FLAG_REQUESTORS;
X				break;
X			case OPT_MALLOC:
X				flags |= FLAG_MALLOC;
X				if ((m = atoi(optarg)) > 0)
X					memSize = m;
X				break;
X			case OPT_VOLUME_NAME_LEN:
X				flags |= FLAG_VOLUME_NAME_LEN;
X				volumeNameLen = atoi(optarg);
X				CheckVolumeNameLen(&volumeNameLen);
X				break;
X			case OPT_UNKNOWN:
X				break;
X			default:	/* Sanity check! */
X				ExitCleanly((char *)NULL, ERROR_IMPOSSIBLE,
X					    RETURN_FAIL);
X				break;
X		}
X	}
X	return(optind);
X}
X
X
X/* Deallocate memory, print a message, and exit. */
Xvoid ExitCleanly(char *arr, ERROR errorCode, int exitCode)
X{
X	if (arr)
X		free(arr);
X	if (errorCode)
X		ErrorMsg(errorCode);
X	exit(exitCode);
X}
X
X
X/* Like the name says... initialize our global variables. */
X
Xvoid InitializeGlobals()
X{
X	flags		= 0L;
X	memSize		= DEFAULT_MEMORY_LIMIT;
X	volumeNameLen	= DEFAULT_NAME_LEN;
X}
END_OF_FILE
if test 4717 -ne `wc -c <'Source/main.c'`; then
    echo shar: \"'Source/main.c'\" unpacked with wrong size!
fi
chmod +x 'Source/main.c'
# end of 'Source/main.c'
fi
if test -f 'Source/output.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/output.c'\"
else
echo shar: Extracting \"'Source/output.c'\" \(2224 characters\)
sed "s/^X//" >'Source/output.c' <<'END_OF_FILE'
X/***************************************************************************
X * output.c:	Functions for printing the output.
X *
X * Part of...
X *
X *	FREE:	Display free space on your disk volumes.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X***************************************************************************/
X
X#include "free.h"
X
X/* Show the amount of free space on the volume. */
X
Xvoid ShowFree(char *volume, long chipRam, long fastRam, char out[])
X{
X	if (ValidDriveName(volume))
X	{
X		if (!StrCaseCmp(volume, "RAM:"))
X			ShowFreeRam(chipRam, fastRam, out);
X		else
X			DoNormalDrive(volume, out);
X	}
X	else
X		fprintf(stderr, "ERROR!  \"%s\" MUST END WITH '%c'.\n",
X			volume, VOLUME_END_CHAR);
X}
X
X
X/* Copy "free RAM" information into the buffer "out[]".  We use
X * MakeFormatString() to make sure that the CHIP RAM amount is
X * properly indented to match other output... and then just hack
X * the FAST RAM and TOTAL RAM values onto the end.  If you have no FAST
X * RAM, you won't see these last two values. */
X
Xvoid ShowFreeRam(long chip, long fast, char out[])
X{
X	char tmp[BUFSIZ];	/* This should hold 1 line of output... */
X	char formatString[FORMAT_LENGTH];
X
X	MakeFormatString("Chip", formatString, 'd', NO_CR);
X	sprintf(tmp, formatString, HI_ON, "Chip", HI_OFF, chip);
X	Concat(out, tmp);
X
X	if (fast)
X	{
X		sprintf(tmp, "   %s%s%s%10ld   %s%s%s%9ld",
X			HI_ON, "Fast", HI_OFF, fast,
X	   		HI_ON, "Total", HI_OFF, chip+fast);
X		Concat(out, tmp);
X	}
X
X	Concat(out, "\n");
X}
X
X
X/* Find the free space on a normal disk drive, and append it to the
X * buffer "out[]".  We use MakeFormatString() for matching indenting. */
X
Xvoid DoNormalDrive(char *volume, char out[])
X{
X	long mem;
X	char tmp[BUFSIZ];	/* This should hold 1 line of output... */
X	char formatString[FORMAT_LENGTH];
X
X	mem = GetMem(volume);
X
X	if (mem != NO_DRIVE)
X	{
X		MakeFormatString(volume, formatString, 'd', CR);
X		sprintf(tmp, formatString, HI_ON, volume, HI_OFF, mem);
X	}
X	else
X	{
X		MakeFormatString(volume, formatString, 's', CR);
X		sprintf(tmp, formatString, HI_ON, volume, HI_OFF, NONE);
X		}
X	Concat(out, tmp);
X}
END_OF_FILE
if test 2224 -ne `wc -c <'Source/output.c'`; then
    echo shar: \"'Source/output.c'\" unpacked with wrong size!
fi
chmod +x 'Source/output.c'
# end of 'Source/output.c'
fi
if test -f 'Source/strings.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Source/strings.c'\"
else
echo shar: Extracting \"'Source/strings.c'\" \(2929 characters\)
sed "s/^X//" >'Source/strings.c' <<'END_OF_FILE'
X/***************************************************************************
X * strings.c:	Miscellaneous string functions.
X *
X * Part of...
X *
X *	FREE:	Display free space on your disk volumes.
X *		Author:  Daniel Jay Barrett, barrett@cs.jhu.edu.
X *
X * This program is Freely Distributable.  Make all the copies you want
X * and give them away.  Use this code in any way you like.
X***************************************************************************/
X
X#include "free.h"
X
X/* Compare two strings, ignoring the difference between upper/lower case.
X * If the strings are the same, return 0; else, return 1. */
X
Xint StrCaseCmp(char *s1, char *s2)
X{
X	while (*s1 && *s2)
X	{
X		if (toupper(*s1) != toupper(*s2))
X			return(1);	/* Different. */
X		s1++, s2++;
X	}
X	return(0);			/* Same. */
X}
X
X
X/* This is a safe method for concatenating string "src" onto the end of
X * string "dest".  If dest does not have enough room to fit "src", an
X * error routine is called, and FALSE is returned.  Otherwise, the
X * concatenation takes place, and TRUE is returned.
X *
X * The flag "ok" is static.  When one error sets "ok" to FALSE, we never
X * need to run this function anymore. */
X
Xint Concat(char dest[], char src[])
X{
X	static int ok = TRUE;
X	int destLen;
X
X	if (ok)
X	{
X		destLen = strlen(dest);
X		if (destLen + strlen(src) <  memSize)	/* memSize global. */
X			strcat(dest, src);
X		else
X		{
X			ErrorMsg(ERROR_TOO_SMALL);
X			if (destLen > 0)
X				dest[destLen-1] = '\n';
X			else
X				dest[0] = '\0';
X			ok = FALSE;
X		}
X	}
X}
X
X
X/* Create an array of size memSize and return a pointer to it.  We also
X * copy the empty string into the array, in preparation for later
X * strcat() calls. */
X	
Xchar *MakeOutArray()
X{
X	char *arr = NULL;
X
X	/* Note that memSize is global, and set by GetOptions. */
X
X	if ((memSize <= 0) || !(arr = (char *)malloc(memSize)))
X		ExitCleanly((char *)NULL, ERROR_CANT_MALLOC, RETURN_FAIL);
X	else
X	{
X		strcpy(arr, "");
X		return(arr);
X	}
X}
X
X
X/* We turn "format[]" into a format string suitable for printf().
X * We create this format string because we want proper indenting of
X * all our output.  The key value to watch is the %d value, which is
X * calculated using the length of the volume name and the default spacing.
X * We set "d_or_s" to be 'd' or 's', depending on whether we want a
X * decimal field or a string field to be last in the format string.
X * We pass "cr" as TRUE if we want a carriage return (really a newline)
X * at the end of the format string. */
X
Xvoid MakeFormatString(char *volume, char format[], char d_or_s, int cr)
X{
X	char metaFormat[FORMAT_LENGTH];
X
X	if (d_or_s == 'd')
X		strcpy(metaFormat, "%%s%%s%%s%%%dld%s");
X	else if (d_or_s == 's')
X		strcpy(metaFormat, "%%s%%s%%s%%%ds%s");
X	else
X		ErrorMsg(ERROR_IMPOSSIBLE);
X
X	/* volumeNameLen is global and set in InitializeGlobals() or
X	 * GetOptions(). */
X
X	sprintf(format, metaFormat, 
X		DEFAULT_SPACING + volumeNameLen - strlen(volume),
X		cr ? "\n" : "");
X}
X
X
END_OF_FILE
if test 2929 -ne `wc -c <'Source/strings.c'`; then
    echo shar: \"'Source/strings.c'\" unpacked with wrong size!
fi
chmod +x 'Source/strings.c'
# end of 'Source/strings.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.