[comp.sources.amiga] v90i082: MSH 1.5 - Messydos File System Handler , Part04/06

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (02/21/90)

Submitted-by: Olaf 'Rhialto' Seibert <U211344%HNYKUN11.BITNET@CUNYVM.CUNY.EDU>
Posting-number: Volume 90, Issue 082
Archive-name: devices/msh-1.5/part04

#!/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 4 (of 6)."
# Contents:  doc/msh.man.uu src/hanfile.c
# Wrapped by tadguy@xanth on Tue Feb 20 20:57:11 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'doc/msh.man.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/msh.man.uu'\"
else
echo shar: Extracting \"'doc/msh.man.uu'\" \(25877 characters\)
sed "s/^X//" >'doc/msh.man.uu' <<'END_OF_FILE'
Xbegin 664 msh.man
XM"B`@("`@35-(.BA&:6QE4WES=&5M<RD@("`@($%M:6=A(%!R;V=R86UM97(GW
XM<R!-86YU86P@("`@("!-4T@Z*$9I;&53>7-T96US*0H*"@H@("`@()LQ;5-9)
XM3D]04UE3(`H@("`@("`@("`@FS!M36]U;G0@35-(.B`*"B`@("`@("`@("!-D
XM4T@Z/&%N>2!V86QI9"!F:6QE('-P96-I9FEC871I;VX^+"!O<B!J=7-T(`H@E
XM("`@("`@("`@/&%N>2`@=F%L:60@9FEL92!S<&5C:69I8V%T:6]N/B!I9B!Y[
XM;W5R(&-U<G)E;G0@9&ER96-T;W)Y(&ES"B`@("`@("`@("!S;VUE=VAE<F4@C
XM;VX@35-(.BX@(`H*("`@("";,6U54T%'12`*("`@("`@("`@()LP;4U32#H@3
XM:7,@82!R96%L($%M:6=A+7-T>6QE($9I;&4@4WES=&5M(&AA;F1L97(@=&AA>
XM="`@:&%N9&QE<PH@("`@("`@("`@;65S<WED;W,@9F]R;6%T=&5D("!D:7-KE
XM971T97,N("`@(%EO=2`@8V%N('5S92!F:6QE<R!O;B!S=6-H"B`@("`@("`@\
XM("!M97-S>61O<R!D:7-K<R!I;B!A;&UO<W0@97AA8W1L>2!T:&4@<V%M92`@=
XM=V%Y("!A<R`@>6]U("!U<V4*("`@("`@("`@(&9I;&5S(&]N(&YO<FUA;"!!S
XM;6EG82!D:7-K<RX@(`H*("`@("`@("`@(%-U<'!O<G1E9"`@87)E("`T,"`@`
XM;W(@(#@P("!T<F%C:W,L("!D;W5B;&4M<VED960@."P@.2!O<B`Q,`H@("`@7
XM("`@("`@<V5C=&]R(&9L;W!P>2!D:7-K<RP@86YD(&AA<F1D:7-K<R!W:71H`
XM(&$@,3(@;W(@(#$V+6)I="`@1D%4"B`@("`@("`@("!O9B!A;GD@("!D:6UEY
XM;G-I;VX@("!T:&4@($9!5"`@86QL;W=S+B`@("`H1'5E("!T;R`@;&%C:R`@G
XM;V8*("`@("`@("`@(&%V86EL86)I;&ET>2P@22!H879E(&YO="!B965N(&%B!
XM;&4@('1O("!T97-T("!-4T@Z("!O;B`@:&%R9`H@("`@("`@("`@9&ES:W,[U
XM('!R;V-E960@=VET:"!E>'1R96UE(&-A=71I;VXI+B`@"@H@("`@()LQ;4U/K
XM54Y43$E35"`*("`@("`@("`@()LP;4$@('-A;7!L92!-;W5N=&QI<W0@96YTN
XM<GDL('1H870@=V]R:W,@=VET:"!T:&4@07)P(#$N,R!-;W5N=`H@("`@("`@-
XM("`@8V]M;6%N9#H@"@H@("`@("`@("`@+RH*("`@("`@("`@("`J("!-97-SR
XM>2!F:6QE('-Y<W1E;2!O;B!M97-S>2!B;&]C:W,Z"B`@("`@("`@("`@*B\*Q
XM("`@("`@("`@($U32#H@("`@1FEL95-Y<W1E;2`]($UE<W-Y1FEL95-Y<W1E-
XM;0H@("`@("`@("`@("`@("`@("!$979I8V4@/2!M97-S>61I<VLN9&5V:6-E^
XM"B`@("`@("`@("`@("`@("`@(%5N:70@/2`Q"B`@("`@("`@("`@("`@("`@"
XM($9L86=S(#T@,`H@("`@("`@("`@+RH*("`@("`@("`@("`J("!(:6=H0WEL9
XM(&ES(&EG;F]R960L($QO=T-Y;"P@4W5R9F%C97,@86YD($)L;V-K<U!E<E1RP
XM86-K"B`@("`@("`@("`@*B`@87)E('5S960@;VYC92!T;R!F:6YD('1H92!BX
XM;V]T8FQO8VLN($9U<G1H97(@<&%R86UE=&5R<PH@("`@("`@("`@("H@(&%R&
XM92!F;W5N9"!T:&5R92X*("`@("`@("`@("`J+PH@("`@("`@("`@("`@("`@4
XM("!,;W=#>6P@/2`P(#L@2&EG:$-Y;"`](#<Y"B`@("`@("`@("`@("`@("`@!
XM(%-U<F9A8V5S(#T@,@H@("`@("`@("`@("`@("`@("!";&]C:W-097)4<F%CD
XM:R`](#D*("`@("`@("`@("`@("`@("`@0G5F9F5R<R`](#4*("`@("`@("`@4
XM("\J"B`@("`@("`@("`@*B`@57-E($)U9DUE;51Y<&4@/2`S(%MF;W(@345-I
XM1E]#2$E0('P@345-1E]054),24-=(&EF('EO=0H@("`@("`@("`@("H@('5S-
XM92!-4T@Z(&]N('1H92!T<F%C:V1I<VLN9&5V:6-E+@H@("`@("`@("`@("HOT
XM"B`@("`@("`@("`@("`@("`@($)U9DUE;51Y<&4@/2`Q"B`@("`@("`@("`@`
XM("`@("`@($)O;W10<FD@/2`P"B`@("`@("`@("`@("`@("`@(%-T86-K<VEZB
XM92`](#0P.38*("`@("`@("`@("`@("`@("`@4')I;W)I='D@/2`U"B`@("`@]
XM("`@("`@("`@("`@($=L;V)696,@(#T@+3$*("`@("`@("`@(",*"B`@("`@>
XM("`@("!4:&ES($UO=6YT;&ES="!E;G1R>2!I;G-T<G5C=',@35-(.B!T;R!UB
XM<V4@(&9L;W!P>2`@=6YI="`@,2P*("`@("`@("`@(&DN92X@($1&,3H@(&%N'
XM9"`@=&AE("!M97-S>61I<VLN9&5V:6-E+B`@(%EO=2!M87D@8VAO;W-E(&%NA
XM>0H@("`@("`@("`@;F%M92!I;G-T96%D(&]F($U32#H@=&AA="!Y;W4@;&EK1
XM92X@("!&;W(@('1H:7,@(&-A<V4L("!-4S$Z"B`@("`@("`@("!W;W5L9"!A;
XM;'-O("!B92!A('-E;G-I8FQE(&-H;VEC92X@(%EO=2!C86X@<F5A9"!T:&4@0
XM<V5P87)A=&4*("`@("`@("`@(&UA;G5A;"!P86=E(&%B;W5T(&UE<W-Y9&ESF
XM:RYD979I8V4N("!)="!I<R`@<W5P<&]S960@('1O("!B90H@("`@("`@("`@7
XM<&]S<VEB;&4@('1O("!U<V4@35-(.B!O;B!A(&AA<F1D:7-K(&)Y('-U<'!L*
XM>6EN9R!T:&4@<')O<&5R"B`@("`@("`@("!D979I8V4@;F%M92!A;F0@=6YI*
XM="!N=6UB97(N("!)9B!Y;W4@=VES:"`@=&\@('5S92`@9FQO<'!I97,*"@H@B
XM("`@($MO<VUO4V]F="`@("`@("`@("`@("`@("`@("`@("`@("TQ+2`@("`@0
XM("`@("`@("`@("`@("`@("!697)S:6]N(#,T+C0*"@H@("`@($U32#HH1FEL2
XM95-Y<W1E;7,I("`@("!!;6EG82!0<F]G<F%M;65R)W,@36%N=6%L("`@("`@9
XM35-(.BA&:6QE4WES=&5M<RD*"@H@("`@("`@("`@=')U;'D@(&-O;7!A=&EB8
XM;&4@('=I=&@@=&AO<V4@;65S<WD@;6%C:&EN97,L('EO=2!S:&]U;&0@=7-E.
XM"B`@("`@("`@("!T:&4@;65S<WED:7-K+F1E=FEC92X@(%EO=2`@8V%N;F]T3
XM("!C:&%N9V4@('1H:7,@(&YA;64@(&EN=&\*("`@("`@("`@('-O;65T:&ENJ
XM9R!E;'-E+B`@"@H@("`@("`@("`@5&AE("!-;W5N=&QI<W0@(&5N=')I97,@\
XM3&]W0WEL+"!3=7)F86-E<RP@86YD($)L;V-K<U!E<E1R86-K"B`@("`@("`@%
XM("!A<F4@=7-E9"!O;F-E('1O(&1E=&5R;6EN92`@=&AE("!L;V-A=&EO;B`@(
XM;V8@('1H92`@;65S<WED;W,*("`@("`@("`@(&)O;W1B;&]C:RX@("!$:7-KO
XM("!B;&]C:W,@(&]F("`U,3(@8GET97,@87)E(&%S<W5M960@:6X@=&AI<PH@5
XM("`@("`@("`@8V%L8W5L871I;VXN("!&=7)T:&5R(&EN9F]R;6%T:6]N(&ES_
XM('1H96X@;V)T86EN960@9G)O;2`@=&AE"B`@("`@("`@("!B;V]T8FQO8VL@S
XM*'-E92!B96QO=RDN("`*"B`@("`@FS%M0T]-4$%424))3$E462`*("`@("`@F
XM("`@()LP;45V96X@('1H;W5G:"`@35-(.B`@=7-E<R`@;VYE(&]F('EO=7(@]
XM9FQO<'!Y(&1R:79E<RP@>6]U(&UA>0H@("`@("`@("`@<W1I;&P@=7-E('1HR
XM870@9')I=F4@9F]R("!N;W)M86P@($%M:6=A("!D:7-K<RX@("`@66]U("!W>
XM:6QL"B`@("`@("`@("!N;W1I8V4@('1H870@('=H96X@('EO=2`@:6YS97)TB
XM("!A(&1I<VL@:6X@=&AE(&1R:79E('5S960@8GD*("`@("`@("`@($U32#HLB
XM(&)O=&@@35-(.B!A;F0@=&AE(')E9W5L87(@06UI9V$@(&9I;&4@('-Y<W1EL
XM;2`@:&%N9&QE<@H@("`@("`@("`@=VEL;"!A='1E;7!T("!T;R!I9&5N=&EF2
XM>2!T:&4@9&ES:RX@(%1H92!R97-U;'0@=VEL;"!B92!T:&%T"B`@("`@("`@-
XM("!O;F4@;V8@=&AE('1W;R!W:6QL(&)E('5N86)L92!T;R!R96%D(&ET+"!A1
XM;F0@=&AE;B!L96%V92`@:70*("`@("`@("`@(&%L;VYE('-O('1H870@=&AEX
XM(&]T:&5R(&UA>2!U<V4@:70N("`*"B`@("`@("`@("!4:&ES("!I<R`@=VAA)
XM="!H87!P96YS('=H96X@>6]U(&EN<V5R="!A(&UE<W-Y9&]S(&1I<VLZ($)OU
XM=&@*("`@("`@("`@(&9I;&4@<WES=&5M<R!W:6QL('1R>2!T;R!R96%D('1H0
XM92!B;V]T(&)L;V-K("!O9B`@=&AE("!D:7-K+@H@("`@("`@("`@5&AE(')EU
XM9W5L87(@06UI9V$@9FEL92!S>7-T96T@9V5T<R!A(')E860@97)R;W(L(&%N4
XM9"!R971R:65S"B`@("`@("`@("!A(&9E=R`@=&EM97,L("!W:&EL92!R96-AQ
XM;&EB<F%T:6YG('1H92!D:7-K(')E860@:&5A9"X@(%1H:7,*("`@("`@("`@&
XM(&ES('1H92!S:&]R="!N;VES92!Y;W4@;6%Y(&AE87(@9G)O;2!T:&4@9')IC
XM=F4N("`@($%T("!A8F]U=`H@("`@("`@("`@=&AE("!S86UE("!T:6UE+"!-2
XM4T@Z('=I;&P@<V5I>F4@8V]N=')O;"!O=F5R('1H92!D:7-K('5N:70L"B`@L
XM("`@("`@("!R96%D('1H92!D:7-K+"!A;F0@<V5E("!T:&%T("!A;&P@(&ESJ
XM("!W96QL+B`@("!)="`@:7,@('1H96X*("`@("`@("`@('!R97!A<F5D('1O*
XM(&%C='5A;&QY('5S92!T:&4@9&ES:RX@(`H*("`@("`@("`@(%1H:7,@(&ES.
XM("!W:&%T(&AA<'!E;G,@=VAE;B!Y;W4@:6YS97)T(&%N($%M:6=A(&1I<VLZZ
XM($%G86EN+`H@("`@("`@("`@8F]T:"!F:6QE('-Y<W1E;7,@=VEL;"!T<GD@2
XM=&\@<F5A9"!T:&4@(&)O;W0@(&)L;V-K("!O9B`@=&AE"B`@("`@("`@("!D#
XM:7-K+B`@0G5T('1H:7,@=&EM92!-4T@Z('=I;&P@9&5S<&5R871E;'D@=')YB
XM('1O('5N9&5R<W1A;F0*("`@("`@("`@('1H92`@9&ES:RP@8G5T(&ET('=IE
XM;&P@9VEV92!U<"!W:&5N(&ET(&ES(&-O;G9I;F-E9"!T:&%T('1H90H@("`@(
XM("`@("`@9&ES:R!I<R!R96%L;'D@;F]T(&UE86YT(&9O<B!I="X@(`H*("`@\
XM("`@("`@($ET(&ES(')E8V]M;65N9&5D('1H870@>6]U(&1O;B=T(&%T=&5M!
XM<'0@=&\@(')E9F5R("!T;R`@35-(.@H@("`@("`@("`@=VAI;&4@;W1H97(@%
XM9FEL97-Y<W1E;7,@87)E('1R>6EN9R!T;R!R96%D('1H92!D:7-K+B`@"@H@:
XM("`@("`@("`@26X@('-O;64@('-I='5A=&EO;G,@('=H97)E('1H97)E(&%RD
XM92!M=6QT:7!L92!E<G)O<G,@870@=&AE"B`@("`@("`@("!S86UE('1I;64@C
XM*'-U8V@@87,@=')Y:6YG('1O(&1E;&5T92!A(&YO;BUE>&ES=&5N="!F:6QEO
XM(&9R;VT*("`@("`@("`@(&$@=W)I=&4M<')O=&5C=&5D(&1I<VLI+"!T:&4@B
XM97)R;W(@<F5P;W)T960@;6%Y(&)E(&1I9F9E<F5N=`H@("`@("`@("`@=&AA;
XM;B!T:&4@<F5G=6QA<B!F:6QE('-Y<W1E;2X@(`H*("`@("";,6U%6%1%3E-)A
XM3TY3(`H@("`@("`@("`@04-424].FS!M7YLQ;41)12`*"B`@("`@("`@("";)
XM,&U4:&4@<&%C:V5T()LS;4%#5$E/3E]$244@FS!M:7,@<W5P<&]R=&5D+"!A'
XM;F0@979E;B!H87,@=&AE("!R97-U;'0*("`@("`@("`@(&]F('-T;W!P:6YGO
XM("!-4T@Z("!A;F0@=6YL;V%D:6YG('1H92!F:6QE('-Y<W1E;2!C;V1E+B`@%
XM5&AI<PH@("`@("`@("`@:7,@8V]N=F5N:65N="!W:&5N('EO=2!D;VXG="!NP
XM965D('1O('5S92!-4T@Z("!F;W(@(&$@('=H:6QE"B`@("`@("`@("!A;F0@^
XM:&5L<',@('EO=2`@=&\@8V]N<V5R=F4@;65M;W)Y+B`@02!P<F]G<F%M(&-A%
XM;&QE9"";,VUD:64@FS!M:7,*("`@("`@("`@('-U<'!L:65D('1H870@<V5N)
XM9',@=&AE($%#5$E/3E]$244@<&%C:V5T('1O(&%N>2!H86YD;&5R('EO=0H@O
XM("`@("`@("`@=VES:"X@($EF('1H97)E(&ES(&%N>2!P<F]G<F%M(')U;FYIX
XM;F<@=&AA="!E>'!E8W1S($U32#H@('1O"B`@("`@("`@("!R96UA:6X@('!R/
XM97-E;G0@979E;B!W:&EL92!T:&5R92!A<F4@;F\@;W!E;B!O<B!L;V-K960@X
XM9FEL97,*("`@("`@("`@(&]N($U32#HL(&ET(&UA>2!B92!D86YG97)O=7,@[
XM=&\@<F5M;W9E($U32#HN("`*"B`@("`@("`@("";,6U!0U1)3TZ;,&U?FS%M<
XM34]214-!0TA%(`H*("`@("`@("`@()LP;4U32#H@(&AA;F1L97,@('1H92`@U
XM<&%C:V5T("";,VU!0U1)3TY?34]214-!0TA%("";,&TH=7-E9"`@8GD@('1H?
XM90H@("`@("`@("`@061D0G5F9F5R<R`@8V]M;6%N9"D@(&%N9"`@8V%C:&4@4
XM8G5F9F5R<R!M;W)E(&EN=&5L;&EG96YT;'DN"@H*("`@("!+;W-M;U-O9G0@5
XM("`@("`@("`@("`@("`@("`@("`@("`M,BT@("`@("`@("`@("`@("`@("`@,
XM("`@5F5R<VEO;B`S-"XT"@H*("`@("!-4T@Z*$9I;&53>7-T96US*2`@("`@X
XM06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@($U32#HH1FEL95-Y<W1E5
XM;7,I"@H*("`@("`@("`@(%=H96X@>6]U(&%D9"!B=69F97)S+"!T:&4@<F5Q!
XM=6ER960@;65M;W)Y(&ES("!N;W0@(&%L;&]C871E9`H@("`@("`@("`@:6UM5
XM961I871E;'DL("!B=70@(&=R861U86QL>2`@87,@=&AE<F4@8F5C;VUE<R!A8
XM('5S92!F;W(@:70N"B`@("`@("`@("!7:&5N('EO=2!R96UO=F4@82!D:7-K2
XM(&ET<R!B=69F97)S(&%R92!N;R!L;VYG97(@;V8@=7-E("!A;F0*("`@("`@8
XM("`@('1H97)E9F]R92!A<F4@(&%L;"`@9G)E960N("!!;F0L('=H870@:7,@X
XM;6]R92!I;7!O<G1A;G0L('EO=0H@("`@("`@("`@8V%N(&1E8W)E87-E('1HN
XM92!M87AI;75M(&YU;6)E<B!O9B!B=69F97)S+B`@0GD@<W!E8VEF>6EN9R!AI
XM"B`@("`@("`@("!N96=A=&EV92!N=6UB97(@>6]U(')E9'5C92!T:&4@;G5ML
XM8F5R(&]F(&)U9F9E<G,N("`@268@('EO=7(*("`@("`@("`@($%D9$)U9F9E"
XM<G,@(&1O97,@;F]T(&QI:V4@;F5G871I=F4@8G5F9F5R(&-O=6YT<RP@<VEMD
XM<&QY(&%D9`H@("`@("`@("`@-C4U,S8@=&\@=&AE("AN96=A=&EV92D@;G5M)
XM8F5R('EO=2`@86-T=6%L;'D@(&EN=&5N9"X@("`@4V\L"B`@("`@("`@("!IF
XM;G-T96%D("!O9B`@+3$@>6]U(&-A;B!A;'-O('-P96-I9GD@-C4U,S4L("TRV
XM(&ES(#8U-3,T+B!9;W4*("`@("`@("`@('=O=6QD;B=T('=A;G0@('1O("!A*
XM9&0@(&UO<F4@('1H86X@(#,R-S8W("!B=69F97)S("!A="`@;VYC90H@("`@@
XM("`@("`@86YY=V%Y+B`@"@H@("`@()LQ;4Q)34E4051)3TY3(`H@("`@("`@+
XM("`@FS!M1'5E("!T;R`@=&AE("!D:69F97)E;F-E("!B971W965N(&UE<W-Y@
XM9&]S(&%N9"!!;6EG841/4R!F:6QE"B`@("`@("`@("!S>7-T96US+"!N;W0@=
XM86QL(&]P97)A=&EO;G,@=&AA="`@87)E("!A=F%I;&%B;&4@(&9O<B`@06UIE
XM9V$*("`@("`@("`@(&9I;&5S(&-A;B!B92!A<'!L:65D('1O(&UE<W-Y9&]SW
XM(&9I;&5S+B`@"@H@("`@("`@("`@FS%M1FEL92!N86UE<R`*"B`@("`@("`@6
XM("";,&U4:&4@("!M;W-T("!E>64M8V%T8VAI;F<@(&1I9F9E<F5N8V4@(&%R+
XM92`@=&AE("!F:6QE("!N86UE<SH*("`@("`@("`@(&UE<W-Y9&]S(&9I;&4@U
XM;F%M97,@8V%N(&)E(&%T(&UO<W0@(C@@*R`S(B!C:&%R86-T97)S("!L;VYG/
XM+@H@("`@("`@("`@5&AI<R`@;65A;G,@('1H870@('1H92`@(F)A<V4B("!PE
XM87)T(&]F('1H92!F:6QE(&YA;64@;6%Y(&)E"B`@("`@("`@("!E:6=H="!C*
XM:&%R86-T97)S(&QO;F<L(&UA>6)E(&9O;&QO=V5D(&)Y("!A("!T:')E92UCG
XM:&%R86-T97(*("`@("`@("`@(")E>'1E;G-I;VXB+"`@=VAI8V@@(&ES("!S#
XM97!A<F%T960@9G)O;2!T:&4@8F%S92!N86UE('=I=&@@80H@("`@("`@("`@>
XM<&5R:6]D("@G+B<I+B!!;'-O+"!Y;W4@8V%N;F]T('5S92`@86QL("!C:&%R=
XM86-T97)S("!I;B`@=&AE"B`@("`@("`@("!F:6QE("!N86UE<R`@>6]U("!WL
XM:7-H+"!B=70@=&AE(&-H87)A=&5R(&-H;VEC92!I<R!B87-I8V%L;'D*("`@K
XM("`@("`@(&QI;6ET960@=&\@=&AE('5P<&5R8V%S92!L971T97)S($$M6BP@K
XM9&EG:71S(#`M.2P@(&%N9"`@;6]S=`H@("`@("`@("`@(G!U;F-T=6%T:6]N"
XM(B!C:&%R86-T97)S("!E>&-E<'0@('-P86-E("H@/R`@+B`\(#X@+R`]('P@P
XM+"`Z"B`@("`@("`@("!A;F0@7"X@(`H*("`@("`@("`@($U32#H@=VEL;"!T/
XM<GD@=&\@;6%P("!F:6QE("!N86UE<R`@=&AA="`@>6]U("!O<B`@82`@<')OA
XM9W)A;0H@("`@("`@("`@871T96UP=',@=&\@=7-E('1O(&YA;65S('1H870@[
XM87)E(&%C='5A;&QY(&%L;&]W960N("!"=70@9F]R"B`@("`@("`@("!U=&UO.
XM<W0@(&9L97AI8FEL:71Y+"`@;VYL>2`@=&AE("!M;W-T("!B87-I8R!L:6UI+
XM=&%T:6]N<R!A<F4*("`@("`@("`@(&5N9F]R8V5D.B`@=&AE("!L96YG=&@@'
XM(&]F("`@=&AE("`@;F%M92`@("@X*S,I+"`@('5P<&5R8V%S90H@("`@("`@<
XM("`@86QP:&%B971I8W,L("!A;F0@('1H92`@<')E<V5N8V4@(&]F("!O;FQYL
XM(&]N92!P97)I;V0@:6X@=&AE"B`@("`@("`@("!N86UE+B`@5&AI<R!M96%N/
XM<R!T:&%T('EO=2!M:6=H="!C<F5A=&4@9FEL92`@;F%M97,@('1H870@(&$*^
XM("`@("`@("`@(&UE<W-Y9&]S("!C;VUP=71E<B`@9&]E<R`@;F]T("!C;W)R8
XM96-T;'D@:VYO=R!H;W<@=&\@:&%N9&QE+@H@("`@("`@("`@0G5T(&-A<F4@[
XM:&%S(&)E96X@=&%K96X@=&AA="!I;B!N;R!C87-E(&ET('=O=6QD(&)E('!O8
XM<W-I8FQE"B`@("`@("`@("!T;R!C<F5A=&4@82!F:6QE(&YA;64@=&AA="P@B
XM;VYC92!C<F5A=&5D+"!C86YN;W0@8F4@(&AA;F1L960*("`@("`@("`@(&%N\
XM>6UO<F4@(&)Y($U32#HN(%EO=2!C86X@86QW87ES(')E9F5R('1O('1H870@_
XM9FEL92!W:71H('1H90H@("`@("`@("`@<V%M92!N86UE('EO=2!U<V5D(&)E#
XM9F]R92P@979E;B!I9B!-4T@Z(&-H86YG960@:70@9F]R('EO=2X@(`H*("`@$
XM("`@("`@()LQ;5-P96-I86P@9&ER96-T;W)I97,@FS!M+B";,6UA;F0@FS!M!
XM+BX@"@H@("`@("`@("`@3VX@;65S<WED;W,@9FQO<'!I97,L(&5V97)Y("!S0
XM=6)D:7)E8W1O<GD@(&AA<R`@='=O("!S<&5C:6%L"B`@("`@("`@("!E;G1RF
XM:65S(&-A;&QE9"`@(BXB("`@(&%N9"`B+BXB+B!4:&5Y(')E9F5R('1O('1H&
XM92!D:7)E8W1O<GD*("`@("`@("`@(&ET<V5L9B!A;F0@:71S(")P87)E;G0B<
XM(&1I<F5C=&]R>2P@<F5S<&5C=&EV96QY+B`@("!0<F]G<F%M<PH@("`@("`@#
XM("`@=&AA="`@=')A=F5R<V4@9&ER96-T;W)Y('1R965S(&]N(&UE<W-Y9&]S)
XM('-Y<W1E;7,@=&%K92!C87)E"B`@("`@("`@("!T;R!S:VEP('1H97-E(")SJ
XM=6)D:7)E8W1O<FEE<R(L('-I;F-E('1H97D@(')E86QL>2`@87)E("!N;W0*J
XM("`@("`@("`@(")S=6(B(&1I<F5C;W)I97,@86YD(')E8W5R<VEV96QY(&5NZ
XM=&5R:6YG('1H96T@=V]U;&0@;&5A9"!T;PH@("`@("`@("`@;F]T:&EN9R!B>
XM=70@('1R;W5B;&4N("`@("A4:&5I<B`@<')E<V5N8V4@('!R979E;G1S('1H`
XM92!F:6QE"B`@("`@("`@("!S>7-T96T@9G)O;2!H879E(&$@=')E92!S=')UK
XM8W1U<F4N*2!"=70@('=I=&@@($%M:6=A1$]3("`Q+C,*("`@("`@("`@(&%NQ
XM9"`@8F5F;W)E+"`@;F\@('-U8V@@(")H87)D("!L:6YK<R(@(&5X:7-T+"`@P
XM86YD(&1I<F5C=&]R>0H@("`@("`@("`@=')A=F5R<VEN9R`@<')O9W)A;7,@"
XM('=O=6QD("!N;W0@(&AE<VET871E("!T;R`@96YT97(@('1H96TN"B`@("`@Z
XM("`@("!4:&5R969O<F4L('1H97D@(&%R92`@FS-M8V]M<&QE=&5L>2`@FS!MS
XM:&ED9&5N("!F<F]M("!S:6=H="X@("!9;W4*("`@("`@("`@(&-A;FYO="!SJ
XM964@=&AE;2!I;B!D:7)E8W1O<GD@;&ES=&EN9W,@;F]R(')E9F5R('1O("!TK
XM:&5M("!B>0H@("`@("`@("`@86YY(&YA;64N("`*"@H*("`@("!+;W-M;U-OI
XM9G0@("`@("`@("`@("`@("`@("`@("`@("`M,RT@("`@("`@("`@("`@("`@G
XM("`@("`@5F5R<VEO;B`S-"XT"@H*("`@("!-4T@Z*$9I;&53>7-T96US*2`@X
XM("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@($U32#HH1FEL95-YI
XM<W1E;7,I"@H*("`@("`@("`@($)U="`@979E;B`@=VAI;&4@(&ET("!I<R!HF
XM:61D96XL('1H92`B+BXB(&5N=')Y(&ES(&]F(&-O=7)S90H@("`@("`@("`@/
XM<W1I;&P@=7!D871E9"!T;R!R969L96-T('1H92!N97<@('!A<F5N="`@9&ER+
XM96-T;W)Y("!W:&5N("!A"B`@("`@("`@("!D:7)E8W1O<GD@:7,@(')E;F%M7
XM960@(&%N9"`@;6]V960N("`@($YO=&4L(&)Y('1H92!W87DL('1H870*("`@[
XM("`@("`@(&UO=FEN9R!D:7)E8W1O<FEE<R!I<R!A;B!O<&5R871I;VX@=&AAF
XM="!I<R!N;W0@<W5P<&]R=&5D("!B>0H@("`@("`@("`@;65S<WED;W,@:71SS
XM96QF+B`@"@H@("`@("`@("`@3V8@(&-O=7)S92P@('1H92`@=7-U86P@(&UEH
XM=&AO9',@(&]F("!A8V-E<W-I;F<@('1H92!C=7)R96YT"B`@("`@("`@("!DY
XM:7)E8W1O<GD@*'1H92!E;7!T>2!N86UE("(B*2!A;F0@=&AE('!A<F5N="!DY
XM:7)E8W1O<GD@*"(O(BD*("`@("`@("`@(&1O('=O<FLN("`*"B`@("`@("`@7
XM("!)="!M87D@8F4@('1H870@(&EN("!T:&4@(&9U='5R92P@('=H96X@('-OO
XM9G1L:6YK<R`@=VEL;"`@8F4*("`@("`@("`@(&EN8VQU9&5D(&EN($%M:6=A"
XM1$]3+"!T:&5S92`B+B(@86YD("(N+B(@9&ER96-T;W)I97,@=VEL;"!B90H@6
XM("`@("`@("`@;6%D92!V:7-I8FQE("!A9V%I;BP@8G5T(&EN('1H92!D:7-G[
XM=6ES92!O9B!A('-O9G0@;&EN:RX@($EN"B`@("`@("`@("!T:&%T(&-A<V4L>
XM('!R;V=R86US('=H:6-H(&1O;B=T("!K;F]W("!H;W<@('1O("!H86YD;&4@V
XM('1H96T*("`@("`@("`@('-H;W5L9"`@(&5I=&AE<B`@;F]T("!E>&ES="`@&
XM86YY;6]R92`@;W(@(&EG;F]R92`@=&AE("!L:6YK<PH@("`@("`@("`@=&AE-
XM;7-E;'9E<RX@(`H*("`@("`@("`@()LQ;49I;&5N;W1E<R`*"B`@("`@("`@7
XM("";,&U-97-S>61O<R!H87,@;F\@<')O=FES:6]N(&9O<B!F:6QE(&YO=&5SA
XM(&%N9"!T:&5R969O<F4@('1H97D*("`@("`@("`@(&-A;FYO="!B92!S=7!P-
XM;W)T960N("`*"B`@("`@("`@("";,6U&:6QE('!R;W1E8W1I;VX@8FET<R!VH
XM<YLP;2X@()LQ;69I;&4@871T<FEB=71E<R`*"B`@("`@("`@("";,&U#=7)RA
XM96YT;'DL("!T:&4@(&9O;&QO=VEN9R`@:6YT97)P<F5T871I;VX@(&]F(&UEI
XM<W-Y9&]S(&9I;&4*("`@("`@("`@(&%T=')I8G5T97,@:7,@<&5R9F]R;65D6
XM+B`@("!4:&4@($1I<F5C=&]R>2`@86YD("!6;VQU;65L86)E;`H@("`@("`@9
XM("`@871T<FEB=71E<R`@87)E("!H;VYO<F5D("!T;R`@;6%K92`@=&AE<V4@(
XM(&1I<F5C=&]R>2!E;G1R:65S"B`@("`@("`@("!D:69F97)E;G0@9G)O;2!PT
XM;&%I;B!F:6QE<RX@(`H@("`@("`@("`@5&AE($A)1$1%3B!A;F0@4UE35$5-4
XM(&%T=')I8G5T97,@87)E(&UA<'!E9"!T;R!T:&4@($@H:61D96XI"B`@("`@!
XM("`@("!B:70N("`@5&AE("!(("!B:70@(&ES("!M87!P960@('1O('1H92!(4
XM241$14X@871T<FEB=71E.R!T:&4*("`@("`@("`@(%-94U1%32!A='1R:6)U^
XM=&4@8V%N;F]T(&)E(&-H86YG960N("`*("`@("`@("`@(%1H92`@4D5!1"U/^
XM3DQ9("!A='1R:6)U=&4@(&ES("!M87!P960@('1O("!T:&4@(%<H<FET92D@Z
XM(&%N9`H@("`@("`@("`@1"AE;&5T92D@8FET<RX@("!);G9E<G-E;'DL(&EF]
XM(&$@9FEL92!I<R!S970@=&\@96ET:&5R(%=R:71E"B`@("`@("`@("!O<B!$'
XM96QE=&4@<')O=&5C=&5D+"!T:&4@4D5!1"U/3DQ9(&%T=')I8G5T92!I<R!ST
XM970N("`*("`@("`@("`@(%1H92!!4D-(259%(&)I="P@=VAE;B!C;&5A<BP@D
XM<V5T<R!T:&4@02AR8VAI=F5D*2`@8FET+B`@("!/;@H@("`@("`@("`@;65SP
XM<WED;W,@('1H92`@05)#2$E612`@871T<FEB=71E("!M96%N<R`H=VAE;B!SJ
XM970I('1H870@=&AE"B`@("`@("`@("!F:6QE($U54U0@8F4@8F%C:V5D('5PM
XM("AB>2!A(&)A8VMU<"!P<F]G<F%M*2X@($$@=W)I=&4@=&\@(&$*("`@("`@C
XM("`@(&9I;&4@<V5T<R`@=&AE("!!4D-(259%(&%T=')I8G5T92X@($]N($%MO
XM:6=A1$]3('1H92!!<F-H:79E9`H@("`@("`@("`@8FET(&UE86YS("`H=VAEG
XM;B`@<V5T*2`@=&AA="`@=&AE("!F:6QE("!H87,@(&)E96X@(&%R8VAI=F5D1
XM"B`@("`@("`@("!A;')E861Y+B`@($$@('=R:71E('1O(&$@9FEL92!C;&5A?
XM<G,@=&AE($%R8VAI=F5D('!R;W1E8W1I;VX*("`@("`@("`@(&)I="X@(`H*^
XM("`@("`@("`@()LQ;4)O;W0@8FQO8VL@9F]R;6%T(`H*("`@("`@("`@()LP@
XM;4U32#H@<F5L:65S(&]N('1H92!I;F9O<FUA=&EO;B!I;B!T:&4@8F]O="`@#
XM8FQO8VL@(')E9V%R9&EN9PH@("`@("`@("`@=&AE("!N=6UB97(@;V8@8GETV
XM97,@<&5R(&)L;V-K+"!B;&]C:W,@<&5R('1R86-K+"!T<F%C:W,@<&5R"B`@5
XM("`@("`@("!C>6QI;F1E<BP@8FQO8VMS('!E<B!C;'5S=&5R+"!E=&,N("!4W
XM:&4@<&AY<VEC86P@:6YF;W)M871I;VX*("`@("`@("`@(&ES(&YO="!A8W1UT
XM86QL>2!U<V5D('1O(&%C8V5S<R`@=&AE("!D:7-K+"`@97AC97!T("!F;W(@@
XM('1H90H@("`@("`@("`@;G5M8F5R("!O9B`@=')A8VMS("!W:&EC:"!I<R!DD
XM97)I=F5D(&9R;VT@;W1H97(@:6YF;W)M871I;VXN"B`@("`@("`@("!)="!I9
XM<R!U<V5D('1O(&1E8VED92!I9B!A(#0P('1R86-K(&1I<VL@:7,@:6YS97)TJ
XM960@:6X@82`@.#`*("`@("`@("`@('1R86-K(&1R:79E+B`@(%-I;F=L92`@R
XM<VED960@(&1I<VMS("!A<F4@;F]T('-U<'!O<G1E9"X@(%1H90H@("`@("`@/
XM("`@;G5M8F5R(&]F('-E8W1O<G,@;6%Y("!B92`@=VAA=&5V97(@('1H92`@6
XM=6YD97)L>6EN9R`@9&5V:6-E"B`@("`@("`@("!D<FEV97(@<W5P<&]R=',NE
XM("`H5VET:"!M97-S>61I<VLN9&5V:6-E('1H:7,@:7,@."P@.2!O<B`Q,#L*6
XM("`@("`@("`@('=I=&@@('1R86-K9&ES:RYD979I8V4@(&ET("!I<R`@,3$I>
XM+B!/;FQY('1H92!L;V=I8V%L(&QA>6]U=`H@("`@("`@("`@:6YF;W)M871I=
XM;VX@:7,@=7-E9#H@4VEZ92!O9B!A("!B;&]C:RP@(&YU;6)E<B`@;V8@(')E!
XM<V5R=F5D"B`@("`@("`@("!B;&]C:W,L("!N=6UB97(@;V8@1D%4<RP@;G5M%
XM8F5R(&]F(&)L;V-K<R!P97(@1D%4+"!N=6UB97(@;V8*("`@("`@("`@(')OC
XM;W0@9&ER96-T;W)Y(&5N=')I97,L(&YU;6)E<B!O9B!B;&]C:W,@<&5R(&-LP
XM=7-T97(N("`@(%1H90H@("`@("`@("`@=&]T86P@(&YU;6)E<B!O9B!B;&]CN
XM:W,@:7,@=7-E9"!T;R!D971E<FUI;F4@=&AE('5S86)L92!P87)T"@H*("`@=
XM("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@("`M-"T@("`@("`@3
XM("`@("`@("`@("`@("`@5F5R<VEO;B`S-"XT"@H*("`@("!-4T@Z*$9I;&53*
XM>7-T96US*2`@("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@($U3!
XM2#HH1FEL95-Y<W1E;7,I"@H*("`@("`@("`@(&]F('1H92!D:7-K+B`@0G5T#
XM(&EF('1H92!&050@<V%Y<R`B=7-E(&$@(&)L;V-K("!B97EO;F0@('1H90H@R
XM("`@("`@("`@;&EM:70B+"!T:&ES(&5R<F]R(&ES(&YO="!D971E8W1E9"X@,
XM(`H*("`@("`@("`@($EF("!Y;W4@9F]R;6%T(&$@9&ES:R!O;B!A(&UE<W-Y$
XM9&]S(&-O;7!U=&5R(&%N9"!W:7-H('1O('5S90H@("`@("`@("`@:70@=VET.
XM:"!-4T@Z+"!B92!S=7)E('1O('5S92!A(&UE<W-Y9&]S('9E<G-I;VX@(&YE=
XM=R`@96YO=6=H"B`@("`@("`@("!T;R!W<FET92`@=&AI<R`@:6YF;W)M871IV
XM;VX@:6X@=&AE(&)O;W0@8FQO8VLN("`H5F5R<VEO;B`S+C(*("`@("`@("`@-
XM('=O<FMS(&YI8V5L>2!F;W(@;64N*2!)9B!Y;W4@=VES:"!T;R!F;W)M870@=
XM<W5C:"!A("!D:7-K("!O;@H@("`@("`@("`@>6]U<B`@06UI9V$L("!Y;W4@=
XM(&-A;B`@=7-E("!00T8W,C`@(&)Y("!797)N97(@1_QN=&AE<B!W:71H"B`@)
XM("`@("`@("!P8T9O<FUA="!O;B!T:&4@17AT<F%S(&1I<VLL(&]R('5S92`@6
XM=&AE("!S=7!P;&EE9"`@;65S<WEF;70*("`@("`@("`@('!R;V=R86TN("`*9
XM"B`@("`@("`@("";,6U&050@"@H@("`@("`@("`@FS!M5&AE("`@1D%4("`@&
XM:7,@(&-U<G)E;G1L>2`@;F]T("!C:&5C:V5D("!F;W(@(&EN=&5G<FET>2`@"
XM86YD"B`@("`@("`@("!C;VYS:7-T96YC>2X@(%1H92!&050@:7,@87-S=6UEC
XM9"!T;R!H879E(#$R+6)I="`@96YT<FEE<R`@:68*("`@("`@("`@('1H92!DR
XM:7-K("!H87,@870@;6]S="`T,#@V("@D1D8V*2!C;'5S=&5R<RX@($EF('1H2
XM92!D:7-K(&AA<PH@("`@("`@("`@;6]R92!C;'5S=&5R<R!T:&%N('1H870LF
XM(#$V(&)I="`@1D%4("!E;G1R:65S("!A<F4@(&%S<W5M960N"B`@("`@("`@=
XM("!4:&ES(&ES('1H92!M971H;V0@=&AA="!S965M<R!T;R!B92!U<V5D(&)Y:
XM(&UE<W-Y(&1O<R`S+C`N("`*"B`@("`@("`@("";,6U7;W)K8F5N8V@@"@H@:
XM("`@("`@("`@FS!M5&AE("!7;W)K8F5N8V@@=V%N=',@=&\@=7-E(&9I;&5N'
XM86UE<R!T:&%T(&%R92!I;7!O<W-I8FQE(&]N"B`@("`@("`@("!M97-S>61OQ
XM<R!F;&]P<&EE<RX@("@N:6YF;R!E>'1E;G-I;VXI($ET("!I<R`@=&AE<F5F"
XM;W)E("!N;W0*("`@("`@("`@('9E<GD@969F96-T:79E('1O('1R>2!T;R!U2
XM<V4@5V]R:V)E;F-H(&]N($U32#HN("`*"B`@("`@("`@("";,6U6;VQU;64@M
XM;&%B96P@"@H@("`@("`@("`@FS!M3F]R;6%L("!!;6EG841/4R`@9FQO<'!ID
XM97,@(&AA=F4@82!P87)T(&]F('1H92!D:7-K(')E<V5R=F5D"B`@("`@("`@_
XM("!F;W(@=&AE:7(@;F%M92X@(%=I=&@@;65S<WED;W,@9FQO<'!I97,@82!NV
XM86UE(&ES("!O<'1I;VYA;"P*("`@("`@("`@(&%N9"`@<VAO=6QD(&)E(&ENK
XM('1H92!D:7)E8W1O<GD@:6X@86X@96YT<GD@=VET:"!T:&4@<W!E8VEA;`H@V
XM("`@("`@("`@9FQA9R`@*&%T=')I8G5T92D@(%9O;'5M96QA8F5L+B`@35-(M
XM.B`@;&]O:W,@(&EN("!T:&4@(&9I<G-T"B`@("`@("`@("!D:7)E8W1O<GD@A
XM8FQO8VL@(&]N;'D@('1O("!L;V-A=&4@('-U8V@@(&$@=F]L=6UE(&QA8F5L4
XM+B`@268*("`@("`@("`@(&9O=6YD+"!I="!D96-I9&5S('1H92!N86UE(&]FT
XM('1H92!D:7-K.R!I9B`@;F]T("!F;W5N9"P@('1H90H@("`@("`@("`@;F%MV
XM92!W:6QL(&)E8V]M92`B56YN86UE9"(@86YD('1H92!C<F5A=&EO;B!D871E;
XM('=I;&P@8F5C;VUE"B`@("`@("`@("`Q+4IA;BTX,"X@($YO=&4@=&AA="!!O
XM;6EG841/4R`H86YD($U32#HI(&ME97`@9&ES:W,@87!A<G0@8GD*("`@("`@J
XM("`@('1H96ER(&YA;64@86YD(&-R96%T:6]N(&1A=&4N("!!<R!A("!R97-U%
XM;'0L("!A;&P@('5N;&%B96QE9`H@("`@("`@("`@9&ES:W,@=VEL;"!L;V]K&
XM('1H92!S86UE(&%N9"!C86YN;W0@8F4@9&ES=&EN9W5I<VAE9"X@($ET(&ES_
XM"B`@("`@("`@("!T:&5R969O<F4@('-T<F]N9VQY("!R96-O;6UE;F1E9"!TG
XM:&%T('EO=2!P<F]V:61E(&5V97)Y(&1I<VL*("`@("`@("`@('=I=&@@82!U%
XM;FEQ=64@=F]L=6UE(&QA8F5L.R!T:&4@('-T86YD87)D("!!;6EG841/4R`@L
XM8V]M;6%N9`H@("`@("`@("`@4F5L86)E;"!C86X@(&)E('5S960@9F]R('1HM
XM:7,N("!)9B!Y;W4@;&%B96P@82!D:7-K('1H870@:&%D"B`@("`@("`@("!NX
XM;R!L86)E;"`H:6X@=&AE(&9I<G-T(&1I<F5C=&]R>2!S96-T;W(I(&)E9F]R3
XM92P@($U32#H@('=I;&P*("`@("`@("`@('1R>2`@=&\@(&UO=F4@(&$@(&9I>
XM;&4@(&9R;VT@('1H92`@9FER<W0@(&1I<F5C=&]R>2!B;&]C:R!T;PH@("`@[
XM("`@("`@<V]M97=H97)E(&5L<V4@:6X@=&AE("!R;V]T("!D:7)E8W1O<GDNW
XM("`@($EF("!T:&ES("!I<R`@;F]T"B`@("`@("`@("!P;W-S:6)L92P@(&9O`
XM<B`@:6YS=&%N8V4@8F5C875S92!T:&4@<F]O="!D:7)E8W1O<GD@:7,@9G5L<
XM;"P*("`@("`@("`@('1H96X@=&AE(&QA8F5L:6YG('=I;&P@9F%I;"!A<R!WO
XM96QL+B`@"@H@("`@("`@("`@FS%M375L=&EP;&4@9FEL92!S>7-T96US(`H*P
XM("`@("`@("`@()LP;51H92!-97-S>49I;&53>7-T96T@(&ES("!U;F9O<G1U^
XM;F%T96QY("!N;W0@(&!@<'5R92<G+B`@5&AI<PH@("`@("`@("`@;65A;G,@L
XM=&AA="!I9B!Y;W4@=VES:"!T;R!M;W5N="!M=6QT:7!L92!M97-S>2!F:6QEK
XM('-Y<W1E;7,L"B`@("`@("`@("!Y;W4@(&UU<W0@(&UA:V4@82!C;W!Y(&]F#
XM($UE<W-Y1FEL95-Y<W1E;2!F;W(@96%C:"!O9B!T:&5S92P*("`@("`@("`@2
XM(&%N9"!M;W5N="!E86-H(&]N92!F<F]M(&]N92!O9B!T:&4@<V5P87)A=&4@:
XM8V]P:65S+B`@4G5N;FEN9PH@("`@("`@("`@='=O(&9I;&4@<WES=&5M<R!FT
XM<F]M('1H92!S86UE(&1I<VL@9FEL92`@=VEL;"`@8V%U<V4@(&=R96%T"B`@F
XM("`@("`@("!T<F]U8FQE<RX@("`H3V@@('=E;&PL(&UA>6)E($%M:6=A1$]30
XM(&ES(&YO="!S;R!S;6%R="!T;R!S964*("`@("`@("`@('1H870@='=O(&9IZ
XM;&4@<WES=&5M<R!S:&%R92!T:&4@<V%M92!&:6QE4WES=&5M(&YA;64@:6X@@
XM('1H90H@("`@("`@("`@36]U;G1L:7-T+"`@<V\@(&UA>6)E('EO=2!D;VXG;
XM="!N965D('1O(&AA=F4@;75L=&EP;&4@8V]P:65S"B`@("`@("`@("!O9B!-R
XM97-S>49I;&53>7-T96T@;VX@>6]U<B!D:7-K+B`@5')Y(&%T('EO=7(@;W=N%
XM(')I<VLN*2`*"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@=
XM("`@("`M-2T@("`@("`@("`@("`@("`@("`@("`@5F5R<VEO;B`S-"XT"@H*<
XM("`@("!-4T@Z*$9I;&53>7-T96US*2`@("`@06UI9V$@4')O9W)A;6UE<B=S@
XM($UA;G5A;"`@("`@($U32#HH1FEL95-Y<W1E;7,I"@H*("`@("";,6U55$E,>
XM251)15,@"B`@("`@("`@("";,&U!('!R;V=R86T@8V%L;&5D()LS;6UE<W-Y*
XM9FUT()LP;6%L;&]W<R`@>6]U("!T;R`@9F]R;6%T("!D:7-K<R`@:6X*("`@9
XM("`@("`@(&UE<W-Y9&]S(&9O<FUA="X@(`H*("`@("`@("`@(%5S86=E.B!->
XM97-S>69M="`\=6YI=&YR/B`\9&5V:6-E/B`*"B`@("`@("`@("!4:&4@("`@D
XM/&1E=FEC93X@("!N86UE("`@:7,@("!O<'1I;VYA;"`@(&%N9"`@(&1E9F%UE
XM;'1S("`@=&\*("`@("`@("`@(")M97-S>61I<VLN9&5V:6-E(BX@5&AE('!R/
XM;V=R86T@87-K<R!F;W(@86QL("!P87)A;65T97)S("!T;PH@("`@("`@("`@)
XM<'5T(&EN('1H92!B;V]T8FQO8VLL(&QI:V4@"@H@("`@("`@("`@0GET97,@<
XM<&5R('-E8W1O<C\@(%LU,3)=(`H*("`@("`@("`@($EF("!Y;W4@(&IU<W0@L
XM(&AI="`@<F5T=7)N("!Y;W4@(&%C8V5P="`@=&AE("!D969A=6QT('9A;'5EU
XM+`H@("`@("`@("`@;W1H97)W:7-E('EO=2!C86X@96YT97(@82!N97<@=F%LK
XM=64@:6X@=&AE("!U<W5A;"`@;F]T871I;VXZ"B`@("`@("`@("`P>"`@/2`@Q
XM:&5X861E8VEM86PL("`P("`]("!O8W1A;"P@(&%N9"`@979E<GET:&EN9R`@%
XM96QS92`@:7,*("`@("`@("`@(&1E8VEM86PN("!!("!F97<@('-U9F9I>&5S\
XM("!A<F4@(&%L;&]W960@(&%S("!M=6QT:7!L:6-A=&EO;@H@("`@("`@("`@L
XM9F%C=&]R.B`@;2`@/2`@;65G82`@*#$P-#@U-S8I+"!K(#T@:VEL;R`H,3`R[
XM-"DL(',@/2!S96-T;W)S"B`@("`@("`@("`H-3$R*2!A;F0@8B`](&)Y=&4@U
XM*#$I+B`H3F]T(&%L;"!T97)M<R!M86ME('-E;G-E("!W:71H("!A;&P*("`@H
XM("`@("`@('%U97-T:6]N<RXI("!9;W4@(&UA>2`@8W)E871E("`X+"`@.2`@W
XM;W(@(#$P('-E8W1O<B!D:7-K<R!B>0H@("`@("`@("`@86YS=V5R:6YG('1H_
XM92!Q=65S=&EO;B`B4V5C=&]R<R!P97(@=')A8VLB(&%P<')O<')I871E;'DNZ
XM("`*("`@("`@("`@(%EO=2!A<F4@86QS;R!A<VME9"!I9B!Y;W4@=VES:"!TQ
XM;R!F;W)M870@=&AE('=H;VQE("!D:7-K("!O<@H@("`@("`@("`@;VYL>2`@0
XM=&AE("!F:7)S="!P87)T('=I=&@@=&AE(&)O;W1B;&]C:RP@1D%4(&%N9"!D:
XM:7)E8W1O<GDN"B`@("`@("`@("!&:6YA;&QY+"!T;R!S964@:68@>6]U(&%RC
XM92!S=&EL;"!A=V%K92P@>6]U(&UU<W0@96YT97(@-#(@:68*("`@("`@("`@%
XM('EO=2!A<F4@<W5R92!T;R!D;R!I="X@(`H@("`@("`@("`@069T97(@9F]RX
XM;6%T=&EN9R!H87,@8V]M<&QE=&5D+"!Y;W4@(&UU<W0@(')E;6]V92`@=&AEN
XM("!D:7-K"B`@("`@("`@("!F<F]M("!T:&4@(&1R:79E+"`@:6X@(&]R9&5RC
XM('1O(&QE="!A;&P@:6YV;VQV960@9FEL97-Y<W1E;7,*("`@("`@("`@(&MN#
XM;W<@=&AA="!T:&4@9&ES:R!J=7-T(&1I960@86YD(')E:6YC87)N871E9"X@P
XM(`H*("`@("`@("`@()LS;41I<VM#;W!Y()LP;6-A;B!B92!U<V5D('1O(&-O,
XM<'D@;65S<WED;W,@(&1I<VMS+"`@<')O=FED960@('EO=0H@("`@("`@("`@.
XM:&%V92!O;F4@(&]R(&UO<F4@9FEL92!S>7-T96US(&UO=6YT960N("!.;W1E2
XM+"!H;W=E=F5R+"!T:&%T"B`@("`@("`@("!$:7-K0V]P>2!L;V]K<R!A="!T*
XM:&4@9&ES:R!S:7IE(&EN9F]R;6%T:6]N(&%S(&ET(&ES('!R97-E;G0*("`@Q
XM("`@("`@(&EN('1H92!-;W5N=&QI<W0N("!4:&5R969O<F4@($1I<VM#;W!Y_
XM("!W:6QL("!N;W0@(&-O<'D@('1H90H@("`@("`@("`@96YT:7)E(&1I<VL@!
XM:68@:70@:7,@,3`M<V5C=&]R('=H:6QE('1H92!-;W5N=&QI<W0@8VQA:6USH
XM(&ET"B`@("`@("`@("!I<R`@.2US96-T;W(N($EN('1H92!O<'!O<VET92!SE
XM:71U871I;VXL(&ET('=I;&P@=')Y('1O(&-O<'D*("`@("`@("`@('1O;R!MT
XM=6-H('=H:6-H('=I;&P@<F5S=6QT(&EN(')E860@97)R;W)S+"!W:&EC:"`@9
XM;6%Y("!C875S90H@("`@("`@("`@=&AE(&QA<W0@('1R86-K(&YO="!T;R!B"
XM92!C;W!I960N("!9;W4@8V%N(&-O;G-T<G5C="!S<&5C:6%L"B`@("`@("`@&
XM("!-;W5N=&QI<W0@96YT<FEE<R!F;W(@."!O<B`Q,"!S96-T;W(@9&ES:W,@X
XM:68@('EO=2`@<&QA;B`@=&\*("`@("`@("`@($1I<VM#;W!Y('1H96T[('1HO
XM97)E(&ES(&YO(&YE960@=&\@<F5A;&QY(&UO=6YT('1H97-E+B`@"@H@("`@K
XM()LQ;512041%34%22U,@"B`@("`@("`@("";,&U!;6EG82P@("`@($%M:6=AS
XM1$]3+"`@("!7;W)K8F5N8V@@("`@87)E("`@('1R861E;6%R:W,@("`@;V8*Z
XM("`@("`@("`@($-O;6UO9&]R92U!;6EG82P@26YC+B!-97-S>61O<R!I<R!P(
XM<F5S=6UA8FQY(&$@=')A9&5M87)K("!O9@H@("`@("`@("`@365S<WE3;V9T\
XM+"!);F,N("`*"B`@("`@FS%M05542$]2(`H@("`@("`@("`@FS!M5&AE("!M$
XM97-S>2`@9FEL92!S>7-T96T@:&%N9&QE<B!I<R!W<FET=&5N(&)Y()LS;5-OH
XM=7)C97)E<B";,&U/;&%F"B`@("`@("`@("";,VU2:&EA;'1O()LP;5-E:6)EJ
XM<G0N("`*"@H*"@H*"@H*"@H*"B`@("`@2V]S;6]3;V9T("`@("`@("`@("`@E
XM("`@("`@("`@("`@+38M("`@("`@("`@("`@("`@("`@("`@(%9E<G-I;VX@6
X&,S0N-`H*=
X``
Xend
Xsize 18456
END_OF_FILE
if test 25877 -ne `wc -c <'doc/msh.man.uu'`; then
    echo shar: \"'doc/msh.man.uu'\" unpacked with wrong size!
fi
# end of 'doc/msh.man.uu'
fi
if test -f 'src/hanfile.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/hanfile.c'\"
else
echo shar: Extracting \"'src/hanfile.c'\" \(20226 characters\)
sed "s/^X//" >'src/hanfile.c' <<'END_OF_FILE'
X/*-
X * $Id: hanfile.c,v 1.6 90/02/10 21:38:26 Rhialto Exp $
X * $Log:	hanfile.c,v $
X * Revision 1.6  90/02/10  21:38:26  Rhialto
X * Optimized 12-bit fat unpacking.
X * 
X * Revision 1.5  90/01/27  20:26:51  Rhialto
X * Fixed ATTR_ARCHIVED bit in MSWrite()
X *
X * Revision 1.4  90/01/23  02:32:23  Rhialto
X * Add 16-bit FAT support.
X *
X * Revision 1.3  90/01/23  00:39:04  Rhialto
X * Always return -1 on MSWrite error.
X *
X * Revision 1.2  89/12/17  23:04:39  Rhialto
X * Add ATTR_READONLY support
X *
X * Revision 1.1  89/12/17  20:03:11  Rhialto
X * Initial revision
X *
X * HANFILE.C
X *
X * The code for the messydos file system handler.
X *
X * This parts handles files and the File Allocation Table.
X *
X * This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
X * May not be used or copied without a licence.
X-*/
X
X#include "han.h"
X#include "dos.h"
X
X#ifdef DEBUG
X#   define	debug(x)  dbprintf x
X#else
X#   define	debug(x)
X#endif
X
Xextern char	DotDot[1 + 8 + 3];
X
X/*
X * Read the FAT from the disk, and count the free clusters.
X */
X
Xint
XGetFat()
X{
X    int 	    i;
X    byte	   *secptr;
X
X    if (!Fat && !(Fat = AllocMem((long) Disk.bps * Disk.spf, BufMemType))) {
X	debug(("No memory for FAT\n"));
X	return 0;
X    }
X    FatDirty = FALSE;
X    for (i = 0; i < Disk.spf; i++) {
X	if (secptr = GetSec(Disk.res + i)) {
X	    CopyMem(secptr, Fat + i * Disk.bps, (long) Disk.bps);
X	    FreeSec(secptr);
X	} else {
X	    /* q&d way to set the entire FAT to FAT_EOF */
X	    setmem(Fat + i * Disk.bps, (int) Disk.bps, FAT_EOF);        /* 0xFF */
X	}
X    }
X
X    debug(("counting free clusters\n"));
X
X    Disk.nsectsfree = 0;
X    for (i = MS_FIRSTCLUST; i <= Disk.maxclst; i++) {
X	if (GetFatEntry((word) i) == FAT_UNUSED)
X	    Disk.nsectsfree += Disk.spc;
X    }
X
X    return 1;
X}
X
Xvoid
XFreeFat()
X{
X    if (Fat) {
X	FreeMem(Fat, (long) Disk.bps * Disk.spf);
X	Fat = NULL;
X	FatDirty = FALSE;
X    }
X}
X
X/*-
X *  The FAT consists of 12-bits entries for each cluster,
X *  indicating the next cluster in the chain, or FFF for EOF.
X *
X *  Every two entries are packed in three bytes, like this:
X *
X *  Two entries 	abc  123 (for one cluster and the next)
X *  are packed as	bc 3a 12
X-*/
X
Xword
XGetFatEntry(cluster)
Xword		cluster;
X{
X    if (!Fat && !GetFat())
X	return FAT_EOF;
X
X    if (Disk.fat16bits) {
X	return OtherEndianWord(((word *)Fat)[cluster]);
X    } else {
X	register int	offset = 3 * (cluster / 2);
X	register word	twoentries;
X
X	if (cluster & 1) {
X	    twoentries = Fat[offset + 1] >> 4;
X	    twoentries |= Fat[offset + 2] << 4;
X	} else {
X	    twoentries = Fat[offset];
X	    twoentries |= (Fat[offset + 1] & 0x0F) << 8;
X	}
X
X	/*
X	 * Convert the special values 0xFF0 .. 0xFFF to 16 bits so they
X	 * can be checked consistently.
X	 */
X	if (twoentries >= 0xFF0)
X	    twoentries |= 0xF000;
X
X	return twoentries;
X    }
X}
X
X#ifndef READONLY
X
Xvoid
XSetFatEntry(cluster, value)
Xword		cluster;
Xword		value;
X{
X    if (!Fat && !GetFat())
X	return;
X
X    if (Disk.fat16bits) {
X	((word *)Fat)[cluster] = OtherEndianWord(value);
X    } else {
X	register int	offset = 3 * (cluster / 2);
X
X	if (cluster & 1) {          /* 123 kind of entry */
X	    Fat[offset + 2] = value >> 4;
X	    Fat[offset + 1] &= 0x0F;
X	    Fat[offset + 1] |= (value & 0x0F) << 4;
X	} else {		    /* abc kind of entry */
X	    Fat[offset + 0] = value;
X	    Fat[offset + 1] &= 0xF0;
X	    Fat[offset + 1] |= (value >> 8) & 0x0F;
X	}
X    }
X
X    FatDirty = TRUE;
X}
X
X/*
X * Find a free cluster to install as the one following this one. Start
X * looking for it right after the given one, so we allocate the cluster
X * chain as contiguous as possible. If we run off the end of the disk, we
X * start again at the beginning. The termination test should not be
X * necessary (and won't work if we are given MSFIRSTCLUST - 1) but won't
X * harm either.
X */
X
Xword
XFindFreeCluster(prev)
Xword		prev;
X{
X    register word   i;
X
X    if (prev == 0 || prev == FAT_EOF)
X	prev = MS_FIRSTCLUST - 1;
X
X    if (Disk.nsectsfree >= Disk.spc) {
X	for (i = prev + 1; i != prev; i++) {
X	    if (i > Disk.maxclst)       /* Wrap around */
X		i = MS_FIRSTCLUST;
X	    if (GetFatEntry(i) == FAT_UNUSED) {
X		SetFatEntry(i, FAT_EOF);
X		if (prev >= MS_FIRSTCLUST)
X		    SetFatEntry(prev, i);
X		Disk.nsectsfree -= Disk.spc;
X		return i;
X	    }
X	}
X    }
X    return FAT_EOF;
X}
X
X/*
X * Add a cluster to a cluster chain. For input, we get some cluster we
X * know that is on the chain, even if it is the first one.
X */
X
Xword
XExtendClusterChain(cluster)
Xregister word	cluster;
X{
X    register word   nextcluster;
X
X    /*
X     * Find the end of the cluster chain to tack the new cluster on to.
X     * Then FindFreeCluster will (or won't) extend the chain for us.
X     */
X    if (cluster != 0)
X	while ((nextcluster = NextCluster(cluster)) != FAT_EOF) {
X	    cluster = nextcluster;
X	}
X
X    return FindFreeCluster(cluster);
X}
X
X/*
X * Free a chain of clusters by setting their FAT entries to FAT_UNUSED.
X */
X
Xvoid
XFreeClusterChain(cluster)
Xregister word	cluster;
X{
X    register word   nextcluster;
X
X    while (cluster != FAT_EOF) {
X	nextcluster = NextCluster(cluster);
X	SetFatEntry(cluster, FAT_UNUSED);
X	Disk.nsectsfree += Disk.spc;
X	cluster = nextcluster;
X    }
X}
X
X#endif				/* READONLY */
X
X/*
X * This routine opens a file.
X */
X
Xstruct MSFileHandle *
XMSOpen(parentdir, name, mode)
Xstruct MSFileLock *parentdir;
Xchar	       *name;
Xlong		mode;
X{
X    struct MSFileLock *fl;
X    struct MSFileHandle *fh = NULL;
X    long	    lockmode;
X
X    switch (mode) {
X    case MODE_NEWFILE:
X    case MODE_READWRITE:
X	lockmode = EXCLUSIVE_LOCK ^ MODE_CREATEFILE;
X	break;
X    default:
X	mode = MODE_OLDFILE;
X    case MODE_OLDFILE:
X	lockmode = SHARED_LOCK;
X    }
X
X    if (fl = MSLock(parentdir, name, lockmode)) {
Xmakefh:
X	if (fl->msfl_Msd.msd_Attributes & ATTR_DIR) {
X	    error = ERROR_OBJECT_WRONG_TYPE;
X	    MSUnLock(fl);
X	} else if (fh = AllocMem((long) sizeof (*fh), MEMF_PUBLIC)) {
X#ifndef READONLY
X	    /* Do we need to truncate the file? */
X	    if (mode == MODE_NEWFILE && fl->msfl_Msd.msd_Cluster) {
X		FreeClusterChain(fl->msfl_Msd.msd_Cluster);
X		fl->msfl_Msd.msd_Cluster = 0;
X		fl->msfl_Msd.msd_Filesize = 0;
X		UpdateFileLock(fl);
X	    }
X#endif
X	    fh->msfh_Cluster = fl->msfl_Msd.msd_Cluster;
X	    fh->msfh_SeekPos = 0;
X	    fh->msfh_FileLock = fl;
X	} else {
X	    error = ERROR_NO_FREE_STORE;
X	    MSUnLock(fl);
X	}
X	return fh;
X    }
X#ifndef READONLY
X    /*
X     * If the file was not found, see if we can make a new one. Therefore
X     * we need to have an empty spot in the desired directory, and create
X     * an MSFileLock for it.
X     */
X
X    if (!(lockmode & MODE_CREATEFILE) && (fl = EmptyFileLock)) {
X	debug(("Creating new file\n"));
X	EmptyFileLock = NULL;
X	fl->msfl_Msd.msd_Attributes = ATTR_ARCHIVED;
X	UpdateFileLock(fl);
X
X	goto makefh;
X    }
X    if (EmptyFileLock) {
X	MSUnLock(EmptyFileLock);
X	EmptyFileLock = NULL;
X    }
X#endif
X
X    return NULL;
X}
X
Xvoid
XMSClose(fh)
Xregister struct MSFileHandle *fh;
X{
X    if (fh) {
X	MSUnLock(fh->msfh_FileLock);
X	FreeMem(fh, (long) sizeof (*fh));
X    }
X}
X
Xlong
XMSSeek(fh, position, mode)
Xstruct MSFileHandle *fh;
Xlong		position;
Xlong		mode;
X{
X    long	    oldpos = fh->msfh_SeekPos;
X    long	    newpos = oldpos;
X    long	    filesize = fh->msfh_FileLock->msfl_Msd.msd_Filesize;
X    word	    cluster = fh->msfh_Cluster;
X    word	    oldcluster;
X    word	    newcluster;
X
X    switch (mode) {
X    case OFFSET_BEGINNING:
X	newpos = position;
X	break;
X    case OFFSET_CURRENT:
X	newpos += position;
X	break;
X    case OFFSET_END:
X	newpos = filesize - position;
X	break;
X    }
X
X    if (newpos < 0 || newpos > filesize) {
X	error = ERROR_SEEK_ERROR;
X	return -1;
X    }
X    newcluster = newpos / Disk.bpc;
X    oldcluster = oldpos / Disk.bpc;
X
X    if (oldcluster > newcluster) {      /* Seek backwards */
X	cluster = fh->msfh_FileLock->msfl_Msd.msd_Cluster;
X	oldcluster = 0;
X    }
X    if (oldcluster < newcluster) {
X	if (CheckLock(fh->msfh_FileLock))
X	    return -1L;
X	while (oldcluster < newcluster) {
X	    cluster = NextCluster(cluster);
X	    oldcluster++;
X	}
X    }
X    fh->msfh_Cluster = cluster;
X    fh->msfh_SeekPos = newpos;
X
X    return oldpos;
X}
X
Xlong
XMSRead(fh, userbuffer, size)
Xregister struct MSFileHandle *fh;
Xregister byte  *userbuffer;
Xregister long	size;
X{
X    long	    oldsize;
X
X    if (CheckLock(fh->msfh_FileLock))
X	return -1L;
X
X    if (fh->msfh_SeekPos + size > fh->msfh_FileLock->msfl_Msd.msd_Filesize)
X	size = fh->msfh_FileLock->msfl_Msd.msd_Filesize - fh->msfh_SeekPos;
X
X    oldsize = size;
X
X    while (size > 0) {
X	word		offset;
X	word		sector;
X	byte	       *diskbuffer;
X	long		insector;
X	long		tocopy;
X
X	offset = fh->msfh_SeekPos % Disk.bpc;
X	sector = ClusterOffsetToSector(fh->msfh_Cluster, (word) offset);
X	if (diskbuffer = GetSec(sector)) {
X	    offset %= Disk.bps;
X	    insector = Disk.bps - offset;
X	    tocopy = lmin(size, insector);
X
X	    CopyMem(diskbuffer + offset, userbuffer, tocopy);
X	    userbuffer += tocopy;
X	    size -= tocopy;
X	    FreeSec(diskbuffer);
X	    /* MSSeek(fh, tocopy, (long) OFFSET_CURRENT); */
X	    if ((fh->msfh_SeekPos += tocopy) % Disk.bpc == 0)
X		fh->msfh_Cluster = NextCluster(fh->msfh_Cluster);
X	} else {		/* Read error. Return amount successfully
X				 * read, if any. Else return -1 for error. */
X	    if (size == oldsize) {
X		return -1L;
X	    }
X	    return oldsize - size;
X	}
X    }
X
X    return oldsize;
X}
X
Xlong
XMSWrite(fh, userbuffer, size)
Xregister struct MSFileHandle *fh;
Xregister byte  *userbuffer;
Xregister long	size;
X{
X#ifdef READONLY
X    return -1;
X#else
X    long	    oldsize;
X    struct MSFileLock *fl = fh->msfh_FileLock;
X    word	    prevclust = fl->msfl_Msd.msd_Cluster;
X    word	    update = 0;
X
X    if (CheckLock(fl))
X	return -1;
X
X    if (fl->msfl_Msd.msd_Attributes & ATTR_READONLY) {
X	error = ERROR_WRITE_PROTECTED;
X	return -1;
X    }
X
X    oldsize = size;
X
X    while (size > 0) {
X	/*
X	 * Do we need to extend the file?
X	 */
X
X	if (fh->msfh_Cluster == 0 || fh->msfh_Cluster == FAT_EOF) {
X	    word	    newclust;
X
X	    newclust = ExtendClusterChain(prevclust);
X	    debug(("Extend with %d\n", newclust));
X	    if (newclust != FAT_EOF) {
X		if (prevclust == 0) {   /* Record first cluster in dir */
X		    fl->msfl_Msd.msd_Cluster = newclust;
X		}
X		fh->msfh_Cluster = newclust;
X		prevclust = newclust;
X	    } else {
X		error = ERROR_DISK_FULL;
X		goto error;
X	    }
X	}
X	{
X	    word	    offset;
X	    word	    sector;
X	    byte	   *diskbuffer;
X	    long	    insector;
X	    long	    tocopy;
X
X	    offset = fh->msfh_SeekPos % Disk.bpc;
X	    sector = ClusterOffsetToSector(fh->msfh_Cluster, (word) offset);
X	    offset %= Disk.bps;
X	    insector = Disk.bps - offset;
X	    tocopy = lmin(size, insector);
X
X	    if (tocopy == Disk.bps)
X		diskbuffer = EmptySec(sector);
X	    else
X		diskbuffer = GetSec(sector);
X
X	    if (diskbuffer != NULL) {
X		CopyMem(userbuffer, diskbuffer + offset, tocopy);
X		userbuffer += tocopy;
X		size -= tocopy;
X		MarkSecDirty(diskbuffer);
X		FreeSec(diskbuffer);
X		/* MSSeek(fh, tocopy, (long) OFFSET_CURRENT); */
X		if ((fh->msfh_SeekPos += tocopy) % Disk.bpc == 0)
X		    fh->msfh_Cluster = NextCluster(fh->msfh_Cluster);
X		if (fh->msfh_SeekPos > fl->msfl_Msd.msd_Filesize)
X		    fl->msfl_Msd.msd_Filesize = fh->msfh_SeekPos;
X		fl->msfl_Msd.msd_Attributes |= ATTR_ARCHIVED;
X		update = 1;
X	    } else {		/* Write error. */
X	error:
X		if (update)
X		    UpdateFileLock(fl);
X#if 1
X		return -1;	/* We loose the information about how much
X				 * data we wrote, but the standard file system
X				 * seems to do it this way. */
X#else
X		if (size == oldsize) {
X		    return -1;
X		}
X		return oldsize - size;	/* Amount successfully written */
X#endif
X	    }
X	}
X    }
X
X    if (update)
X	UpdateFileLock(fl);
X
X    return oldsize;
X#endif
X}
X
Xlong
XMSDeleteFile(parentdir, name)
Xstruct MSFileLock *parentdir;
Xbyte	       *name;
X{
X#ifdef READONLY
X    return DOSFALSE;
X#else
X    register struct MSFileLock *fl;
X
X    fl = MSLock(parentdir, name, EXCLUSIVE_LOCK);
X    if (fl) {
X	if (fl->msfl_Msd.msd_Attributes & ATTR_READONLY) {
X	    error = ERROR_DELETE_PROTECTED;
X	    goto error;
X	}
X	if (fl->msfl_Msd.msd_Attributes & ATTR_DIRECTORY) {
X	    struct FileInfoBlock fib;
X
X	    /*
X	     * We normally can't get REAL exclusive locks on directories,
X	     * so we check here just to be sure. We don't want to delete
X	     * anyone's current directory, do we?
X	     */
X
X	    if (fl->msfl_Refcount != 1 || fl == RootLock) {
X		error = ERROR_OBJECT_IN_USE;
X		goto error;
X	    }
X	    if (MSExamine(fl, &fib) &&  /* directory itself */
X		MSExNext(fl, &fib)) {   /* should fail */
X		if (error == 0) {
X	    not_empty:
X		    error = ERROR_DIRECTORY_NOT_EMPTY;
X	    error:
X		    MSUnLock(fl);
X		    return DOSFALSE;
X		}
X	    }
X	    if (error != ERROR_NO_MORE_ENTRIES)
X		goto error;
X
X	    error = 0;
X	}
X	if (fl->msfl_Msd.msd_Cluster)
X	    FreeClusterChain(fl->msfl_Msd.msd_Cluster);
X	fl->msfl_Msd.msd_Name[0] = DIR_DELETED;
X	WriteFileLock(fl);
X	MSUnLock(fl);
X
X	return DOSTRUE;
X    }
X    return DOSFALSE;
X#endif
X}
X
Xlong
XMSSetDate(parentdir, name, datestamp)
Xstruct MSFileLock *parentdir;
Xbyte	       *name;
Xstruct DateStamp *datestamp;
X{
X#ifdef READONLY
X    return DOSFALSE;
X#else
X    register struct MSFileLock *fl;
X
X    fl = MSLock(parentdir, name, EXCLUSIVE_LOCK);
X    if (fl) {
X	ToMSDate(&fl->msfl_Msd.msd_Date, &fl->msfl_Msd.msd_Time, datestamp);
X	WriteFileLock(fl);
X	MSUnLock(fl);
X
X	return DOSTRUE;
X    }
X    return DOSFALSE;
X#endif
X}
X
X/*
X * Create a new directory, with its own initial "." and ".." entries.
X */
X
Xstruct MSFileLock *
XMSCreateDir(parentdir, name)
Xstruct MSFileLock *parentdir;
Xbyte	       *name;
X{
X#ifdef READONLY
X    return DOSFALSE;
X#else
X    register struct MSFileLock *fl;
X
X    /*
X     * Go create a new file. If we fail later, we have an empty file that
X     * we delete again.
X     */
X
X    fl = MSLock(parentdir, name, EXCLUSIVE_LOCK ^ MODE_CREATEFILE);
X    if (fl || error == ERROR_OBJECT_IN_USE) {
X	error = ERROR_OBJECT_EXISTS;
X	goto error;
X    }
X    if (error != 0) {
X	goto error;
X    }
X    if (fl = EmptyFileLock) {
X	debug(("Creating new dir\n"));
X	EmptyFileLock = NULL;
X	if ((fl->msfl_Msd.msd_Cluster = FindFreeCluster(FAT_EOF)) != FAT_EOF) {
X	    struct MsDirEntry direntry;
X	    byte	   *sec;
X	    word	    sector;
X
X	    sector = ClusterToSector(fl->msfl_Msd.msd_Cluster);
X	    sec = EmptySec(sector);
X	    if (sec == NULL)
X		goto error_no_free_store;
X	    setmem(sec, (int) Disk.bps, 0);
X
X	    /*
X	     * Turn the file into a directory.
X	     */
X	    fl->msfl_Msd.msd_Attributes = ATTR_DIRECTORY;
X	    UpdateFileLock(fl);
X
X	    /*
X	     * Create the "." entry.
X	     */
X	    direntry = fl->msfl_Msd;
X	    strncpy(direntry.msd_Name, DotDot + 1, 8 + 3);
X	    OtherEndianMsd(&direntry);
X	    ((struct MsDirEntry *) sec)[0] = direntry;
X
X	    /*
X	     * Get the real parent directory because we will duplicate the
X	     * directory entry in the subdirectory.
X	     */
X
X	    parentdir = MSParentDir(fl);
X	    if (parentdir == NULL)      /* Cannot happen */
X		parentdir = MSDupLock(RootLock);
X
X	    /*
X	     * Create the ".." entry.
X	     */
X	    direntry = parentdir->msfl_Msd;
X	    strncpy(direntry.msd_Name, DotDot, 8 + 3);
X	    direntry.msd_Attributes = ATTR_DIRECTORY;
X	    OtherEndianMsd(&direntry);
X	    ((struct MsDirEntry *) sec)[1] = direntry;
X
X	    MSUnLock(parentdir);
X
X	    MarkSecDirty(sec);
X	    FreeSec(sec);
X
X	    /*
X	     * Clear out the rest of the newly created directory.
X	     */
X
X	    while ((sector = NextClusteredSector(sector)) != SEC_EOF) {
X		sec = EmptySec(sector);
X		if (sec == NULL)
X		    goto error_no_free_store;
X		setmem(sec, (int) Disk.bps, 0);
X		MarkSecDirty(sec);
X		FreeSec(sec);
X	    }
X	} else {
X	    MSUnLock(fl);
X	    fl = NULL;
X	    MSDeleteFile(parentdir, name);
X	    error = ERROR_DISK_FULL;
X	}
X    }
X    if (EmptyFileLock) {
X	MSUnLock(EmptyFileLock);
X	EmptyFileLock = NULL;
X    }
X    return fl;
X
Xerror_no_free_store:
X    error = ERROR_NO_FREE_STORE;
Xerror:
X    if (fl)
X	MSUnLock(fl);
X    return DOSFALSE;
X#endif
X}
X
X/*
X * Rename a file or directory, possibly moving it to a different
X * directory.
X *
X * "Tuned" to also work in full directories by first deleting the source
X * name, then look for a slot to put the destination name. If that fails,
X * we undo the deletion. By playing with the cache, we even avoid a write
X * of the sector with the undeleted entry.
X */
X
Xlong
XMSRename(slock, sname, dlock, dname)
Xstruct MSFileLock *slock;
Xbyte	       *sname;
Xstruct MSFileLock *dlock;
Xbyte	       *dname;
X{
X#ifdef READONLY
X    return DOSFALSE;
X#else
X    struct MSFileLock *sfl;
X    struct MSFileLock *dfl;
X    long	    success;
X    struct CacheSec *scache;
X    ulong	    oldstatus;
X
X    success = DOSFALSE;
X    scache = NULL;
X    dfl = NULL;
X
X    sfl = MSLock(slock, sname, SHARED_LOCK);
X    if (sfl == NULL || sfl == RootLock)
X	goto error;
X
X    /*
X     * Now we are going to pull a dirty trick with the cache. We are going
X     * to temporarily delete the source file, in the chache only, and
X     * undelete it again if we cannot create the new name. And above all
X     * we want to avoid unnecessary writes if we decide not to do the
X     * deletion after all.
X     */
X    {
X	byte	       *sec;
X	byte		old;
X
X	if ((sec = GetSec(sfl->msfl_DirSector)) == NULL)
X	    goto error;
X	scache = FindSecByBuffer(sec);
X	oldstatus = scache->sec_Refcount;
X
X	old = sfl->msfl_Msd.msd_Name[0];
X	sfl->msfl_Msd.msd_Name[0] = DIR_DELETED;
X	WriteFileLock(sfl);
X	sfl->msfl_Msd.msd_Name[0] = old;
X
X	/*
X	 * Don't FreeSec it yet; we don't want it written out to disk.
X	 */
X    }
X
X    /*
X     * Now we have freed the directory entry of the source name, we might
X     * be able to use it for the destination name. But only if we also
X     * temporarily hide the MSFileLock on that spot. Gross hack ahead!
X     */
X
X    sfl->msfl_DirOffset = ~sfl->msfl_DirOffset;
X    dfl = MSLock(dlock, dname, EXCLUSIVE_LOCK ^ MODE_CREATEFILE);
X    sfl->msfl_DirOffset = ~sfl->msfl_DirOffset;
X
X    if (dfl != NULL || error == ERROR_OBJECT_IN_USE) {
X	error = ERROR_OBJECT_EXISTS;
X	goto undelete;
X    }
X    dfl = EmptyFileLock;
X    EmptyFileLock = NULL;
X    if (dfl == NULL) {
X	/*
X	 * Sigh, we could not create the new name. But because of that, we
X	 * are sure that we need to write nothing to the disk at all. So
X	 * we can safely reset the sector-dirty flag to what it was
X	 * before, if we also restore the cached sector.
X	 */
Xundelete:
X	WriteFileLock(sfl);
X	scache->sec_Refcount = oldstatus;
X	goto error;
X    }
X    /*
X     * Now, if the moved entry was a directory, and it was moved to a
X     * different directory, we need to adapt its "..", which is the second
X     * entry.
X     */
X
X    if (sfl->msfl_Msd.msd_Attributes & ATTR_DIRECTORY &&
X	sfl->msfl_Parent != dfl->msfl_Parent) {
X	struct MSFileLock *parentdir;
X	struct MsDirEntry *dir;
X
X	if (dir = (struct MsDirEntry *)
X	    GetSec(DirClusterToSector(sfl->msfl_Msd.msd_Cluster))) {
X	    parentdir = MSParentDir(dfl);
X	    /*
X	     * Copy everything except the name which must remain "..". But
X	     * first a quick consistency check...
X	     */
X	    debug(("Creating new \"..\"  "));
X	    if (dir[1].msd_Name[1] == '.') {
X		CopyMem(&parentdir->msfl_Msd.msd_Attributes,
X			&dir[1].msd_Attributes,
X			(long) sizeof (struct MsDirEntry) -
X			OFFSETOF(MsDirEntry, msd_Attributes));
X		dir[1].msd_Attributes = ATTR_DIRECTORY;
X		OtherEndianMsd(&dir[1]);
X		MarkSecDirty(dir);
X	    }
X#ifdef DEBUG
X	    else
X		debug(("!!! No \"..\" found ??\n"));
X#endif
X	    MSUnLock(parentdir);
X	    FreeSec(dir);
X	}
X    }
X    /*
X     * Move the name from the new entry to the old filelock. We do this
X     * for the case that somebody else has a lock on the (possibly moved)
X     * file/directory. Also move the other administration.
X     */
X
X    strncpy(sfl->msfl_Msd.msd_Name, dfl->msfl_Msd.msd_Name, 8 + 3);
X    sfl->msfl_DirSector = dfl->msfl_DirSector;
X    sfl->msfl_DirOffset = dfl->msfl_DirOffset;
X    /*
X     * Free the old, and get the new parent directory. They might be the
X     * same, of course...
X     */
X    MSUnLock(sfl->msfl_Parent);
X    sfl->msfl_Parent = dfl->msfl_Parent;
X    dfl->msfl_Parent = NULL;
X    sfl->msfl_Msd.msd_Attributes &= ~ATTR_ARCHIVED;
X    WriteFileLock(sfl);         /* Write the new name; the old name
X				 * already has been deleted. */
X    success = DOSTRUE;
X
Xerror:
X    if (sfl)
X	MSUnLock(sfl);
X    if (dfl)
X	MSUnLock(dfl);
X    if (scache)
X	FreeSec(scache->sec_Data);
X
X    return success;
X#endif
X}
END_OF_FILE
if test 20226 -ne `wc -c <'src/hanfile.c'`; then
    echo shar: \"'src/hanfile.c'\" unpacked with wrong size!
fi
# end of 'src/hanfile.c'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    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.