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.