hAPm@#Ap?# A># ># ># /># >#0>#>#W>#>#># ># ! >#"#$%K>#&' >#()*+/>#,>#->#./P>#0j>#12>#34%>#56>#78H>#9:>#;A?#<?#=>?@ABCE?#FGz ?#HIJw ?#KLMNOPQSt?#TUVWXYZ5?#[$?#\]^_`abdAE?#g9?#hi :?#jklm';?#no =?#pqr??#stuv@?#wxB?#yz{ C?#|}~E?# F?#A`p?#db?#d?#km?#Kx?#A?#o?#?#?#b?#?#M?#?#?#A`?#z\?# ?#=9?#     m?#!m@#U@#V@#W@#W@#X@#Y@#Z@#Z@#[@#\@#]@#^@#^@#_@#`@#a@#b@#b@#c@#d@#e@#f@#j@#g@#h@#...commands<docinclude...bindis88#make.mined3sh...tail.c.Ztar.c.Ztee.c.Zterm.c.Ztermcap.c.Z test.c.Z time.c.Z touch.c.Z tr.c.Z traverse.c.Ztreecmp.c.Ztset.c.Ztsort.c.Ztty.c.Zumount.c.Zuniq.c.Zupdate.c.Zuudecode.c.Zuuencode.c.Zvol.c.Zwc.c.Zwho.c.Zwhoami.c.Z/T& -@ hʀ( 7f@aƠD/(p :d$CL7.TT)"26% d O?$% NDMg!Q9A&'E0ꆫT4aC۸ 1cf*F$ҥ6ݠ{fL[vRuQNcv.(A4黛Ṷkڴ$Lxhö*̼CE ֭Iue )CG,ֹߣWn"vVڛs{ȹvA -x1)obBWAARCmg9]xA 0,h_k}T^|Yf{ځЂT|Yz1 Ղ jp.C0He 7C9 C:h~ F(xFd#V)fkw]LdTQ ٙxfl`TcHcwz:G%WF|%~Yˁh #p6)WU01BjBh=]rіƭwqt$l cp͑!1f`vGx{JZz:NxʐCD PaQƮ /u!]l]EGlLڅ"<+&[ާ`Ć.Qa~Vަ~moyi ":螩n${kFYF%1na'^\,ѡUQG܅WiIo,7vi~"f%["DvK1:T\:^/iÙegvi L9UMX W ݆;ªcT:ʎ'{1hgb~b]ۚnrF}Q% ’MyB癹@ŽbB''r0W9/,ɛ@XQWڊyED$#IU@' A (Â"dXz0lxpOW$#|A0Z `5nq'1(3! kbÙ`f8FDbh5ǜ8¡j"!ip'꞉(Zʣ9! |`@ uCÅ!{$l4zk$gB-ӄalBz`/:al)XЩ#qv<޴/yc@J~ s+ay&1/ kޙ7$AJo$,/)t zHiJV(5[&\G|Y` SL-Qo133gR .I}ҊљNJ3o[r?߉( *^ٚ2 ]C$dwA\Mr9tC(C5R_tE3!U(P }%qyȠp R8PD}*D*}Sf:/"O= ;)EkjZѤ&Lj媊:WT5* OR@2ΓxbTr*5kRPLgX1V e4C؊ DdT/TF)4i씑b:tмD4ӔaI4sԔB  2'̙2 2. IÆᖡEtQВ@!u4, .l('Ds4aC7lðΜ2eð 7gi3 9e”M5eINѠ B8$tX ę7aH7pYŜ$b$X@X+)[Ƨ1taf/\HWZ b7dHǯ[iNanUdެts"øɓ13 ż}e%7 U6FpD7ao!Q"5`UTYK `lAC<̑/БBC#x")ႌ4A("i ЉfPA L"1DU@ [1Tx S L#p&EADR|1EZYC 2y&CNDz)f 0]VC,U8ADRd2p Bnq{0%%TA_cvh]h tYQ[~T yJ]ud Q.1K'HauKψ -FI #X\Yޑݝ {ER-I,}^j2rL靀'%`P90HMl*(L5| 2Wh$ j8,a}XavUk8XNKNJ Hx_U# !/ k fERv*& JijLAT0KwcPp߅X_/ dY&@(Pf$Ρ5&2/;ќf5ә4bN `-I|˰lxK:ӿeb1njrX]5Ѳ{:}XZqz`$$#em5 ,H Z{X&)e<#W a G9E  :5_(\^Ӏ4]] z;[Rrx뎱@#a#>(лZ^d;j7 ~JI 9J)1 7<90]cUp`gw8%ve#pC#?Ί_-GFWdXضްg(n.דjq7{zLXzYnmWڟ;L1Hvpa'ܜXޜbwִ55wZ}zd7_Mv;&15]|C^r`ܩ NCq몐aR[.x뽹 AIML._vms9wi߰;1g%Zp<3tSggJssG&Yv<#@waB(pC?TMDD#iID90EEzuF"mzwGRwq7fq|Wro>,'.Dy+s> с%'qG/D}2X&Tkwk_'D>FCFlȳUWHZXti-ЄLT\+D}Ţ{TR,%$e$t!5'P0%@p@Dy}xZ䈫UMOKH[ [ `&@,ҴvNwM58bO|8:3'[RbX`Dp piT6[pp(@p.sFgyyhz5SYȱBTvRYX`tUQ0lsC6kdƍƱ;}s#/I")6d# 6IIii9XHEXvx&eahR*U!=wԅq9R'f QU- Xq.V#~0&c Zvh!=b&cWƀC(=0fH9l PIM%{Ҩ]yg8:Ge>ȗݔpYUҘdݴyY' ] JiiI*v[cksFv[j@T?ݸReFVNi9pseF&=ߴ,ٙJُ+, _ )MWyl!/ iɚiUu[qqKƚ  \mה*kv&g &p[c-Y;S"ʹ@n,Oڠp)=ji7j=sI#Ji5yI]YOsɔh,##S,ǂIR0\JM <'gV:g<z9z|n)F7v(z6J'PnoyVXś*8WfQY7\b^rwL?#dX&"zF@7%g!urtjqIBs؜թ>x&63>6U2!/Qj'_J,UIr ..C$J5n85+]Or6.[*ZJ[E [fOi:>YŒ\FqXc0 ㈖Zpvq8=Wirf۟9h׸$n~M/TS  ँcL:tҸ9 A:tм0ux|ÆL9m¸#$aS$m$B 7cI 4>`ʤi3n°9In$h" bx)3dpJˎ)%# 螱BAټuǼ.Kzݣ†Әa  ` 3oCBL3[0y2dɗ)Iq4xuv+vlWp;hҰ1870A0x]wD)@0N0C [Ǿ%F 34't$"rQfQYfK.Ud[!Ga|F~  o,9 s&mnAP 2'!CYQm>g^(zU ARH'ɁUQYd-a)cstn‡ C('}[p8@\`chiY ;BlFsH(=Rmfl^a BdΏe@ԙSpuD$N`g 1RA 4Sc޴&͘I8VN6o• c7vVL  A+L5:>s)7ca:ͤpuC'SIsMko  <Ě2yļQMmqƎ!SAt N6%ҁ=vvorwN|9ctAxl嗍 txf[6fFCI5AHqIndSa1L aaf(ZkVLuqJ 81E 1PI 0* :Q_LEE*D */ڋ@ F鬖zB$ANdYZP(GZ31KU"И/ęG "$`p1FnݹUqa]͉\*EL1006EZoԚXkYѷҊ)I\EE؂tf4OF ԸXCba(!7U8@CEWuoFsFh+z!iĕoc] euc1eZѱz:E  !B "D( {C"x 2 2N.b}@v:k5zޢ{%ӭbD}z?eP'&  1Fۑ?sSA&C24\M Q( 0< P ! KV7LswA[5 ^PBd PGO?ؤ ahHt748j D$ұd1A69~/ Ǟ́H#Ё ZKx"60py a"T2b9p Axf1D&:R<[i`p@L nS>,RmeAJ55B/ ZC!z`: =i;455DU XeO}V;'r`ah ߶@ ܧ:}ª5 04_cXC۾U:6ChI0 Wla[ (FnӤϊKmBpkFF٘ `tU?`%<Q1OTá%4:IV(Ը!0ժ^5vjWE`CY Xy WAW N=ީ 8^5+A*E4k  ʼrA8W͌ikEGWjԜg7BSȚuvF@9ɠ2 2B,ZVrM6FY^։ , |/siэ (m5AW[riӃ gQPTp&ux[tUjUV$_ !H̾SI$2%D%d$$6IBG=Ir0$%n]1Iz oM IgH2 d"w_8a/13i  b:oA% \-)Ź0Nza.mVҜl{TPE5}5:D(.u`M耗l&xnb@4Up'͖ٚpE7nP/J7BвЅn0 r@pg>DҤl9e[7~3DҗFOݳHky;3l7[ďn @S nݍL^xsRBG ] G\'Y Ys5Wwp%3cx "y73p plOslv@Q{tZ88)`BEdl4q mjk*lti>9Xb@kq&luvg;AkBAo@ ~F%fbo!SGTc7G/TSFN1ah4n ,x0!9eЁxfN uy#G*q3 $oش# aSKsI7G4!_T1b bA#A@SqD᠘:fLP4a 7bUrU_&Pn\!0nC"Cfٝq31h KbUI"כID{T"rʨU0b GQZu{ 'RM矵XIQFdxw%qYy` dxX_eV\yj[!0jf⊕oDдRםÊKQLb%m&oD%6f+殮z*bf1aAY밉Z͖Bsnt FG1!Ner qqo1ȋUA3{ |r`t (h"P1i6$3Sa m9u"P g$ #(-m5lkC^ȰoN"@9T}I'1pRH\2;7>O];\iE@фL($ImK䛤31pF۱Lj8xL!$H3'rq$_# CW(ok,E@^?+8\\'LER4C[)&T'iVӘ# !"xGr&;&AE=ydN DkLԚd'̍` 1(>M h8e҄ZWY*H4t 3iE׉S-="hOi ԐUHOk29>FB` k` ڠx !sI \CҦ;9oPuW nU+zQ\qY;6Nvo`cf̯y(V,6-qG: 6bl)C!5m[ `o [CوE>fQSVGQBE/C}hSL!(pjի6L<ʍ`2 9bwKՒ jy؁R. 08A|WS͐tA[PkܛP1k+00NDKa%tu$hػęB" P;C ܧ]WgdAMd.-AN|ԆDD'RNk'C`yHB~˰m%T[*gz\yNŽoSdJJ<,VŪӎ/TSf1Ra9i޸q4kʀѢ0uy#D9A gLTB4nưCF#9y漠NAh|ĩOB T͜;{yѪ X`Baƌ)Μh4yÆ͛;8π8#'L6aP 8r%86oD\rLj38 `9y@H.}:0Aw&:pэ븱h_:$A  $wXc.9rč_B3g)Dl;dNxō/oaf?sG~zj1Y~!LX_ ea`aWqCqxFK TDX`F"[e(ESX#tD `8idDLHAD1,YƐNBy `% <ɄSeaBĔ4IdLE5%TP v0Z }D P(EDD9,DT*h&QPY`jJŤTz jQfGCj$*Pg *+XNPI(BA&"1D+P!E`)oJQ~ʭFO@!S`pQF2٧R٧ֻ.o A/ ʮ:Q/~-a$Gc! Ah }At7HrHܱuUg}L<]И !+)a:p_ZJPMt~<:e!=&T7=-][]tZYEuk?B+12me=jq_=~rW6y>iF-jx DZ餙+.+ZD蓃ݕTĊqX9nJ;?]:xЛÆ8'zљ!lZ ;wx+{k do6 + }(Їg ^(B ` *gbo8g1Q,pp 0g h\,c <31Aң? c4$( D 0)8 6a8ÉP% f &Dɂ HP@0Ԑ~ `[#)R {VQb@:a"2T F2b$!:& R#* \Ld(Nf1R.~1amPcFZR|tccE&9Ҏ)#*}`| [CNDS(`GgHAml8Ɖ8ȀT$ax*jygJ)R1"+K Y#-MKWq61n23 JQtgcOh1$'r^\ϠlLʊ!d oHr86S n >QIHn%`&L5Ʀd` " ѡ'TcRiN?f1c4F1a0g/A1MfHWTUhU+[G(]MU9_ֵS"bu2Ɔԯ,d[Y[}k;C ҳH-h`-kn̡[2llND,>J Xmg[Cvm.mwGܹl/ꏐ-nb ȝly 3柈)D$`8թrUqў=9W׆mTp93@Q H`7bT H񊧨2 ="UF[1]Eҵ+D@c7αGg{')viY@&XpŴ+-joAY ٲbre5xegb '2]<ȝO80P( (kdSB*D14 0Nk3"gU=3gG_4}>5hXQ: 4MC˜2& fK ]@GӨOō>%E1x prm͈ sΖ.=WN1 GN/b꘹ ^ ~ Bo:upOCF<6oܜ)Ooeo$mč!h1vZeA 0 h&rAie@fT d:j?uoBe`B-$r& (`LiA@8 p'f,B ?B)^!(0DnYrњG. r ! Z0Z2Gc`% _&A@hսqaDlAGOaPFeL9 S$qDNPq[G|ySlkU$!,{FF 7]1LHCև?0Zd$c)~W.Kcp ۙtfC@$E9St!q!lz w )&B!yQzZukP+$m(iBD\Ə!E8ft Ϝ .H7ͩuWg=aE,V=M͝㊽z-j'7ut pz 8h?m f>=^֝Sƀ'@)˽a'qBnQyth|duZ_JBc{:G͞qmFid+]fҖ0GipCh!>~+cgi6'w# 0 6>#=ihP0/&Zpx%<~P&(@ pi%C D # `sB4w^ЀTa ih;p?`~, BX˭,Pߏ:a6M.)͖NuOV"Qh>!2f0F3q6.TcgfFq 5ph!EzG@b2!n܂ !\L$OJf 9$L6l吥twvC7'1*CNC16c{A7?%-mn-Q&1 XnJ?$'hoK'9l;)!0 PZg[hB`)P!CX*a ;G@ Dy`$D2 psQE b&sy(:!mԘȩ"X$@g#"!@ڦTK$^9՛h<(>UB[/G%|Se7gJ5Z0"'9bbee p(hApt  Fq3M2e@g :y L9tЩxQ A# 9eD ڄ"3cX=c'EL739Q* @TH4?fg`ٚQ蘝9)D8aq$敱p梫.PawWa%*f Y7iktSN3^%0Hr\tѵe/T0dp 7v8}MXЬmIs'$?*{ F|x"T`!X[0Fg!':h ^1tp!"0,ӏ/T#Dr¸& 2 Ơ pC9s$R7rthFb2l@ f2s@x *sœ)# --ƐiܜaR]( "a@ 6eڔqC3 ItdDAY!p:FXbLsɤuږj9"ĩSm갡+7H12͢UV]o̺E4k&)D!U)"˔$Z$C ٴm2eH$a̸qC:y"!O0فL H", &@(v E - (TZЧ&̺)I  *wADĪ`l0 `mJizAF hVZ5nd.bz[k+. 0,oﺴ!YYjtZ "OPEmARLLT]"P8)̩(}Xt1mIcƻ0p<|jsZ1-RAd5oR\.m-}c4lE)(¡aMOt4\zXdYfMwy>:f&kw pxٚ'F>/.Z{ Ԯ˶[8/G?l>}:{G5M 5\$(}wb*&HeKɧ)"vBe4(jA J@k;4O}59b|P}#nT k "a Q02mhģ4!Hwl*"V'2d  >dg=[mis;5y-m {!`7FKTو4&0`UWյ2n`L툥eՃXoJp@Z[c!]p$ 6,~'75jQpH(:+0A");ud:tP6*:"424-_KK,953"n"aH(dB3[ ))QGͣ@$"I * 9ɓu$ I;! `<5*Ӕ' |9ʡz0/B2C J&듟Z4kvSZQH u0@cE5Jyyӂ@ RLe z,w)"(-;! \;T#Wg)ZZh#ebUZ*\R#׮SuB#x HIR=ô Ұi_H@ԀZk Z˪Ku+\trXuY"P&zURHu4k.fUBuyu +[U _ Z6c.hM GKp u5Wág\{fWlow@/La iX5ڲ ՈtcI_W,9W `b);'O Îj`RO'DI؝_$Pe;kIضj- *S~G[?TzWmTɴ]-V8^wv$<8y/T#'2rb` qXLAAFG B6m¸#Ҹæ`ʤi/-z dF#4MVEfߌuMV+0g0v )_0VYgKbDe u 0pv,gF[L %x`&;< ~ӎ˴ 'PM>'b(B IqWNuҗw}>mڣdnG-hz4@$gi0h%* ҕuB 7>|@TB /m', ](.s0 O̠/T#L1mhb̛a f`2s$R7rtLT¸)FL:m@x@A@hGΛ3r,89ias!Ă;PhpJ2 Ig7 Ȥ1cLA7c0P D: USD9eȰa$2xaSf4,ASA 3AxtxoVKMC4jAw.-/i\qv \nF3.'b޽a*T뎑Kq&ilt-}8 si3QblG1ݕ: \ٙv1QF!SґQZ%-]_r~fYbI}Qv:$T[F`tmEFv%&'bc8%UERe}7y FR'͑GmAPcHGx :XQa}ȒzY xEWՑnJEenTvil@qn9\ahbeKiͱWLyҢ>']O;nՎeZYL XWO?JyƐ^aFىk8Z]Zfo>u#F ,fohDAaDnUNB mт]&G ]*x-jQ c/~'ewRvѤ;Fs0,.CM#xȦBTaIhQ4 ݄aƦbԡQ2єr+DX@H 8,ЯaDiAGbXݴ3] E8AmKM߁feщ[b?{p5Q&Gk8pAfygi̠z. [9|kr+Z՝ŮeY{4`QMas:cR.KvslIաRjRR٪g@ۉx/l:3po{ɏ"A: yPK{M,7ƳI>7vC'2y#Dʊ|eTkXZ5\\&y-&+ Nb2,n!W`D"/+XvbٟKlvf5I!10h'89/jMg1{Bゲesw!Dgh|f@ĶC6z{}H6q%(BCbJ8t pfQx9S8eZ\h^8/c]xfZvgwxvTabeR4veI{VR+Uioz(oȋ=~tXVPcdCŁ؄$t k pdZOWc5HvUweEkvU"?(+!2Lv#E89)f}+7ٷQd; %z@Id*>#0s+eddF0B{ɸ>' Y8l5 )B~!9DIPDc )1du=?WF`}UI"%F"@k(%86K'{y^C$ŲxQ'q;*`#SÅ1~n* i?Aɀ9I;&טo8i0y/+pdM)O9:uTh82N0{!. Yd)j ɚ&9%D,t'FY 雄zX*c,mywE.\"r){iٓ< f %Bw.; 9x)')Iyʛ  VfuDi6m6q9d|чdP`cՂg(ţp/u3&:);-ԢЇ|13:-6J-t؉_;r7 F`p(pi:Ѧ iFs~'L ;mZjʦrpt&zyʨ|ZI)9*F7'ԄwMl&P(3.%WN:|B| ."hVr|!> bJSΙ$#ŋۗEp|*~9!=}-AZ"rgJ] gv[4P =St'"s9?i `E;iPCګad153/5h/@ (jlDvA7Uf!F. .2~SfdI /T3 -@ĊXֲ67mo7jwld߶淬D0v 6jx [hMMdXSc„>g/}K`叄t0!`H8ʖG\r\/)C|2|)?8%AU)UܐLiP`B; !2'A D pHJr3[z ̀ĕݲJ\SdmnÌ!i{AКD8UICyZ#/T(9o7 | 7gҌ B ޸1LH9d)C0i i0m(^&]tUߒ&HWE(RxXRQFEdiԐ /0wE!ňxH*%_+ƝIdaQQ3d[ö~ (0BYcQGJ @ bl0<;FăyQhY&iJcNm)$*e  "0, s )|A4QE8 2]RH7MQS$ 20rac"?L{(j/4$*tR)Mxбw{+зo w78Ne._]m\ƒ勳 [4c]`){fGnqSNQ8b;&,:7l {H#k,AxH׻aWl1RL*P U- *C@6! ,üHAE dRd<`7bo4Ę!sB@H-t!qcA :6Ps]5,pk`םLOp*2Eay_:sS=g"P4̡q { Tƽ=NSIz9[/W3q r#7B`f+l -Ġ rה[4.`KL)vZX xr+ $O{D p"6H||NQd%\IVhUJY dbW{DD&"D*u`JKZCsf`OY>giCX5K2hLU[=}{Sevuc#DNeBjWص$˟o[r>nCS}.G8yZЅSy]ov`7!zW5SW ju[!3o_>R/zs(˸~7M,JmR*L6x%j :>ЊU-jK`ֺ_ik۲.MnoQ禮uyU(ZwHb#XSlM| iw̗Ų+QLg( /SwUqY0[XMmp10tnJC9a2h6,/Ψ`K_:6vUi2X{ې]/ V꺂ٸ]dҸV22FBȖ"-%g8mݎdN۰l4D*ͳ|3MaH#G+jͶm2[jխuh+_fuܒ{Գvppxbrko'v emk{%tjye>ĩNȝTrSAD?Q@-\iTܼr`hSX 2NB$!a`kАDP:Y! Ar4y>q 0\3: CSP`cԃ4$O ݯ[=,HQvXLVaLHz:泎AZ/rUv ;HgjumA jZe42H%R:4z횸>+SU`.ge=YxD DuYVWMuEG^'yAA LfgHvZzL0N@Tz{GUIu'|s8g P+;U!8#2!Tt"R+$4zT 2^8鶁lf~ˑZxSwWn˷||Eg~[fJ'jQK((&҄-L,0LzgXLQ}eyGfg7cGWt wT4SWvxGEtD_3vQQQK 2$2Pop.0SdDt1DlS G>r=7Su9]4E:BA=zDDJ4N5NDrMu@/M,r$ENtLbW%,3`UO` `h%A4uHnkGpC.428#$wvNȑWBG Qk 4K4O5sHf!wYIMy\'PMFsh~CGr:W1wta`t `G3H7؍|188PM 1BO&m:Ght/N#nPy9h9OZu1/U zmsy)P4G[8G^GyYyՙѕZ8Gcy\asVauaH{?dGlQ{T'm(k]en@^.NT řjyrTWHu6Ip9&0) 2U|Ԟ*EiohgwnP| $⸗c՗ ac9/w,)YxHzLZYM9_%Jڵ N)iI pE'G_'7PhWGbVVVt`sdՇ.Q3 *,"A ʘHM\SؘcU4ٍ>C 8ZZMf:79(`0StM/TC'1 ZRN9n&L2 C9:@SL0%̜1a؀Hb Hf :dʀ14o\s 0r E)v<3cXj't@VS6nuoؤjw%kQh~Q"k4fP(aA0Bqrƴ㕭-1b&o:<4CSI<}aSM6o|Um6s(HG"JFX|!E!E=Vk񤡃2-14U9/TM7t@a@Iæ 9y)&A uy#G nA%2nĄ!B  Fq3M2y#h|tKBDK1`Ƞ EAL8 Ơ #Ctˆ/M\1"Ъe BL3fn:j.,j© „aĊa@6av`{fLdvR( k۪@ =8A5b Bؕb0gʠHVw(D-1Fq .k"IX ¤|)B2vҌh4ۍdp̽Ws^pER}=D Z x(Pn}([|Uumx'C&~5"v5zV H_(eaQjf$Jަ@@ HvXҎɱr5BM79nDf:6 ; 5`[n Pied"YrRPwqEJDQgDFn_EF%Gfd%&GdQe=de&nۛjhPC 4i'QQO&wqioAK(dpvyx⡠QQcGuF֭Q\7TGF:)ټR &v$k媋tdlu,nrgn wq| +P(s4'Ka0 G7ˑs&*ua tK7 @%}brWEes48Fa! /T&M-@yN1t@)L:eȀ`M9 C9:@(y +oސB XuȌ-L6e!j.:UdMpEN:]8lG%K0eaAtn1ǀ 0LG @qMY)0%F6/$RK)RHKL%hĝ"F 8S0Ym{9'AqY:I8$& M ܼu)VnM^:,K5mgTFD|mzN%ut``_a`FlFwkH#QTWFiB $k =p '` C'pB $v4AEt| h0F$D5FEn FQf8WU1EZt^q !%`aD6tE4٤dҡqD ARatؖnO1GvD)c(0칠iLjISr%*!&(]m^kNtk;:5fba$K|:76.%fs|a/GTn爉q (e hNTX=w "g*P΁ TFR ƛoDtR)@cpL[Bݶ/MB tMEhns^UvrB G' +,]n D K_c AGMq’&fuӅ07x3˂pi^ /~w55 ]lC)ꭋ98+l s dͬ&^t5+ ju]xwqsF! ' tNiW{a X&@B` A<_ZAp~Q@@Y} f`t1ꈅy.zLŤ2s^Tf;hk@>;/<"fĐI!@HkLs7@(CSH6 -aHD`y +"24l22ovCu> gOr.e1lFMBs 氆4fM,_!_:-m ,aKSoKKzcΡ\.[6]0!S7ISDdHe|dYH9M ,3*SbN&!@;ѩ΄H=0}΁'@DmazYJe u57kb3HFO=sLL?i P+b̸ORs ,eK%!CM] 3mK.{P= :.Zr눠K 2,l"( 4R9.h[WYkRt( XCK:7M^׿nDәrD y03Q  #RHkN &F/TL:e@A 9y܌4oȤ < C9:@qC&*aܔq#&L6 TP`DlIcN3n:@g0?QPG?0C1uleO  fN1lNIrJ)MrjiGsm5NREIE7ߴIh&M9 84ɆLf4e&c?A9Yƅ^cؼS ŰeFسk (DS;tWq|fl҈qtȕ3+yy^Uk$4rD;4 Ks&UwaYBBU @$TfUWp0o /TSL1o h Ba)a2 ̤aS 1& 6:@$0a-iCF]| 9͙6 A(c bq#h21ZA 4aܐb7r`Y1 #N#baS#9tȤyr*VlwN9/c1uA}o:C7 $aRģ7ݠHCr\)Cg# j, I&L@ `^q&P[t"Ήyv9aƔRew$Rd1)؏? '@gBt7ܐBHm ܝ1R qyam{(@sR*ASm %GuXsQ$$V.HAxm 8ta#n h8cH {a1$V@f, t&peBFra] %"]h`j(&ernI (p} +Vc}Ps᧙h⥗ifp!(PaKLnTF\Q'( 2<#miFO6Vu;%Zn(CbHGod /nܙuP+ފ!VQfUT"(3<@ibEmr*0j" e(fbj8%!/lf V0G @AHHǡ V\QGr`l FoahGI s(G3Q9obV-&)6F*[1T6๡ rKn+89o'UV́"AY>C\O np! goZ >^rX|g+ M%a؇~C&J I#>AJHGeAǽ&6Ë?uuOK%(9hb HZy.v7վlyTLN!:` oh<ǙRQ4 (U]KL[j7,J5O]E @JLdIt[R S7/;A (JzS VҀq %&_nqwX !Hlb"rhԬK iX1Qԑ 狶pKv @**\W`WI4skLu"eE R&8Ejơ&y&YŽ XhMԴM3G8fD :ԙ3RJs Iz搂Fґ0stoE;n*ۺsZ|\Ԥ,SUJs bk-A4Ι-P>ݎdQY6`ܝ` (neR0d-IAN-> *L 6TDZ ]IqcE,V(F xI6-r.61g`iRh2T8#RA-?IF.V_ ǐ)!:2AEyK?e3 d@ʽ0A j##C~4@wP`4xt\o h+h*(ѡ5jSD /TS1oȔA Aa& f&4n΀F"9eڼpN9,ۀPB aF&\$:tx(3 U8dŋ#KE "Ȕ!Iq' 4 feU#,Ԙ ȝ-.Sag mn.|8Lދ.~VC2Vak*r  y$ 4>F>Qt [Aک]y3 ױRNb#Iq)vYifN1 b&0cKbtZ'&1̚pR~!T UB )…`0pC+p)H(wchGn .j @'L iLrAu 8G~oW 0I$ua4ᘆ P $0(ERvlCc )TÜ(8 :QLc!Fw=rfCm++Ђ}8e<*'tƓnY)z!̩&l&Pf BsqF>B yLnxt&6%SE\rbc Q Q$ Fn0 s i.4gIkȡ78˗]PR sp+X]dZ& k Ŋ`)(7 zRAѤ2_cmV_y gSgrSRHh(* ڈck%0t$6m;8&NPYUHC ^|elH ћ@bs!58"5 X,ZF íœ3fV 't9 w훞O;Κپ[BgLRdŖ[cƁe8f\afXf}X+ ph7 1d  愿kI>-@4І``A r(;Z%=M낿 BmAJl`B qwEP9%ޙDq.c%fE%fp @$$ecdմjRETn=Zte2h~(f67EUJw` OiY#g9 F]PB:8'N]21+4eb&G /T  )f 9tȤqb"7 iSfN uy#G nA%2nĄB  Df8rޜ aL9d*DSw䤡ӱ"o\!qΚ2tas有gԴUdt~}c1htD:'| 3D9w{0Ca;p'aUdO2r@x!\d{M[0+Ay5֮[M4D{žm5Y\^ :>)nwZ1{6llS᩸ `=0L9pBUϠctud1Ff^M'rQYxg,@^qA3/Q/A !rVb.TljKeHz!]F4Ce8cՔ@B'b/ bx4h7)0DcQ 0Gs.ლl 'mL/OGmzFo%ggFz*@!WrPd_rt)E復VoB *jBuaj[C,IhQD.6 !gؑ&K*f*\R}FwB l)Z[JŖlQ [*XxaWw%FU({I@Q[NSa:`V4ji+m ˬ!;&`  )@1G B?f[PG-СO{i\ʅ"%ZE g _ -* 16'!` ]7.]or[ vQ8Pjt$p$,5\Q_(̳@!t&շ~3$xK/ʭE eDb9sѶ;c*B s#2.@Eo)9,.I՛jw|c(D9djf8c! cD=.h3 @Ѝt/pW&1ng3wAA@  X5%I\6ydK >8%yDv&@ &|X;[ РE>Fz5R% A0hG31TBXTxСwE آ+^ XrWXP RXRF( /%LrM 2`K!">2x֧OHBC4UpЂҫVN@) rE1UJy& o=m%+a1EO4'ZL!;.9]TD)yq&֭! lC2łCmHe(RTG$# f=C*٫_skXjsd CƢܤ0/ V 9Xq-VQq^6]x]/yW"9kkHq1$j:V:8y](sv=Уj"a'*XѼ(b<[[vHeQ87P l{[D ;P'+PvoW|H5 qxܾ D(tqk;( qNF۱EQAwS0_sRUsMlQokz6a=Z eo[FJ[[bJC `BNcBZbZ'-ukh0o8у1aRC{+[ v%6  \w7c@oc,H lClzbȡ|'!l֯l۟b1]~vtLObY~˜@Pnac (7E=&iK#-8!s*wTk M'e8])OYN% d$? xE @\k,weUm)kq9Voc傓P~Hr'/eN)<=( |G8 x 8^yTW(8c `Tf$H9 p%HXzVwי`wÃ] BEA@p8b-At1n"ԙud=+O@?nBNh"TppXA l 7ezֶyc/TM6i@GN7t@ASĘ:r䔁Μ2r@9X1A: HnT7lڀPBǰC"9tȤyA2M*@*Θp̙su2tICE>ۄyV @p V,Y2;~HGNx 0 Φ2ݾM  ;I&LR(' 16煃rŢ!xd2W~ cs...dis.hmakefiledisfp.c.Zdishand.c.Z dismain.c.Z!disrel.c.Z"distabs.c.Z /* ** @(#) dis.h, Ver. 2.1 created 00:00:00 87/09/01 */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 1987 G. M. Harding, all rights reserved * * * * Permission to copy and redistribute is hereby granted, * * provided full source code, with all copyright notices, * * accompanies any redistribution. * * * * This file contains declarations and definitions used by * * the 8088 disassembler program. The program was designed * * for execution on a machine of its own type (i.e., it is * * not designed as a cross-disassembler); consequently, A * * SIXTEEN-BIT INTEGER SIZE HAS BEEN ASSUMED. This assump- * * tion is not particularly important, however, except in * * the machine-specific portions of the code (i.e., the * * handler routines and the optab[] array). It should be * * possible to override this assumption, for execution on * * 32-bit machines, by use of a pre-processor directive * * (see below); however, this has not been tested. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include /* System standard I/O definitions */ /* fcntl.h not used in MINIX */ /* #include /* System file-control definitions */ #include /* Object file format definitions */ #if i8086 || i8088 /* For CPU's with 16-bit integers */ #undef int #else /* Defaults (for 32-bit CPU types) */ #define int short #endif #define MAXSYM 1500 /* Maximum entries in symbol table */ extern struct nlist /* Array to hold the symbol table */ symtab[MAXSYM]; extern struct reloc /* Array to hold relocation table */ relo[MAXSYM]; extern int symptr; /* Index into the symtab[] array */ extern int relptr; /* Index into the relo[] array */ struct opcode /* Format for opcode data records */ { char *text; /* Pointer to mnemonic text */ void (*func)(); /* Pointer to handler routine */ unsigned min; /* Minimum # of object bytes */ unsigned max; /* Maximum # of object bytes */ }; extern struct opcode /* Array to hold the opcode table */ optab[256]; /* +--------------------------------------------- | The following functions are the specialized | handlers for each opcode group. They are, of | course, highly MACHINE-SPECIFIC. Each entry | in the opcode[] array contains a pointer to | one of these handlers. The handlers in the | first group are in dishand.c; those in the | second group are in disfp.c. +--------------------------------------------- */ extern void dfhand(), /* Default handler routine */ sbhand(), /* Single-byte handler */ aohand(), /* Arithmetic-op handler */ sjhand(), /* Short-jump handler */ imhand(), /* Immediate-operand handler */ mvhand(), /* Simple move handler */ mshand(), /* Segreg-move handler */ pohand(), /* Pop memory/reg handler */ cihand(), /* Intersegment call handler */ mihand(), /* Immediate-move handler */ mqhand(), /* Quick-move handler */ tqhand(), /* Quick-test handler */ rehand(), /* Return handler */ mmhand(), /* Move-to-memory handler */ srhand(), /* Shift and rotate handler */ aahand(), /* ASCII-adjust handler */ iohand(), /* Immediate port I/O handler */ ljhand(), /* Long-jump handler */ mahand(), /* Misc. arithmetic handler */ mjhand(); /* Miscellaneous jump handler */ extern void eshand(), /* Bus-escape opcode handler */ fphand(), /* Floating-point handler */ inhand(); /* Interrupt-opcode handler */ extern char *REGS[]; /* Table of register names */ extern char *REGS0[]; /* Mode 0 register name table */ extern char *REGS1[]; /* Mode 1 register name table */ #define AL REGS[0] /* CPU register manifests */ #define CL REGS[1] #define DL REGS[2] #define BL REGS[3] #define AH REGS[4] #define CH REGS[5] #define DH REGS[6] #define BH REGS[7] #define AX REGS[8] #define CX REGS[9] #define DX REGS[10] #define BX REGS[11] #define SP REGS[12] #define BP REGS[13] #define SI REGS[14] #define DI REGS[15] #define ES REGS[16] #define CS REGS[17] #define SS REGS[18] #define DS REGS[19] #define BX_SI REGS0[0] #define BX_DI REGS0[1] #define BP_SI REGS0[2] #define BP_DI REGS0[3] extern int symrank[6][6]; /* Symbol type/rank matrix */ extern unsigned long PC; /* Current program counter */ extern int segflg; /* Flag: segment override in effect */ extern int objflg; /* Flag: output object as a comment */ #define OBJMAX 8 /* Size of the object code buffer */ extern unsigned char /* Internal buffer for object code */ objbuf[OBJMAX]; extern void objini(), /* Object-buffer init routine */ objout(); /* Object-code output routine */ extern int objptr; /* Index into the objbuf[] array */ extern void badseq(); /* Bad-code-sequence function */ extern char *getnam(); /* Symbol-name string function */ extern char *lookup(); /* Symbol-table lookup function */ extern int lookext(); /* Extern-definition lookup routine */ extern char *mtrans(); /* Interpreter for the mode byte */ extern void mtrunc(); /* Mode string truncator function */ extern char ADD[], /* Opcode family mnemonic strings */ OR[], ADC[], SBB[], AND[], SUB[], XOR[], CMP[], NOT[], NEG[], MUL[], DIV[], MOV[], ESC[], TEST[], AMBIG[]; extern char *OPFAM[]; /* Indexed mnemonic family table */ extern struct exec HDR; /* Holds the object file's header */ #define LOOK_ABS 0 /* Arguments to lookup() function */ #define LOOK_REL 1 #define LOOK_LNG 2 #define TR_STD 0 /* Arguments to mtrans() function */ #define TR_SEG 8 /* Macro for byte input primitive */ #define FETCH(p) \ ++PC; p = getchar() & 0xff; objbuf[objptr++] = p extern int close(); /* System file-close primitive */ extern int fprintf(); /* Library file-output function */ extern long lseek(); /* System file-position primitive */ extern int open(); /* System file-open primitive */ extern int printf(); /* Library output-format function */ extern int read(); /* System file-read primitive */ extern int sprintf(); /* Library string-output function */ extern char *strcat(); /* Library string-join function */ extern char *strcpy(); /* Library string-copy function */ extern int strlen(); /* Library string-length function */ /* * * * * * * * * * * END OF dis.h * * * * * * * * * * */ D# @(#) Makefile, Ver. 2.1 created 00:00:00 87/09/01 # Makefile for 8088 symbolic disassembler # Copyright (C) 1987 G. M. Harding, all rights reserved. # Permission to copy and redistribute is hereby granted, # provided full source code, with all copyright notices, # accompanies any redistribution. # This Makefile automates the process of compiling and linking # a symbolic object-file disassembler program for the Intel # 8088 CPU. Relatively machine-independent code is contained in # the file dismain.c; lookup tables and handler routines, which # are by their nature machine-specific, are contained in two # files named distabs.c and dishand.c, respectively. (A third # machine-specific file, disfp.c, contains handler routines for # floating-point coprocessor opcodes.) A header file, dis.h, # attempts to mediate between the machine-specific and machine- # independent portions of the code. An attempt has been made to # isolate machine dependencies and to deal with them in fairly # straightforward ways. Thus, it should be possible to target a # different CPU by rewriting the handler routines and changing # the initialization data in the lookup tables. It should not # be necessary to alter the formats of the tables. OBJ = disrel.s dismain.s distabs.s dishand.s disfp.s CFLAGS= -F -T. dis88 : $(OBJ) cc -o dis88 $(OBJ) disrel.s : disrel.c dismain.s : dismain.c dis.h distabs.s : distabs.c dis.h dishand.s : dishand.c dis.h disfp.s : disfp.c dis.h s脡f 1hbΘ1sҐC"4sq1+e!Er ,3 6q 9~C**MtӦPJJuEjʵׯ`/Đ7pIs (t'#+D3&ðabm[:s MdJLX l27 960n&*p:tʀ M2bL:6‘Ǝf 1M9cdyCIwAsz݂p`9#y ivc:&k:ae'ZhfFlH@iXB5q!o,lnFJV E6]uaFh]ӵ05'ua$vGxfq.d Z+wGbl4h2UF e d h`UhNfl2Q#D8uT! XbXQs*g gu jP$;8l_6[$Gp &֛#@lZJK)^*z n*Ʊ:iT,c@봶p-J,6\[FR{õfUW~R[.dFa"M6ʖF0(WBБ &80EAE.PJ=hNkr t &MkLž)* BV"'Hj1*%noc:V]cIv%ov6JtJo]S0#p+{PfE]r}m-7MdNdqFj.x{Is@gIwItP'Rgs脡f 1hbΘ1sҐC"4s!b VqBXf" :nǍ0r!b/T0\)ӧNB**SK/jʵׯ`^TU)!o䑓 : P #OGX6aDG7gNa[t.3GcˊLWcA@Qd7n@ys0maF^1 [1ueĜ>#'l2'1/#! bΛ:rL 5sj AsKM80F4kt^Ne™߀n TQi1hbtҕffPofv[spC`iHd8Pq1&Zs4ֆ6^DKl :HfQRinD8mըabs"bf]nцJ]D] GJP{X$9vA\8"mlesuXuG¤Y%G< -J6xiEZE&ӊ ZDDB!gx@G"aKA0cJ[h-l)5H$D-LEC$aDCϱ1с =&ib&l![h.$GfۧgAQOr9R(| ƞ %[tR IhqGqs >HLX2DjbQ^G[e Z%/'*ެihVޭ7ef[ض'z lKY@B@!'-~ !-ݷ%+uUޢ>dVNꪷ G lԱ!ܠ!BeI@H1dѮÎ6Wfq>sfقq*aa8˕ 1a[SBolflJE.D}lj(--yG%ixi}|G1_Dΐ>6YPһ!@G&:RP%ʀ `R\&$a C(w= S(ĥsV)ZAUE+e`Cc yI*0ER#r_I)fD($]LQ@E+J$  F1lB}lv㸐歡ZAU\@T! xdWdBdWie (蒓y+ZlI\fgٹMhR-fUukӴt5)H7Z賞 21X+* bXW3VUStL4~puB$p樴?VDr]JD.3)fFhC -ՊO*T,>+O:K{֌sd<_hMT6 '9':-؀A;?MD"kJrJӟ LߕOf~8tM2X]1B.=m+Aʶ!?1Q,@RcF[!2i}GGH`GNWP'l*guWhSWut`Y 8WXm\<"K'T4/azA~tGuR,QC`Q, Ohg~a,0, uƂ]i`b(XgH44p)_+.83 `lHfE1 TXL1LujufpQybveYwBvw7mWv"% R2f7\Υ B3a(Pm!E:=x8 ?v:KsnMF{Py_y\ookz`Ǎ{ޘyx{7|\x(#G,|tOCHqsN\ty"Mׁc8OidP k~h9,INu{Q%RLNTPX@,OKRC,2ɅURIYW7J[׉_ۘpWwZ)hvmERNkFpa]\bK+"rЋ0(ur)G7x<b*8/Aas"*_c`:wf$uR31jl+e1TBqxa ہb \ *B-1ux!7RQ0K|h9\29bX!ia2,\ѝ|]IId&j(V(G(eyzeǎWphxn7KS\cJ'h{B"f-\'*'z 'q'! h{J,{a1p]p430|x׏WwybJ.)H1$:Rd @x0> `iХ"3djGw`JjVn,Hm|f̷Gj:qI2w&GϷp&r_NTPuVQ:NbNh|1ja),P`A[;(MNI" 䪂>aO$rZzy$ǥ&76:qOѧ@Ȁ"DFIx]KqH}6|gHڃO  ҥExߺ \Nj7gAs `!{JHh|3}<ш'~2p( j,> xZ}G2 ڭpjH5I"'ȀG~*Y4GC;`ʰaW˵k IK{_G::Oj|"| G})kzԬڰ[ѶQ'I)RAt@_@A@f;ٓ?B0,) H;q%, (t)`6AyS[`n+^Z^w}.k',[hH:k*+ #_Q& vH񴆊+˼zS +'x(PZ `HOO +{T|G%bH%@f{ufMMZY:k:v1dvTa镥v!ǒ2' b"t)2J6bQ&/o"//Qw^Y])#CHPr~a_b1tXv6vC7f맠GdXnEk סOf.j>Ǐ Q hzWz>45r2_%C2Ȱsq!7,sLWcPʐ˝8@tE ,Ds Lsne#m(RUOGgW V{FyV'wG6?;L, WuTF!dy JzȠjz<(':)ijP쏙Mzԧt%5AHNʿRجPl~&8䌀Ep|j̀@-C4S qR΁JWf lH ql>c`)|~m μՌ¦t,ְKϯ8U.=Żr yLpQ%sOb~eQ0ij&=#"Wn0Ao0؝$4^'gPjI2sy'3*1'1>$MnXңY%h^h(e!L>[3 []"r5Za!-WFsS4 ag1.+(912G>*"5B1zA"<Ų\~}/cb21XY] VD>"<3aVs̱?ó^+)4$yv.Z[_Ghfe0mẀwy?U{}#|h[4S0;NY{؇GYQSyiճ>d4b? AƱ;fx`ajS:?>vnXSq: )Э_8HUڴ ?=R^{hޛ{x*X*\, ĸI> P.˅WW_j$S|C PB+p TRBd@ #r\J(>Vz֯~ffѱ-'cx-GaAwʝ mX?dpnGEJOأwAؓ,i{;Nݳ>zܣnu8: {c6Oպ{q/@JH(o<DŽBJB Q>t|"O}>h]J.$/^I1{9MݯU&`Ay}0 \app0w_i.>DIIE|1PPPChf |TB$2BipKJ ȉd%%mˢ{tDž  qw .v8\^AT p +R8 :RqzJQQ.ڋ@O -3rBB&fԘb(ȁj)1Gmq'9K #qܮvP N|hkq1р#D6^\t*p4FXXbH<9 T2~BDgI{h?gb 0 @} $$jh'V.?:I#EU1zCHۂpc?6]V 64B檸ۛ2YeAĩʉy[[6KA&)#I>4'&o\K1|9o 8wg(az`R"H"@MƌGG|QHN>+D P#DOԷd44*Y!j0BHT՜U2MA ǣ-@Jk~- ʡ <0!&P@kH1C&cr<ҿ88̆BUjH8UOGI6Ҵm!uj'ҜD$So7оVZ~{q+; c! ! ,8DP L&ܧԆ Z'ǚP\|42#ȼBO6GB( h΃9ME-) 4MI: $&@Bo&hLEtIk'j3uZ'_й@BvfM8'ک:C$EG0Op!Cau M , #geqbԡVԏdV8Yܞ"p3/8e Tx/O(U-Mɵ,DnK"зoL\tɶRďSYwUrjG Q'! @۵ؗZ:V[|f>J~R:pF)x+}Y扎8TgҕE}(P,lL0Y9扨aKA-SC)t#lJ^ إԴFJLa3+ ,{JDFpz.䖗tSPi#0Cꏏ@4B I F>%) suq3$%t ]Il׸^/I}XaA%\K3cYHh3\P9zaH e`88pI!1)^UdByëW)[?O8?7F]DG;LCEˀa31-:_^uP|<*#Gdє*)v:GGuXKG)B[3D #!k;,aiJ$nXfҜILgC'(tvӄ:Oߒ45S! P gӃ ~zVMMTֈ[5C&W]v%,ohtHszR0A"W. B@3 '3 WP{U:jJA1[뒿tX{n_k}]5F:+ Ú8,H3%b˫u=aY{/.r`)I"vgRBJ>վyFgpc*Rs脡f 1hbΘ1sҐC"4sڄI  1)3D0t /`C_`tӦPJJuզ^ʵׯ`Ê"RC#'4t@1F lnΠ Æ o9\fJ;6ɚKeɂ Ȉo܀< ¸cb)$4+ˈA}FdPff G;#SĜ7u䌡= 2(AICM" 6pTi ꙮ&ta wȕ Pmfm!IsIauׁ` uHTF MFupqfHaXb<F&G!HUrMG@e ĖqnIU-`qn!`:HۓF_]\!(UZunR\@a@AFWEIƤ^F9Yqw9hDO=d;pnrlz%d#cfFz6G+lparNf" meCHѣ(jwElZ_%!a8E!e@&`]7!7k{t̔B%Φft)Dۂ̺XhD qiѠA >fZ~ޚk Ezj&]l 4B}b<1%i!m FbePu-țsrr ڙ*gRAE=б1LqԑL x&dLȁ&:~dF3Ipµ8p-##k.lQNYzi+M(!Z肋yy] 1jj|Φ莟Df?1Ӗ}7k9f+_W_ HI5.@,G>z<"PRpFx\ɃzT`iHܰ1Ip =Iג`$0&" H>ӑDN[ Aܰl dz GA(OPӃs$TQW|)!aix k!$ņ!"rM $:6 `i*?0QXbP@xK3@XIR)>T I0iڤ P0P;>Q09L*\4Yk [iw:"JR8,.cDac"v|:n"0]90 )[J0!ApBPU >L#T C0"r eD`0sHAVsl- aN-2Np9\LUUnYloB٩ \pXӣlLAA b5Lɠ3 08etK bCcIu+GeRԧr7*UֱgfZV02 (zEő؊d@ԝ6PPVO.A4ZG(=db-*˂Ԗ>.[ۺSYqw&5u/ r -Pq +iqy viW9ѽAn@wz.k8NHF-(V;-A=p ^pw`Y \ave+pX008,ep  +cD%\2Xԅ XqfΡpx!I =LS.ɇFٴSo8M"82R<_.fÂX;w^{pÆMb`eVUg@bث[Ņ04[8d=t3MBȹtg A}OזD5Hu[5m l&9nMA MPFހU*.OwlY;_lp5h;P- Ωe=4pr9ւ4:VJ{-Yu( ${:n%H US;Vjdg&LZ(6.:vE4Mci&-1vp9AB!N0ˬ_y6mHMG @1e~Gdr!l]Fg{ȧ|'ϷGxP02ce}};xrAaׂjՁE '-Ua!:Dau*[1'{&I胄}`yEDyFzj zVWzdXzw}Geq]3r2[$)4GDv7y@@!04phT8C+2qO+*fKQr5Yb{Sv4!Q!bvbw"0;oiقNS+ݡ#Ws"2#!Hf+&[1By"Tᎀ1%&3FiLqQ( !>a36 +ArrCs26c_p >2#L4ON GHtء#'#dz->gS.!8T/CiWwzvO "׉yy8Õyxz}1$_Y$[021]`$F)n|0|Օ_@ET }|rD Ԇi '\]ؘY]3Tb"@^X.Pl:0Vu\\)DY B[!IٓrLXN(~,jJUx^ڈ)n阙8E)yb5Nyt)ҚE]S4ډlJuY͹Z'!Iĉԕ-YxzH؝;)a88fUP |C-t"r)Q"=rhu(w"A=E!39GAaPGgIbkkQFMy.HU*QڨNv15Z /+`HQyyGUA` y(J6EדH|jDJ iQjm`jz CA0S࠮4_`緘JƚȚB : \yRD`秬zy Z |:OM^!Xǖt \Kl]s0V:c{(\` tAb`ʇ麱1'\ kZ\i0-  +V9˜rnb^cQڮ[AG+36h\88PZ[vʴ۪4'. ~G 7~l{^8Cd6 ^sU @+DK+] |۲C{!z$B 8]"jr`T|SBTJV(017۰,{}ز"+$x.kQBLTԅz3,uqɂ۱ MX{6U| ;Zn A +\+Uc0fKVmM "]v{x k\\˥k PP[^λ;9k]bE}H,EڨGzLNd5tF736gC.+1x3&gAq+w`S9M5SAjXfdk+Y 5T`7Wrf N8PrDD ._͂`m:sHD/ PUa5v.DB BS@hU5V|b &:ID{ɫ9J2#9yLY[HŗSyoiɜHȮ?^ U6rj)4d0uRQ xLh{l+Ie7swo`kSikHۼdxVna֋!ܿ-+aFdrsq1g6&AΖ"gdmb)1f޲+{=C9p7tj9“ԔfCqEwK38]Ck63_ C",]g7:bBq$bL˃_{%i6!q5gPsr/9D3,CevWljg/採s33#ۃ  !!"2iLC"[-f|fz!!&B|Vs(.67={'9hnx/slGVޱ+1fs hq1q1Bn:h1#MDz=ۂnL;jfwȘ hVɃ'r?Ɏg,:j[H4PL}dGX_J)xJdMh@YjГ?_>EhB\EG ՉJLJN]RT}w׵7rA  ֛[Gᅨ/zm؏]D}wZ%+L˳͆n|7ԇxNo* ; I^ֺ܇JxG78b'LTiڒ:Xn VZkVr'}!]v 6|,!- .Nu="=.6a#.y9CCO+1FAro3oCsȁ^#Saz5G*[%ﳅ7.^K | D,/O֟!^>w`zjN!ty.=V^bM+Z!=!ٖݒ HJKETdC^S+4.g 1 6dN Oܱ6Ʒ_l;~a !/ȉ rH˜PnpzآFk8ޡl*DALO-Ja#M6Ҡ<ÿ sc$LRjjO;v[;!& cL젞GypL2 g;`7Ń zȴ( b'aaDR YtF e/fXH~m'H 'w؁4{D<%;HZ@.tg yP8qH_X,*@8U%j F *E`B4`0DR%:-S)zH-sbW9AľU<4Dè#ITz\!q=?l&#j3l8)C¦ ' ֖wى+@+ְPSnK]G+h@T .XBY m {M'u1b"D+<Ă6X cYbs:^!0F;PcČ14JH\D#pa@*15JMd\ZQ1."h<, )(6#ql?1F0mL07TDˌa7Ƭ(c\GA٬r+%FϨOh:d"r^Jp,E47"3Cn /e= p`Yɀ8b, ;v&rA"{B{ey} U<1 ،l3 ~|oɿ(!#>KDrmq㙼06̲A#kLz ]&ggɁޜ̀gu` dOj@ExV'K1-PC|!56ßxsXJwLO$C! n3o XPФ(]+ iҖ"6(Bgt;\: %D/rs! BZ*[e)yK=`Bkt^y)6Z ǒN*Kf@W" |@WHb&RcL _1E389%qyG4#NRp"U5!ٴT'Q֜&*H! )ps&k&wM![ ]F/B/۴dD5{%fHKd^0pK76di4 I$#`8QF&*Upd F"G$,fH2DFz Ue9< H+Hq;\mp(s脡f 1hb8y9 @hň <8"C@ȁ#.@4D!4nΰ )ҙ̜2r!#b#'l2'1/#! bΛ:rL 5sj AsKM80Ft^Ne™߀n TQi1[invEluq@b8XjwBd CVt@7o,lIDXFa8цoQG 1GcC:Iu`A(!`FwpFb vQq1_v "t5M,fzfl  ĥцB ۝dK)Q_ru`RvURi2Q#L8uX%I.YF*yTƩ i*0PRRU46h9maXЄ4jQ冑[4SdD΂ krvfKday-iߋpɔAEƽ&"g0X]qE&^VXD/ AE1.QR,# 0B,remV2R1VGQKP= Cx0+Sl"h 2mܞ(Pl N#í~;畁NqX=GO6y>ȃG[hcۅj@<|[9^0yܡ{z?-|~b W=W m"/x2`Hg5^'dzAĬ]'y|w1W޷v؜2y+x3Ռy3H:و#3w3aZ~M݋3;O!7'OL^qw!Yxgf6w̶րU}kGydz3y(g~׀~[Qv)b3zzgsvWd(y7{=~zBL3x~x@ʇhK{;hcEp4 }5%ww[w4}T8z7pS*JιT FZP:K*P"bZdڞR.Y!(Fb|}=ab!56_6z8n[qs]u i8@alFڠZv 1ZՆ jMxip8p蹪,j}|wUzz:ūʪjB*֫ :R ^ejm(YJJ`SifJ>֤[ciM!_PhpJ8N,q 8, jK PɁ9` ;Mx79P !k@ :k$۱0jMc w 7h<&OwpJBJa$7iiuKta虴%˩(Rmh`gn[fp;`jUvS\*{[~w9@*maD;;mpa@watQԷiakGk}a w;p0۲J aJt0::z[V5[ iv״˻k ձNIg˭M!d0ۺq1{Hia@{ŋapk,v|'( Ks_'K\1µh{^blĄ ,% 3d '%8,Đ&k~s+b0(A̹ibE[c'HZa#VC l>Ť|u8n|plrp$qCF%&KFȂCL979,)2QicpQ<ܾ62,"Izcl sicm`\G|ϼi~*0jʜwcLLƬL]LL |1H[PMkϨ6!JLcs;'̾ܦy ls wd GГ}d-viw dve7$id㼚<"x \ 0Z/dH]J}GBԔ:iՓSRb^)aAWS`'_vL~f{]W@okqie{]}׊Mʥ]~W2zїjӵPh'ۧr hdpfƧMx|g||*4699krGBSI{ϷHjM=e9 HHtf)l q5dBf2& Xr#!>Z"Ō5"1@/!rpJ%!rR n h鍴I 1: p<;()pZ=-k:{ +nRpBO`^R`L!,PpFhqꨱ9/&5jP20,=,+j꥝/(!`.]nS[5C_!2V63:O%s\'x#r():}@®E`Ct`Q>*oM(1!X־5k0Ur 1XW3!n7Yc,x5_C$["RER'!-~\*A"$qQ߉!w@ qu62:(q~w&ݑToy[_]7,#5$(bv0u0_Qr+doJ|5b*'1}5!Dc'"i|~,V/&*e9(T.t@!&'B1dW W~&!y1%Ͼ+'WaJeO<Ơs`0:A҂JH@| v ;Tw1d2F̒w(Ri~"pą ơ A6>HI<{4̿&up B!%T%ļ Em|2f`pxBAȁN9<x#W؉!:C %H|E;P kANYiapN hW A0p֣,!F$!R P4/.`3#"4g`ﶂ;uYH3>w+S3x(^#z0nbNex)ZI[ap0 ȃ,ԍ_gQI$GeBP RqOE0H\3L(Lmű]K.E"ڋPŁp!xQ+ -^ a2Fۇ|a% v,oT9a&qy۰MP 0 ^`Pwܛ6@Ge 2 S P1hÈxqFBᡕ[n@ !Zy%#XB ɁrA|~!}Ѐߊ8;jltp; YFL,D@ H0=%4Ey?LƄ-_Ti0#HX#(v s!x3QBxxNuQ.LUpCe6X+{ˁ 4\ m26Jq!,ChNoK2y0E]f8Q8"#y0r۰)Iȅ~2#+X4 Y#4@/3|No;@qfHC9 Xd"yRNb>y!z,{T oWS2Pzq@ă#AߩĄr1P<3Q5-lՉ@ C\<88qh `2j$bdL2S\gy^EH6Nh3l9;Pp(<숗*ΒH1! tG;0DyF=#A@"D "ktid yF0Q&@fM|w yiEv^THF9# ЊEzB'EL <%Bh-D(y)0P8XaLFyɈ vONR$P1~ ~\aTxn\0ERAf,v3.XhtNQ^sTNY)f˚C49 ?WψX IGY%`JIYd Mx@Aa4`eo]a&Bpȁr -_ؘ̐5(mվʩ Eh\1@6C|5'"H1 $\ \KQiNsY5Ӕb H:eL5A3ȏ_IؖHص!'PEX!m.c^Ě|YS%WNs_¾0# 46Kؗ\,UK((e D(@+P@XHYM8~a3pD|33V<d\-lHq['+j [='zHy!v,,?$K :kdEXY,e#ڐMTlUpNnYjܝzJ[NcZ' K O>;Z @m:TNT_ 3\8uhY a{*٘cef ,X\",X$*`v8 V$ah-h;# <ě@}vKC& p/vd eX<۲hUK H񼐲 ܢ[ح36y{"r)u[vjlgRD|!ᾭ%QkJS" W )1ŤJ\8H/(T` 0fE*ԉԮ`mJv*PBI %ܔr[.T<.aME1`&ܟ. 5w\EJIKq bx,t@!*pQ <̀I_G 2FZ6Du;jMnk @$*-ϰM+q( C7]ːyW.\!ƅ΍0:]"})їX$, z*BXrY5zKeШP@ Pjt4^[|.@3n "㹇$^~ S j/*j_#@&F{R]$(@/^[wž`ZvMf7 i QI s~UV[Ekz"p_L6ows s qI.}d_xA-V^X}Be\ϛC(1ޭ[SE7 C쵶+O=cV\pX¼G0*_|m_hie-l^`aB W[D.=|ۄѡ7[/Ga~p'Szֿ?o$F XKṫsM"P #p+CNOvu1 +:GţԐ'gY-O-1O1T,0APtPt(.&|GI*; RǮ9` kAM\˞^%QAxr( N83hap6+܎:RDz+dH&y@q,5Qp ( k$=BK˭@~` 0JAx,]o؟*Cn<0E-Q"Z-AkP}tۙ F+SNp /TDA<+Qp:씿qSG#...$check.c.Z%input.c.Z&macro.c.Z'main.c.Z(make.c.Z)reader.c.Z*rules.c.Z+h.h,makefile-readme/T("4eƬ1:cԑSf3ohfMUP`D7c!SdҼqGɓ)W LEI:ԡB!Jh1EfN!2m2qđ7ob8¡N0ͣtcǖYٴ$";h䂠[o7LQVK1uΜ9yƮ & pAB (NnXFcÇA Ӧen@: kQcS ׂdt.NkJ0A6S3xtc>&{Х#MmL zo0 `~C_Qtfe 0& PEmȅ"`VpanA( V(/W hb .H1 ) :xuia_n"iaTfN|AUD>!bxaÇ!唴ѣue1GiҎj8ǝ bȥ gYnde%GCCIߛtĩDI8AfM?be_L )FUz3֨P-n `rd`Ja -th#?gmÆx_y!ni&ȏZ깨fBY΁'=ChjFJp_e/ޛ;^G2[9,jCMPIDsaGK-E]\LS-Q-e&y@[ $ސ5ir=gpeg\u͝IGmse YR,ѦrC!upűRFyNgmWƇ~9jɞV =m]mvK`*)* Q廖o|G+tPUZ 7褛X6EjcP @ aao@Яta8]B|f~Ciyn}|4 OE:[QJ"֣A [SB LqP!$MSb")@&!2(6 "S6xt'="̳Mq zO:xo!j2`nB*9!шHA R 90L_BQd*n^~e<]!y`_ЖcU^jHC,n/T("0rD0kʘIæ@/h6u,14o\񡀣G"C'2*Yr4*EhTPRN ܄iS&ALє CfQ:FB]X0ĄtZU0 BN.;H7ea9 f,0mQmߎUb$nu0RtSGpt,7ZfQ:3}wؚ]^GAgҔ:+ñzLgk]Ƒ+' 0pck8 A- 7_w8`VUw7w-~]5`כSi E]wY ÆNƙg@0| k*l1iQ\m)D S=s[‹{ 1_y`_u!Iga~>gXr$  8dGU%2 1DiɥS^Ɇd:Tƙrfi[I]pA('wf9_zFG xYZkt2[lqF'cg!@C5]dQH7AF--4GpqkZ삫.tcH B 6s%`W=V*dەux$_mW!u1r,0cm*wgz<Ӭ:YtQH%H'9f&*kjx@tFcg˚3,}Y2g5hN]@6eˋ|&LPUd&ѳ c܋+-f4DGByjʕPC'e.P2B`7H83%8Eq8rc[9tS'3-d}߮?A+Q`;Pq8xk9sZ(2dNMQ9:U/Ftphky!o"GMngPG1Gw;UcAAB#$2GC `&iL0%k ) Oq !(1'"!#Գ7*!2 ,k(-E1{1vuP`qbEZ}a -1 D\ Mr8gb\j! TM X@7%%(B*) *)$5 l1k)ȃ|tWS2dNq{C y 04aՄgp A&5B>|BS"()?cBT@ _I N(`x75rrrB&16% A1ӆa>x~H|ipO!$.N) GA-:F)Uh*Ղ背CXH{ Z`%kR3Qy8%ȅ^(|QeqjVD(-V#+x~4Ȉp(H0fG/(@ {Az!Nބ1iB!" L)(ǏVY0%n`8cF 5QDS@E 3@CWffy}RaZ;zM! d@@QaU n$l*PmQ7aP Ix6E^BmIPRsTbD Ƥ JUa) 1Mqz6)ԆQi%~jaolh A01"V5oxhb-R^|ǂ0wC1qNopȱ0maPgDG)_huK!W1tnHuցVz+z蚇uRgdWuD:/H6#]gn[io vFd(pPF(\6 LdGWqxBi $WcTp6~F ΁* n1 ׆:MmF񵞗L4U̝PA6za 8Hc<g+N*: +Hhxg ` K -8A !Jq3]Ȟ*\)bⱌcsz' uf4,1!` @QsRң?8Q7L:H𴙘e))j-#+@LdHQUt=~`V^QBͧiT9V4B%Xkp9JM*4 HTpWJ!Jʂ*K*x91"xF/ql,9f v*XɊc |HKDq0d!u%^-tC$i,=D* .ɬ \RLF1 Y:C9,v l\8ɶrBsHgmF1dYcASAP1c>͕}t$Ɩh8ʁq$Լ1ӟ\JfGGHaZ8Q{&ӗqF|Zud?C6xDTViBd:#& KQJc; IX?/ϬX-X&2KvnR*,4:$2o`, ,M;zSFgC̰4BZ瀟&'Ap"4) =1һn`fBeaFmj<Zs☪P=ƺ` Uv0 G*>p6_BpBtc (8I8}Pw妉kn8!;yoӐveey$i߆@"rK~fx2TEwNZraC柰 [Nbع+^CNB.z<@y R`dAuPd H. VU ۇGUZ,GmdFӁ#~CИd!'$a(]{(c}Ӈl}C8 fpuP3p4p5p69C~g~t!cRZV> vp.(S!#X6(k87& (ݧ/T("7 )":u°&̚4n΀0FEex@c!Ð:dҼqGɓfXQM<&Qd e9/SfM'ݤ\r/yTЖeq32nb&ge޸:QYZհr@۝o(4mJhV K{)ۍ)}&+p[@CSDɒE&(tCsP+QO:h|L/IB7ä # "O>y ÑfLnцaN 1F/`R`]Os%Kbq EsŜi,Fk0FcO>хH$aDd$ /ɁWp)(0M>XzT} @ePQtt8Q _k8\ # (IG=0[JL"0Q0=DB f@@QdqtYRGI[s (p\r=Dˍt֠kf^]Gd@chŧP n;1h^ƑkT:%Z>BJ(%CJJoNdmIymq¸E*,&;åR2{ߏ'+!iAv1iKf ܱ B+ǼtĺVARсPE51G:m"_l(GMnkeCc n&b81GheoygUjnٔtw}Fyztec1ziTbn83~n^ Ѝc _R௯] HZ \pB%ת!߹^p"-4'0b=w,* ŝOp-rIq_28/LtRNv>E/Fvp^C& kR Fw ЉCGϥ# TW"J t*S|`}*\᪨'-F]LA@@GX` LC[У%"#*H E b-vģiأ)B:K#?C"RqX ,6:* Nxtv!{%*e(AV4t \z)\P:{tWLm+B82,, @F &0అtjoLS~'("c18&3=.4^ӔU I61! }aCr?F2CAeb$ęW'ni QeB$qԿ5i!FA+^fU[t 4A Ri]ZQ?A"ت#Ċ(% CW!ŕBJ!pD*6թ}Mj(KP. rl=̋s})wB fXF/@A EYArre tk& U/);%dxKk0B图u@N1EyCz%j`l+Uo %_S_N)c8ifuJK23Iiں2.pCBt!" /DM{[ N'(0#D9...W}I;8s=ճB$@ ?̲=#?X1CHo=@ش:8yؐIa7kI ^i 8&FI^ 1(Npqsq EydB R Yx4GpT  ]EnLhq 8mftqFSr$bq _@Blu QtP()0`cIe$Juu=DtE]@ ![Y^B)4 eDLLQTqDgw˂Cmɥ+ q Ȟ 'If9+t7B(C aaW^’[n%(]0EFEL!Bja j~AER\{E ´^RA§B§;,񧼲kxБ.ϑ*P eMvƨJU_]\Zl>M>@*Z vV!>ʄWeFرQ0ZtEIBg EyJƸ(xB lR: o)‹ٍѽ~r/!ocɛVAOG; [׆7Ae@Ǫ у''a`@&/i(2 f%-j_C0" `#x04W aUƜgbc&a MwCv` <mZ)J.cH"&1(T$&f#ʀ: %o(0! "P-(2 KVJ#0!G0aD|+# Fҕk3} )G!$ c"p\Z5I In Ԣ+a9Z35 <2ELh&Z0nS4Ɣp bP9D pp)O]60,ZĖ$ŧN ²XLF4Mh4Jn^ȹ;t4HaʂA *҂SW0qڥN(U_R!ŢE *DΌ6-TzףR4* }8yFM^1ֱPEUD zZ6Ub"͊2? meF[XɚV`dlTYNT JWt>vQFP*a1P N}XCexF2Ҫ`gU]ӭX? 2@ I.b֝N(0(B{)՝2i9 aѪ u f]7ZĊv!nf*_ޕTݒZ5R}ֵ.4s0@(9u v-XެK,,5dUp2:;|_ v ΃pi-̙$ʩ!l;I)wUO\͡NX\&~|>C8.8: rh]Op'2Øji9n8  Fmc Pմ΋lEFvHZleccLc8؁`B sȁOX#! rБ:7tXdR,)Ar3sÐ ˽2l$b7P )#_ExyKlAr "c:.Co-kCwꞯ5u^m趽0E::NEs֣pa K'zGlVם걷J? @;l8Ԛ[7 ]>{ ZfV띥|j-Z]6=zw!\o6_azJ=cydy.l7om /* * Include header for make */ #ifndef uchar #ifdef os9 #define uchar char #define void int #define fputc putc #else #define uchar unsigned char #endif #endif #define bool uchar #define time_t long #define TRUE (1) #define FALSE (0) #define max(a,b) ((a)>(b)?(a):(b)) #define DEFN1 "makefile" /* Default names */ #ifdef unix #define DEFN2 "Makefile" #endif #ifdef eon #define DEFN2 "Makefile" #endif /* os9 is case insensitive */ #define LZ (1024) /* Line size */ /* * A name. This represents a file, either to be made, or existant */ struct name { struct name * n_next; /* Next in the list of names */ char * n_name; /* Called */ struct line * n_line; /* Dependencies */ time_t n_time; /* Modify time of this name */ uchar n_flag; /* Info about the name */ }; #define N_MARK 0x01 /* For cycle check */ #define N_DONE 0x02 /* Name looked at */ #define N_TARG 0x04 /* Name is a target */ #define N_PREC 0x08 /* Target is precious */ #define N_DOUBLE 0x10 /* Double colon target */ /* * Definition of a target line. */ struct line { struct line * l_next; /* Next line (for ::) */ struct depend * l_dep; /* Dependents for this line */ struct cmd * l_cmd; /* Commands for this line */ }; /* * List of dependents for a line */ struct depend { struct depend * d_next; /* Next dependent */ struct name * d_name; /* Name of dependent */ }; /* * Commands for a line */ struct cmd { struct cmd * c_next; /* Next command line */ char * c_cmd; /* Command line */ }; /* * Macro storage */ struct macro { struct macro * m_next; /* Next variable */ char * m_name; /* Called ... */ char * m_val; /* Its value */ uchar m_flag; /* Infinite loop check */ }; extern char * myname; extern struct name namehead; extern struct macro * macrohead; extern struct name * firstname; extern bool silent; extern bool ignore; extern bool rules; extern bool dotouch; extern bool quest; extern bool domake; extern char str1[]; extern char str2[]; extern int lineno; char * fgets(); char * index(); char * rindex(); char * malloc(); extern int errno; char * getmacro(); struct macro * setmacro(); void input(); void error(); void fatal(); int make(); struct name * newname(); struct depend * newdep(); struct cmd * newcmd(); void newline(); char * suffix(); void touch(); void makerules(); char * gettok(); void precious(); # Makefile for make! CFLAGS = -Dunix -DMINIX -F -T. OBJS = check.s input.s macro.s main.s \ make.s reader.s rules.s make: $(OBJS) cc -o make $(OBJS) check.s: h.h check.c $(CC) -S $(CFLAGS) check.c input.s: h.h input.c $(CC) -S $(CFLAGS) input.c macro.s: h.h macro.c $(CC) -S $(CFLAGS) macro.c main.s: h.h main.c $(CC) -S $(CFLAGS) main.c make.s: h.h make.c $(CC) -S $(CFLAGS) make.c reader.s: h.h reader.c $(CC) -S $(CFLAGS) reader.c rules.s: h.h rules.c $(CC) -S $(CFLAGS) rules.c Following is a repost of the public domain 'make' that I posted to net.sources a couple of months ago. I have fixed a few bugs, and added some more features, and the resulting changes amounted to about as much text as the whole program (hence the repost). For those that missed the net.sources posting, this is a public domain re-implementation of the UNIX make program. There is no manual included; for documentation, refer to a UNIX manual, or the source. Here is a list of the changes made: i) If '-' (ignore) or '@' (silent) where used at the start of a command, their effect was not turned off for the following commands. ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o), if first in the file would be taken as the default target. This resulted in error messages like "Don't know how to make .c", because things like .SUFFIXES were being made. This was further complicated by --- iii) Special target lines with no dependents (ie. .SUFFIXES:\n) were not clearing out the existing dependents like they should. iv) Default rules could not be redefined because of the error checking for commands being defined twice. Now you are allowed to define a target beinging with '.', having no dependents with commands. v) The -q option didn't do the time comparison correctly, or clear the variable used to keep track of this. Thus it didn't work very well. vi) The syntax ${..} for macro's supported by UNIX make was not supported. vii) There wuz a couple of spelling errors. viii) When make checked for implicit rules on targets without a suffix, there were problems. (Note: The ~ feature of UNIX make wasn't and still isn't supported) ix) The -n option did not print @ lines like it was supposed to. x) :: added. (See UNIX manual) xi) $? added. (see UNIX manual) ..../makefile0mined.h1mined1.c.Z2mined2.c.ZCFLAGS=-F -T. -Di8088 l=/lib mined: mined1.s mined2.s mined.h @cc -i -o mined mined1.s mined2.s /* ======================================================================== * * Mined.h * * ======================================================================== */ #ifndef YMAX #ifdef UNIX #include #undef putchar #undef getchar #undef NULL #undef EOF extern int _putchar(); extern char *CE, *VS, *SO, *SE, *CL, *AL, *CM; #define YMAX 49 #else #define YMAX 24 /* Maximum y coordinate starting at 0 */ /* Escape sequences. */ extern char *enter_string; /* String printed on entering mined */ extern char *rev_video; /* String for starting reverse video */ extern char *normal_video; /* String for leaving reverse video */ extern char *rev_scroll; /* String for reverse scrolling */ extern char *pos_string; /* Absolute cursor positioning */ #define X_PLUS ' ' /* To be added to x for cursor sequence */ #define Y_PLUS ' ' /* To be added to y for cursor sequence */ #endif UNIX #define XMAX 79 /* Maximum x coordinate starting at 0 */ #define SCREENMAX (YMAX - 1) /* Number of lines displayed */ #define XBREAK (XMAX - 2) /* Line shift at this coordinate */ #define SHIFT_SIZE 25 /* Number of chars to shift */ #define SHIFT_MARK '!' /* Char indicating that line continues*/ #define MAX_CHARS 1024 /* Maximum chars on one line */ /* LINE_START must be rounded up to the lowest SHIFT_SIZE */ #define LINE_START (((-MAX_CHARS - 1) / SHIFT_SIZE) * SHIFT_SIZE \ - SHIFT_SIZE) #define LINE_END (MAX_CHARS + 1) /* Highest x-coordinate for line */ #define LINE_LEN (XMAX + 1) /* Number of characters on line */ #define SCREEN_SIZE (XMAX * YMAX) /* Size of I/O buffering */ #define BLOCK_SIZE 1024 /* Return values of functions */ #define ERRORS -1 #define NO_LINE (ERRORS - 1) /* Must be < 0 */ #define FINE (ERRORS + 1) #define NO_INPUT (ERRORS + 2) #define STD_OUT 1 /* Filedescriptor for terminal */ #define FILE_LENGTH 14 /* Length of filename in minix */ #ifdef i8088 #define MEMORY_SIZE (50 * 1024) /* Size of data space to malloc */ #endif #define REPORT 2 /* Report change of lines on # lines */ typedef int FLAG; /* General flags */ #define FALSE 0 #define TRUE 1 #define NOT_VALID 2 #define VALID 3 #define OFF 4 #define ON 5 /* Expression flags */ #define FORWARD 6 #define REVERSE 7 /* Yank flags */ #define SMALLER 8 #define BIGGER 9 #define SAME 10 #define EMPTY 11 #define NO_DELETE 12 #define DELETE 13 #define READ 14 #define WRITE 15 /* * The Line structure. Each line entry contains a pointer to the next line, * a pointer to the previous line, a pointer to the text and an unsigned char * telling at which offset of the line printing should start (usually 0). */ struct Line { struct Line *next; struct Line *prev; char *text; unsigned char shift_count; }; typedef struct Line LINE; /* Dummy line indicator */ #define DUMMY 0x80 #define DUMMY_MASK 0x7F /* Expression definitions */ #define NO_MATCH 0 #define MATCH 1 #define REG_ERROR 2 #define BEGIN_LINE (2 * REG_ERROR) #define END_LINE (2 * BEGIN_LINE) /* * The regex structure. Status can be any of 0, BEGIN_LINE or REG_ERROR. In * the last case, the result.err_mess field is assigned. Start_ptr and end_ptr * point to the match found. For more details see the documentation file. */ struct regex { union { char *err_mess; int *expression; } result; char status; char *start_ptr; char *end_ptr; }; typedef struct regex REGEX; /* NULL definitions */ #define NIL_PTR ((char *) 0) #define NIL_LINE ((LINE *) 0) #define NIL_REG ((REGEX *) 0) #define NIL_INT ((int *) 0) /* * Forward declarations */ extern int nlines; /* Number of lines in file */ extern LINE *header; /* Head of line list */ extern LINE *tail; /* Last line in line list */ extern LINE *top_line; /* First line of screen */ extern LINE *bot_line; /* Last line of screen */ extern LINE *cur_line; /* Current line in use */ extern char *cur_text; /* Pointer to char on current line in use */ extern int last_y; /* Last y of screen. Usually SCREENMAX */ extern int ymax; extern int screenmax; extern char screen[SCREEN_SIZE];/* Output buffer for "writes" and "reads" */ extern int x, y; /* x, y coordinates on screen */ extern FLAG modified; /* Set when file is modified */ extern FLAG stat_visible; /* Set if status_line is visible */ extern FLAG writable; /* Set if file cannot be written */ extern FLAG quit; /* Set when quit character is typed */ extern FLAG rpipe; /* Set if file should be read from stdin */ extern int input_fd; /* Fd for command input */ extern FLAG loading; /* Set if we're loading a file */ extern int out_count; /* Index in output buffer */ extern char file_name[LINE_LEN]; /* Name of file in use */ extern char text_buffer[MAX_CHARS]; /* Buffer for modifying text */ extern char blank_line[LINE_LEN]; /* Line filled with spaces */ extern char yank_file[]; /* Temp file for buffer */ extern FLAG yank_status; /* Status of yank_file */ extern long chars_saved; /* Nr of chars saved in buffer */ /* * Empty output buffer */ #define clear_buffer() (out_count = 0) /* * Print character on terminal */ #define putchar(c) (void) write_char(STD_OUT, (c)) /* * Ring bell on terminal */ #define ring_bell() putchar('\07') /* * Print string on terminal */ #define string_print(str) (void) writeline(STD_OUT, (str)) /* * Flush output buffer */ #define flush() (void) flush_buffer(STD_OUT) /* * Convert cnt to nearest tab position */ #define tab(cnt) (((cnt) + 8) & ~07) #define is_tab(c) ((c) == '\t') /* * Word defenitions */ #define white_space(c) ((c) == ' ' || (c) == '\t') #define alpha(c) ((c) != ' ' && (c) != '\t' && (c) != '\n') /* * Print line on terminal at offset 0 and clear tail of line */ #define line_print(line) put_line(line, 0, TRUE) /* * Move to coordinates and set textp. (Don't use address) */ #define move_to(nx, ny) move((nx), NIL_PTR, (ny)) /* * Move to coordinates on screen as indicated by textp. */ #define move_address(address) move(0, (address), y) /* * Functions handling status_line. ON means in reverse video. */ #define status_line(str1, str2) (void) bottom_line(ON, (str1), \ (str2), NIL_PTR, FALSE) #define error(str1, str2) (void) bottom_line(ON, (str1), \ (str2), NIL_PTR, FALSE) #define get_string(str1,str2, fl) bottom_line(ON, (str1), NIL_PTR, (str2), fl) #define clear_status() (void) bottom_line(OFF, NIL_PTR, NIL_PTR, \ NIL_PTR, FALSE) /* * Print info about current file and buffer. */ #define fstatus(mess, cnt) file_status((mess), (cnt), file_name, \ nlines, writable, modified) /* * Get real shift value. */ #define get_shift(cnt) ((cnt) & DUMMY_MASK) /* Forward declarations */ extern LINE *proceed(), *install_line(); extern LINE *match(), *line_insert(); extern char *alloc(), *num_out(), *basename(); #endif YMAX /T(0rxB3 q&MC2 ʐICUP `HAHD4cФ):i)3$A'cqLC9aj)᚞'O" €3fь;Ag3Vx8e'I,S)gCςSA$QM0nv!a9a&  ܼQᙺlcIV77 L\*_t怨UKÐ-aWpy".2Rn&1<{Җ!w V{n12;AObaQowCk)FS醐Cg!WUdhƖC|&Q q*6RYϕOu}աnxdF!Gt 5oXti0#Ry~0I]~_PL%VtAC=y(M1DI'uI srDVfIv&YB4¨_Z~uȱTbwYǕ1w,WeGn8lXTehi@Gb,fL9bT}FAC9CpXtxlc;qdp;G} 5DnT离oe{jR8bU!Z 3G)<ֳ@2k 'uig^ kk!%u2\a5YkB9MdAkJH&1o BqBu&F˳7,H/ôh"%9y$$F 7aKLrV#ٻJbZ~ߑPnVv9:YC6$@dYҺ# ΄ =Mf˝Wj@Ȭx\̃L# {D1:=Ypn/1T(r37Q!nC3a/}i~$,z! TɰbH${’ ̊n4IxF+,f3s :x6!M#h#eا?JCBgdɻHz@ZNP,Qt[yƤ.2 Q_ɥ8!3V\gX{zWf"2"aBD`d>^994&!XGQ. =u `\T  <ѰMWIuM3CrL] o FIrCn=\Tj@n.˲Nɺ@ Dx/~)<fW8W+Yr(w(rO_ۈ!d_?@K6%vMC6a6"], gd%q{I>E聍v'1y#0HB=\&d$ԙ`bA$uYjy!"4ң(|BJ qلf"l#IqRceA#\HەNiVJca:mѦo*!^yTH<z g*b0R,zt/ˇtw* I*@@9c.ƪЉl.ImYq釀TRLXG#!d Ыr@ 4^QPMxyN032C3Cs藜,nJx4OvIe0t,H=\GeI'_ km71fr"XPtYUˁ5frQQiQ)anI5˲Abe~~)=6Df+%VP0tA~:~ -#GNIf_c&1D%DG,-9eQ yX LPIY`xZg*Neyp &噡*~@<  4сJ$v06!9A$l;b ,^23ς "ydpB>C;3d)#f2 4bYuo _(`V+'EőR#dQ"bK1Oydw̵+-$0Wg1/ 0a ϒӮ"žeAt Ru`A$ggA\kp<4Jbo[zKF>o,/JJL 4N٢6ýdrIyr7^b8#eړԎ[zHtW<’Ȗt[*d-Q¼@#NC!*zR2:WcAݜ58ٜBbe*u-lg/V'dtU,z:WI@<'#HF,DtbD|NCH)2DKٽqb1~vɚTcu#'rSU?0K!PKv:@3ՒS;ދc=W)H [ #9)660wHxF ^(NKLR}2{KlD \LZJaD>Kؠ%d>YT@\&.Lݫ~hյ4NL ʙ] T:ZnlrF~\`9yP .~d- w^24+HAe8NvƔHĐT*p-'dTCA_^L1%Ub 3!3m1TJQrc[PkEs?©Y~*]9?}KT_l=;k2n7B.y"銷;[1?Ñ:ua󋛽kNo݌xb;5N{o)| Ij|f[ H*d1QALWJQZ^Ɵvj:ɹO=/us. ݱY@ _fak𜷪oЪ5uzileGI5"a񨰯qL qa X 0N5*{z/y; DT~I03RaKvْ׼&Y[b čy 0 AzVe<ߠiѣ(k=Ѐ@bDb~MKr) O$|4t\6簔 rU 4uP@u%֬"֎Re)2hNQCx镫vX">`a!@ ,b#}_{ql"|r(*Ҕ" 6ͮ/a#[HI5BKG}!4 H3[ dXktBCrP:i#qSAE@0[ԅR(V"l)px*.I t|؛U`p+/+JMa9/PxR ?9U bAHO# I7 @ QAa<_fqI3pMP"H*`B#hNxEJDa?"i5B*C{DA}LxE<-|_96uJg#MƑDz2}Kg4j݈VB xXi(+ۍAcI e3l H!r^)ΑDC =&#`r!loq(FwSI u Z}5@$0dnu,8VFz gf,GHvͷd_DkNie"38$r+x09A"2$\lH2m~},5Ѽ4#aa$ &t_S6mR%$=ǩ{|rgLWri\c}DqXeOic}t.#bC 8SHH꒖iMX(Oš$QgNX>8/oO$%si2K]9Ok.L%&Ah BIW#pa$>3 ' #DbQ8o;8p!=:)V(5ʘN*u~;A&LZS`fɐzfLXW~HBJɏ;zGXȣyDleMbi@R/&S!M$ZSNTj7`g;H(+\ .%Kx_~ "%y*M;T:h = L/.ijy)tS0b$ cv/ҁk[V|O #I@T@Kzk%eHIj!܉KƉD"C@c5jUy:ժCHdIc;QJ{GD J KSY!6'xXdͽ>9aebGtB J 勀p<"8.L8|" A%T)px)/'Tc', tኬS$s+лpMVuhaХ mUN=!@ , &ȦBsSc4B ܉颏L6KD ,A1;k5S!LhdS-6'vN'Fx o ~X6_ R)'^!CxAQRq@WU4JuA dlb)SaC&\v7xֱh;kH ,Vj;YMthx^ faD So$%x(Muh$\ylq.n'Uk>s"a/re %dBW)uPhDTls:HC#6ھE2 +;Sݒ`a 1lLv#UF"٫HDZ dk:%@qcZ $ZƵ*1s)>ᓀS$wO9Q%vi xzKp`yF6/&pܲz+w;cV M/)h?&|and\NcA%8V9k"|^O^$TֱRf:tE<ؤ2Thy- WzDg:4Y <"7[8RCE(F5 /L܍lb %L׾rmzR1-vN,CfcЄ $g".-|uЄ<ڼךa@6㌘ڝnv9ۥ+>֌L+{{9|V4QG ) <-6=\ SH/BMͮj ;)dz@@5]1RVx i'ӫWRzC(t {#1I C~כ%n*Mj }ӤFEgIFH1  ԁCܠFXDj+t@N )\+>:EU{m-7?g^W`\H)sO=hSjΘ F~[>yEv@ @[Ƹ0~yc K#>Á-%vK F@cYx=jH 8ZD@أD<;ޱW8 0qO>y- ԭ5"C#¤jR+`m9_BXH^~kcP‘ ¢!|CO%d b3G@jUEX'BT@@)&>Jy?aeQ[%񕙤qܒjZhcNwt@U$0?ȝ@K}aD^Nj@L?^tY1SPsXᔣrFNL-< V>k+t9Wf9B'O윗`΍CCNKȱ~)ht/TL棳wZ Я:A<|/P^E`TGI+/3YV:$]S8u'8{L_O Ŕl4Ձ]avn̹ 4j!Own9[@ ΥDYNי; `6vΣjw]OP^ŧ;=pH˙T?Wg_ꂻp ݝm$\hl#V'dO|Q,wI(M d M_G[ PSa\c,CE wTo->Q]u\Ɂ!i$|7N!TS{ @O'm$U{tCwOGkY@O2_[/[4@4~琒;~ՠ n`^/ͥwt.1@؀Il@`7Sotcf9Va}rEP@пSu X=n {žcBܞP]N (saղaG6;yvS$|qw}H6bM=(^5? o^/WmrX |k pH|}u"[>z3(:8)S)ݿ{%d`_FՃ_\w`>'%;F + ŒĐwN w }q'`TUػ8 8 #D:r_u&>3ua!ЅQ2>pfP#N97hk+ H Xܢ' E:<ݝ/1?)K+ g2 > Q_B֢c~RRZ@ ep%$ '7Z? S@kQuX/ ;.YUV2D%}E܀.´,L6J \86aҵQ+=3'!w/ ]g&c6߳i7v08/_ l E-Rysƪ9 nʳS E:\v.o}MgRS,S=x78$ݎ">/Z9 MW͞I/*`Āf<_+`ٛ9Y=_U+`xV(E+ gps@/Z9#TEUe,ry!žvxo>guMs2dC?4]ǭnvy8 sߐ%Bss?h ϲYw!":.!7 5oy*,=myxGC]o+-pSޞVBōPX+uabN4 qCMW#@+K뒶%!n,n{".ҁ'U\ZGHWnUuz$#\?#]hl4I=;_T0@*:Lߑ=$}qjЫ߻a?Q!ԔI@ǃg  P `H~=$}qjЫ߻akF?ן± n@V8Q=GY^żs8߬0 ីʂ`'1Td$Ӣ! %bpqGК =G ǃ ʒz q~cI>|`:RNYF4I.yߖǏ|'az`_.Y&{C_q"!k-c+O^

S'Ǒu xP@BߠF$USyB$|^FxD=!w:{|b!ǏA b%`^ xS)Z ,N(M`O Y3w8$< % {*OȭKa؁KBQIN<13 [&A.pG `)6^޸` nuxH=!q;O q;،(]E)]O| 'dkou>o8k39pu0{ 'd(s=JM \f?8pǑaMowj>W=ן$gm_q.,G@6tq<.3:| G ȨYxR1?x$t<'%}0Ā2r9"w? O^!;@F.Cy𿄬x`N X콎q>1px֯up=D/L ˇ[Zv"lQM+@:'z0&{*S C˛gH*l">D}Χr_zߓPV@x]KyV{o.zkk%Wp0f #{ txG <ؔ\5uBH`e+D@FPy/-ᘟr W lA!zA4X1ӣ oP*|N gQ )Go_H0*rsovK_'EV[W}ŮVAߐVH/ҍŜoog>/9{I([X-drg91p +̀bΐyz.^{>Nȯ<'^+@п ~PO:bjyQħl [r@Z8)2~$ #L:C|J«CtFX78 pi4/EHǭnxW*R?8o=seyYts%BݎS'4_@ so' 5oKpcXso' w0sI",:ow,7#KNH (|9\1aMQ4_|sܙ1;ͿQΈOUgV8YE*- ObCg3,TS4XW2k$6[<.4Z@5€p~6v| T&` ge*WȾELe05p"sZoYI( 7d{'cvIWJ&׷"RЩ'!;>+|Gf9$GfMli@N}u96t5f6NCD6ǍouH ::$ 8jRE#KtcqFHpoZCJ !%>O}eD%Bw_OrwKv6>%!D[[|a=iGt`p/Oz > Kv>HomzT$i=Ï1u!.RdqDžynJt.B=w+Dž9BX12x_I믽sSǰU [mkmU3+b4n[`İV@{{cB.Onk]OX /``V,o, ` DzH*:" hT<[mkm N+` ֯u~ u8SXEԩ}gw Ҹ@bf6BTc+C0H ' yA<{yUF?Fu0Al"(ߑ B ҍRE L8S. 0@ϝ`iJ)i@Z0'0 "@rGPy}p.!;tIՆ0] Z\k$ϙ ̈m;|q7'H^ ƊxOy1?)˽ SyNV 0}G 1ɮj.='%*:$? KaSyNE(U0 ޾ x$1:Mp>ne2ȿw y*O#ny0Ε0s <\"z;9'%ui @£ ^s O=[o$~L}`"H3kڶZ1o?V[5fQW:<{{x@J{{x@J ^AM9e@:hҸ9fԙ @HN9n@I#Ҙ!S *N` & z1 /OPIbpHc.Tě:tN9cq_2nD-><˰SZ22o)20;RIl2k~ ;NY!NKSoń!qŌ-y2e)RH^cؔ #狘:f#AE=J.U 0@!K'^t!1a&aڏ&z <bHfj3Th=XPCuTRK'CCtwZBUtPtOi(Ġ<[o 'qpUmi{69AD" BƂ‰A7 x+C 8Z-D*%E+awuC-OCv@ !:x"Xt1tPrCi[! 1[y"qS2@Ck˗Ѕ84u6a*ɺ ]Gl"raߜJI BWm,4B5 +~z7HBq| 9,iK["䄔`nZ",O+N2lbRx08IT[װMYv];C!\pF3HʹJ dKnFQ1)-iOo0m6$ d۹ggkY 39!9D#:v 7iJ򒹹kYSpHѫfKt΋}Vq7kN;37Vi{@ a)4qKaO 滿뾥[ee\,"c|[N0Yb `ͺ.bCQ'TV3I@t3%,b VëFbt/1.D\Ĥ>\$7FN= F)o uQ`rAVZA_Y2"]>W'^o-ն?%vV!6^۠1x4!>\"+&Yi4!a*`,G&!DeC" "#C>tP*̎(@R=ˍuN%r|618Ҍ,53x001r[CQ|lt0,@K*,p 664o-H+L՛..,p88 _6qLeMk' m!TrsUW=bul< gìp `j'P=%r>] {%5_*c_0>"uEKjB$:[\+z7 Adw):jaȥ0`:m17-ğj?%*Ma*j.]7ޚ_(hbn( 0b@1C-k4K4"4qZ"jU O`])rŬ:'%1!2u ,W`ۯBI '!K !']!l N) ]?.uj1<)PjB[{ru+4R{AvLQn$N Nhj!${J>_2- uB݊c0jYmA`#| N5i\O1ЕoCA6AZ:Ri1< }&ʇJ ߍf W C͓rLTN( v_ Q!Co%,5Kd]a;oc18iVj8` M|'lUC\WOqk}1 ;Ƣ&rFeRgYJf~NjE1,3f5/oU6(ˬaX,2ge|!P0$BTIRppTQ91|G]P1>3EAN:a:m!ubT,Wf0Z ^"2qe{-z{Nw 6QYz+[⍡0L!N "o_hc+r~`ٿthF8+}hCS*< ?mECf蝨w\?AHw@zi+mј50` #MAePn0H@(Z3n cQg)'*u IA\iIĴ $5\Ck" ܳ4 U=M H<|coz<Z=O "0H~ |3ƴ" X\+И1#Ws4gNKX ޴*N^ш&k&Euea- Bbqs1ñ-h6kZj Fqxڨ 1F@oĂ-BB̡r: dYXȯ皢( 2B DVYxhLv81mZh J^1"0HQh@H7yt(^0뤾 c$6I2b)զ8BS"Tc%h"@@ˑ:c'[jltiD/p-b"a[utNA |=Sh#JALJN*4\C|tE20Ȓf@@Z[u Ͷ瑲E-"X&.Y6Z"'}RwrBӓ&J(,&<0MÆHBD)tEd;sVn1ԟ\%|@(@3%貲 dpJS si g,KO# -S7(<ҐuD Ebe/QN:wLDZvr3šcQNaᝁbD Fq4@hvJт뤷C֣w*7d`EJXItyݕ }Kt+CHVU.R"˷PAy꤫ T+3e1Be)U=Mb1#j\iz *U+-\X;8]R7z%"$UdC80&ÄajiZtJn$5Ѷ+M4QGH2[tLH m$) Xi | R!H-S : EH8.$ , VX>Hv<8U9 |!Ig<N!`Աx`D$~WI|BDVLc/\Br0mR(n1cT4ђKFs购` :nC!"\ ʷp$ [, QّcpT,kMj!_J4-?߰+ (+bx:ىURkCbARtK^ A;UʸO aO"[ >\ЌH/㌖n㹛_&Q7W.dy,wk%d)<\ l B`f<)lƊ-V؄Zª] \KJׁ[n]2JQ2@ wj=꘱ =R|*xUʎDMMU4_ ^uO;Ey~X]{Or3a6Jœu+~bzjUa;uUݼ.2s mJ:+X&J9pzLث\FH&̝"3ѓ!s#igՑeW*S挃30dT^pU`5t!sm&O4HO꠫h\@ eY<_Ⴌ[Q]fO 8̞){xIL:ػ`iBjcEBR9Uy:VX- Iw4]uմzE<'5nSV-˗2su~Q+<3,qr y|:;dv-PcpCaڈXd 'aueoXtr8f3*s!U {m} 4 _AfË'"⿣u"q 0sT`: Qn-؁ӞILF,r HH9S4ix ) p@^.r pw %mdh9!Y…UH\ܛx"Sdg2#/h|]~2kËy&<0^yh|rq6^z 3 r ! c}qFv3V!j zHCg C@'!rC8*⭼ %n@H9]O.lq\ˎS TqNwśk &/T(0r耐tД&2d@`LCUP =R\ɲ˗0clyR 84ycg7mڄqCfN' yrӧP9Rc!3QDŋd\A2 ӝ=^:p@Y  !<({&mÇs)Sƍ S$aFĶkEMΛ4d O)gN/lfsw6<_wD<)l쳷 9Miԙ8ȓ po-@xI{>̛;C$n޽}A 6:_gX&1BMQffq^s)@~( Ex(4aљ &!nyHG!nC \qBazDFAE!V"ݡQpD_m&0um qei݁EHy8i Wqe$^n$:&vvrw yEQ oQtUȄux(pF΁F_t0FC胭~1tnQTfeacUx_E>W5 &Q\cuyrzcpI]nDNEN'}/eowm)rq~ꨞ%T_*Taql#D% cf8Q \ܹnn[SP[￀ ugܰaeP'o3ŠdZ<I'!' hSZ}Fch6 dDXړUL.-/64[9sVn=^xZx*m/ƹOlPAr{nzCed'uE${+<)} 3%h ۣ 7Qe/W7& S)H R^.}$A|72d@!7 x%h d#%3 Cgd \ :Ca`VSd8n"dwFBsn0̪!kN;EP2(†5 |dJG@Hhmp\\P*0$B.#jDDIxHD@V2 rND%Ma aHK>Yʼn2Z6c܄INex@8?K2PO?i@`v2AB7ӰpZIt91Ёh $aA`$fPdIbX%\\*#puC8AL}XdP@s+T1AEY1-g:C1g~b rYQ#H88#m °zl fR35XL,[pɉ$)MY:TV,9Җke.^"P0TNdɔPfK51&P 73qZM]8o* |`IO{fCũKfdQ <)?Y?TUEjDs3p!UpB:C6|tB32 s\r(k ${mn~T6=J0A0(߈6}lk@S eS,(gl,r<-o[20,pD%0VXsR\*H3] 2H@(4F+⒅) Qv`)Y!ENЌ{&@ LnA@V:0f [~NxLs:Ɣ& >PNSƭX._PKkP5q3*"%r˲!JF4ZvdXJuQAY ]6eB$S梕cerPhG3jC6u$7vߝ|=\;Chzvݢ35yjf ֱl \˹k-},9@H{]'.x ^ƼUlު?sҗ!7A%Ji;A`GTR}BE{†R~Q~--gdF+~5;W%!#$R` 2޶gnfmQoqB~agE z8хO<jӡ]XQ,腅BT+#pp7zU'\kf}QtG]tA^R_u,ł|a'6Ev{Aząsx bxh  paq]n -p_eE36\c@X\/bIa sR|J b(4M`=jUp$K.as(kD\)h=TD^'R\H6 $p؈(Yݘ:r1_)OD;E@E9Bqae`'xaLG[vbL@X=*:>4Y7I/"p0^G)+C){!uIy^McFPX.7I:incsu& 3W"$Coi-(K2O'nT² #0pc'q*Xgɓs8u I(!Y~x8{c)MWd@ ׃m `! Dp`3(O B59J^wv3Qݢ"#+(/ YYB!#;B[-x}N"|CBik@uP,&GDEdֹ2HaYE݉#}R8{{ii#(x! ))RDYvNxؕKx`F wUbce3=fV\rt>2""ns n }bgQߘCbr 8_e`AJuZ˨")I YVOEk@aL!>)KM"l@@>4k`|B&F( )b*,02YeRIޅp"[4psn%1M깟ҟ"jDؑ+0ٞ`9JZQ9xj+Ԉޥ9ĭl!ab:t{\Gj'M*YJOTzVz{0vjǺ٧CiGqE SW19Vt~!R>#n::Q֩j9tӪ#4ۮxBjډ*'u/B R`+5G?c9c{)r;.AgC0|wØ3pUX_%u 3GX @Ujpocpѧ.guD[U)lkVIղ8F|EyI7+yN Y/TB,@W^ 0SU*Bk{Y㥗BPnkX) A{WzseYHǙ-KEi9x) ˻*4˼|q~yNO;E\{zgqweCe榯K$=BwAL{(!, 0tP{J뺑[,LÌ{ٺ55>R84 F;gpKnͻM趡Ylͼܐ?*$=A&D6I2>^rP%d٢ \>`N"kT)!C!Vm13^wPSBI'A(M^ZlH n1*}Xb.uqle \1e蹲ԥnY^=>齊*`͗=E윙j"_gB@l"biG~ZYg>pq8XCO#ACCk E{8%]EPn\)6TR9gPCh?->\`qoO[B/!rN9IpPNUNn X*Ӛ?ϔo$(24' 3DNc3C0&ikhO"F( p|-â_,!9n{d,f8 (Ss.DD/=Le?OH(W.CySzk^zL-Nxf9 T1&&uDzn*#<Q yI7j+T!рKQj6!oсqjVFqPC2?19^7dPwUxwwR9G|G4co=4=YlVy-I@ hK8g=̓현G <GIGcqc`X(rf` Hs)U4 ҋ71Yx4Q@c&#,t.b<G 1˅IږC;U Zc5d!X 7(v+'?SRP> x2xwENw1#hJeYK1_ (J BXmD$I"%a :'d!QJd-v\rκ"[p|,Aiq b35`N Q"սO%Igv3{ R?q$KLn5itM 3f<ښPˠ9@4L 3A7[5SS#e7g4Y( =C|@  ͸ЉZcMJ #rY͞)#%n8eLtçٚR5f@@E6 Vnd^#eE`>'ѽPR?,n!rb/7J`{4K&ƍ$< o-5b !}Ö?FVGf:BeA!Id e; k\ (8'^qBQ.A4 WzvWI$Th%OiE$ ;TT`ZTZ}YT969֠C =Ebsp`"g"jxA/ᕃJD.T{]ᷖ)l~ismc6wbstQ)%omє" gx8RP+[ lLJ{cLf7pQ$1lhqXdf6Ѐ(>Ǣ3 SD[lћ) LE 6PX..g5xtE6!MsZ%c%j :aW2RŢȮC^Q5PDM 'ܓMٙaiS{#TZ_Ts[8yݰSeJboQy"? $cHIOS ym}Meͤw!Z&ND8K^@Pz;obk"M&nތ- js̀?ҤPu>B!¥5.j+^e_1%3}\:³ (ႌ6 m>!D"h6T*JYzu7ך T921S?a~`":D !DV'T|#U:,d1HxAWV冕CoUOp&! 0qsdwԪT_cc:fʫnۛfeB#YI+;2D,6.Vl+5va &rR7ݮL4v3'^ ^DjEč#@~oIןio)W_|o!4 x%?`l@G8)a_h7YQR[n@;&zz8Tk[^f;. XP_[C8[L8a7B&E{'fA=],)H#@}}o~Xs`S)~`~$DC 64HGޞH80-QpX@Z/f]Ci0,sެD0G4LޯR6;pA1\E 3y)@ د-\N:q:\ Caj !x s:^w6-X A.`"̘wuu^"pfk] 8yo="CSmh-tɡ;h?mq+cpg ]H*fQ@!׈Dǒc/$1m)۸c"/D8eBl_.ajFHnOISa^\l yɸ /coՏ)W0 ~'9VJ3[w6!˲k;<lU8W&oRX FYOR>Z|JZ 5FdzD§Lw_pi#\jbPBx .qew2VnPksTJ*cw ya9 8Q]_0ߕA"nK g^^XS$5~Q]*5چJ kan*kf**D H< bR*lxm1r9M ZϧM/ Vg+ @"ɶѓ0mx/;a'fl")KrSwoz%-m1Զ`cQgn)3u=I3ى4Mp^9k/U5iq42#jѧK:f)ۜs iFi'YH/Lf&Պ}.qdA "UBPXh29]L3 *:ڠp!0(QU_Fv"jv=@nFT`牲~)e@ G8Y|y̮ΰ *,8/,Vv@p Y؛Ԑ"b[ Vq{dD5É_u4_ 8_q)cѕ 6j;dOi gxtJj[aBf!JP՝ *3Q(n9e~ҀZkLaA06\e1@.euXkBoxP7`2 NJ&BS @&zK6=4tKvzA {v@Ɂih- 30Z{A##@ba.&.QԫD'=n}(H6D7wazw*/ nodk«gΎ*>Blݪ `[dI8YdgL(K?Q,-7|&&M#ԙԺZ.ᐁ^w`J[uVQ<}~L6,N;m-E 1}e !@ FݲK4շkWf&pb#\) Wq#I)#nFcBH淢8dN>Ly H\0˳y`R.z2`i8&*qrLˑ*RT^EfEmwMmu3S@hzFsP]C@ G# $ pN`f60yf&J.*tKp)]#cpR'@O tNL_H'Ą?"C~9Vb)L?,S=cmo@C)RQZ <؄6.8@/jlx Oan?.\W3k}2BOTX LL`Ƃ͆ PꀞshMh P%hoBs^P ՌX\6j|$SG nk;TS@ [;oa 5+@ 'SvO{>I%9SM\̊5$-պ~2|8yhyv΀WbY#){oꉀ_ c(H&Pal!pEIyzA{"GʼnxD~"ThJ+x^ #@S=N\61ƾ4*,rGai8h7oTx1">+BC+B܂㻜CD"f4SJ>*T:KӇuH?/še(!,MJG 00O|jKWis`ձPqj߀:!hݙS |W3Ӎ0 fґp<RB򴽇Q2RyNJLugB*N.@[xfJ'"M6Bȸ|Q3ž2>Qˇ}1_29P1Q:sR%-=8DgU"` `~O M?8"B!a ePeW-Q1C|FR ehwhp^P [zU" )y1fHz*ߢbXEdL.!*\b>7Uv2l f4n[Xbt݌p}KKKa;W"n'(F " j|\rG^|RlBp5yZBg5YY:hgڣguydT;IN ##dlsLV3;).v{ $"@DP䑶Ĉ$"@De= hSGrj&\ G&#VHO)gѨM.=x{-XحZyhh3f|ID#Vf1D(6=I ,E@` Hzq(JbW(6!{tE`'(2|Z pză5F6& }ɺr)įv *|I1 ƌj a9Q8QErױ<*.Y9էiT=`R8l˹~@PPitֵ:ҙJe~(䫬XlJM.J":Ckh;QE'W1<jKr*zsg#d#rW7TݪuaRX }e`24]YcY}>pe [Ьw?z9Ԏc#<6_[~D*U:*v'&O%T 0`ՖGk, 0PmyI 0`ՖGkAb 0jˣ ւX '< ` T[zqH 07^.0OrpWKE'@(hWUivO?߭g 3 ձnN=b@{z.agJ0P4 VVPS*x m!Lڤ~UMdv$uVLHb&I<}́T]Q@D^N!L\!^ڣ` 3@YXC 6\& tr0* PlB+Zl^¡ W4p("b">N,)ĎBXoU !Vw+^S9ͯ O2cd1Oz0o_dz`ìd|!7gPK Cq.ãN\ ~6k;\p0+8IxUsHp<`(8 Dv#N!>``fNc.`l:\fߤ=DBӋϊ1M=Dhu#^:3[Xu*tr>vi~.&4ؽR{ #):&;Hf4+.6:J|+0-'0R.,tp{@ 4H8}E4͕5'i~= Bxp(6)=D4_D~V++I|(@۳z+sx 5PDHؽ^}}Pl.Wyp VVPgEY[&p`f\ȡ%u|Ct  MLMr ͯ<[ṹ*vW\__@!ꫫR`z5-Vܠ߽Jח hvu}/Ed5h"2bc$]c<  +@X C` |$Q@)a2BW ,`7PD$A V`[&\:3+BR\K!"gF0<{мzBeR ~1LjBk'kA`,dqXzmd\zqHQb`734[i\ 4;&>N@bY:̓KQ ьVX/'}ſj\8a:,7d6i~.fq^ 2QbSHㄜnr5P& $ qEOh~.kG'Ip?a/% ]b'8Nf eؔ578!7578i~. _(wQ5!1 PI%㘎'h~/`O!33z{+ k>s3wn&[bE]_ϓ`{qF5fql|"0%%hKN=g'utN^HNP@o&o-p:XW2KvfWZoHD_l/5\{,O{b J46miw̌g [jr rq( 懇 rqH <13_J8$ś yÓ,N&!l{(tW; Syb98d> ZK#!J M]OvR0\$p3CF(-A4Hje1Lj"XG{,b=O.E֪d`rc m b- %o% x{rs_}4ëi$){M1*[!xC` \,F3W (,Z;'ɧWNh{uP`N7x?IƧ!F˰zZ NQTʀ܍&F@ݻ{H:+=+P1b ua\[F'弮WX㠃#CQȋWlBpaQx,7 W sul2Ĉ$"@Des( *u,ˬ֖'y${5(@K\[DpPG[r& 2dt!h{StPZ6̡{d:jM~Ӻ&TɁ\" C"Oo·>3&?8^s&" aq 7}f* }9h"9^8d4\Í" [tgE2bf @.ȕ?H`W nXg3*E5(@k[ H"Dh <=~&pE|V8cE(6S!K6#9C& ^QqP,I]hT Lj}d:YnGb9dULu3_cV9*D3s'h084={_h{a}1{!Ԓ%eʣTaȺ O̷C{H!D!>R)eB!> \rMbE@9Ra1L}" <=ڂ%W?K0%PU <=ڒ:T!ʘ4A44;EOjSoo}q1IK RBYmF my}`B7LbXsw&7Xg܉C|m@؇uPKC.ófib9 ]}ERx"޸H3s4 b&V, `~xoA+f?e7 yF;p8 j&/|] C'3 i #bˌrj6LD߸(?d^:T%-jY 1R 5!'>52 Ym9@m؂ O8f8$&U؍l<]ko7Jr[Z319ϰKX,)`WRԝ(CrNt<&2!jp8ҦaTMo1ZYeT-Cewenp-IϵyT@(N;O~ *5gH9Ք]+ѽ]ي-*b1g:`Կ[rJ`CR |e!s27 x?Hzch&L'i8N1aUmXs2WE +r~ a0ZNex* @Uf zCa`;A5QxB([+`*59T`9mJu腚M!`)1s:9<\(0Dܢ`ưB\Vlx X{^B,P!#̃Ҝ:9be Az9]Mˠ+7Ķ1uO,׽b(Hju02p]I?/%S4^v<3*6RMA51,HwJ,m:YnnlimjmF㑭⟔Zߦ"pE`6tdm)agt9)r9FB`Ġ5@HwQSW'Ma1~,!]y@5i"r3R2[ @!! Gto1XbHgVPjv-S=?YX}-vG1~ 3g ʒ}j)[1*sTyz2~p+E'K-lęLaG!S1rQ ejq!FcaۍɸTф:.ř✛J*` ʚ {2TMKdtmUT 91EzFh*d S"{X 78GTLV!OLyl|:c?!,o&jvmS|v1UTWBye,׈⟟++ěWJuSbƧť^ X|IWB- + d,ț=>|IMV `|m4%JUʮ'`S/+@.@ʎ̡~"L+:J()w_Ơ\ȌR'_,Ûq?9;fܦ6 {a !`VT=!q{! KYlBNqƩѾ1Kdβ?MV-A _eHͺ(iR]L&[ -hNʅ~N/**/9.NQ(ѵtbNV,k^A.X*T-Ld}H3PPv(W5r_7Qs=H{oOW؍mmuk,;}/0>Tnǫh|s8nXo]`]E#%RXl_6FS2p\jeS%@ܚi>s2>׉OE|-M. +,&tL)g#yũO/tZt"a !%nBbQ !?M0K3p7o [O`ɟO[S(o~ &oB''@emh!Kr^~@\#3}EX U0qqjSE9&$Ecn.*,dN#U2 HoXs1IAa(@#vdo@22MbX)H, T$ 6'G. ?TxoV(a (xTGX(yyNrY|nXtvqٛ(L R( _?W d*9sӦDА9Pk)3MJ(hed8`FOGr!gm38QU͙coVLj)]7!!@SC`#Z#*ʠeh#!+KE+P*wTjPB1TSeR Ufkj;gqjuk /b@5+qy,r*:@ #%@HZ(?eLC+_G]!x 6"0K#&@,"1D n ~ ]K~A | sґ!Mor/…ȉ>$?(CQ,#ӱp&G? p0D8VII, KE•lf:! LPhz 2p܀FZNbz.xy@ؓ0b5-Y47tp?#w,h@=! v_qt (9rAP61aaA6Vn#%.QA*UNF;)BVMHaL(` 3ʁ5/hT(ԙH<,_).ǼU,ĆX~!Z/\q3)X@Hg1E?qTnG%utXJ#t@Sn)iPPmR:B(68rtJ0a.E "B1(QʈO`# ,7R[m4cqQ=O{L) H0C:H.@LpGcU@l3PᔛWvqy*QC2QnXHCȌ `BVȯx!uf5Xr%120qLkhQqZb"puy."N;dMA9 UX|@j68@FVG3&'nΊXc2Q.9E,2R!@ 5刿LG)C@R! |][fPV̗9@g<agP G濨 LR)N] GZZ(F)-e)YQr#a"86~+bUd-'hi7fHq澍mAIǙ |W(@HSG(*0$A<JY %3bJ9~ Wr|BN1۔SmӠ)ꄞ+?Y$QS қt]NcR:MpȎ6nTw80=#xфJV=IfɗN\ʙnC2h)e90ABCE&%i,EEH! RbE)4NL"J䈤dithW"D̍BP8<} 3P#Ȕ1ME)# 2 Q06u1'7aظ@モEy0lfdɊn.f<ȱ 5m4AsЌ@  Z(]Ę9yܸR*^U+eذ5*0x@Îoܤ蚵( dB% ",X&'R$QŽ0yr$ݼomP8qܻkXN)E,z$Fvۀ9$EQv&S>{g7D~ <$nH'6҆HOrs҉Z/%_&˒ p3ӥ6>}X,cA hIxpU*Z 9թ8 Mx7|"udobYQAhQT0U1(&qC ! pcvf\'qwT$)SJrR M/A*ωm248 qF5Iob)5/~L÷Xv3}ܪ$].sTy(9`g.6p2"a̷׶W {6oM ,tWVԻ]=1@8g cQ%"*ퟐ[jUu3fZvt3Zz|ޢcRfHn鈂yPh 03D׬(xgDWJxIAωRTF, װt.0|,G Ɍo+b[^j"ζCJ\5Y 66"b-Q LJ^0S ٬ ѣAV&uKN5{+n&w e9)F- 0,d؂~NųFj5L/Ļ7k3n?M>s dWEd#;nQٞ *ڰ㪨hN4ӛ.J|F/ÈG.~k3t"q1`Waַ.$_CA8 Wut'&=Kϻ^ėUĔV)OqZMrhD~"Jԉ2j6KcVt)Rzc*LB}@%3 ;f9x B,Лoylgwb wV}wgEt DxWsxrvhwrNxlyXy^ʆ5-DxҁWGS~U3s5 Nu'uwg}~J׀q~~5~d2(3';8=m- vQ!4B]qBwa .5_ W_6jnjG(lb@#qQ,F\2\dv.cw]5)SjV/"$H $t(@t vM"7cs'5ŕbG(uWehHzۥ|Q1CRxl7WOHGcҸZTefa}DŽwP! wQ਀U؎Wx283D{C+j]QImMe瓋wgRƈHLMsՔCy7NңaQH&MkRuJXhǗcGr`ʎ8$>JJhyj{=Mr;vrᢈ5w^rzb]*#Q&"6w,@"pwjCwua0j^ 7"/":ep?dZA Zʋz|tj"0.f!I~WZ~L@^(u"@eA⴩$E:PA{gw=*wJ0}@:r-o' ZrPja ;pxȰvc5-c("=H$~_^Q$ GVXjCi(o`(@өM*`ʦOTzejjzMTʯ \=>p>)a@d'44XafKw"Cp#7 gIpإdԀfSͤu1Wa~zs֦$YƜVtScQoGHx8!D˟Ck4'iR".RRo or6y(oqGsBR@oJH鶋A*iًIW[[o@i)r6µ\AK;s@&n6\6u-f`bKj(q)RoKD ̿t)ɴt(6O"qqYD|KG M=hUSb n^6d,.b2.=:J;y4-v5-inPmpMӜ;l=mxts2 }Ԥ Na:' t[<1 Jэ"Prf p`]lX#=#ABZ;wlǝzuz}΍D-݌29q!݋d-IE;6ֵQo_3@tiW^>ٽ.ս_u{^LO kCJnjӉ|}(kΝ R);E菕]LVԥƦNGM+XWePsRTP| 9Bd`<6Uѫ dOV_DТVg09O`Epc0=)5U^G@RPd @9 zWda8(5Nnt&$/'E6)oDHf`hH`bHT Dp'ը{$VE[tSpu&?U_}qsB JA6 w̶,ӑG2AT@E8cS@O4f̨Bj **.dX(ܝb= ѡw;ùazxe]WE(ؘ~" pؑF90^%VzC ^XŸw:ZjCnfަ~hrx wŇ>yQzL$1/g"9o ~/?ڳ_*=-#_0,8aKC*aai:=ls(`bZ|#j6}"oHD*a!YyLAs Z,? @&qCؐ^,c$<"eΙpR,rM)$(*J_lxƝ1 UHAG90X4 EB/ ;b]ؠd G F4IŜ:" @ φPf]e h"`C0bb)>ʙjO"h%Ƕz$b2e K`HKL9-DZBSɋA5w=SA d 2 vXNM &ơlx:+ZTcÜb?,._#φ:3hAdsSO Vsa:!`‡6<(/;@MSyqh œΆ׮w̆^>I~k`2f'҅eQHnȍk&dBXXTC“Mqʅ* TSdFp4ss\wrrtIְ=%}s{lV6& qU^!B5Z!}pgVܫ/KNX^o睭5[1*s/8_puڬ1;(ߴ->{ > RHBNw[+c"A6MLǜ_.}Փoy)_~b~0Մ G \fǴ`, ];S -Oc:"8m-PD{[q#a|rVo{Ewu+Ģd(n\&e eҬ_/9-3 h`<6Xo ( 2qE C:,9|i\nĈحL9P|ʦΖ6H鲭 ^˧UQCU+ ZrͯE;nQdw]W& V4p+z( e ʡƻ`bט\|6,Լ En׸e1mF3܍Ï7h0Amh@:|-lHIȅ+[T5W5^%*8#O@E *LB;By\k8iJm a#VhRkR"Rh*CTDHDVZ0Q1q!q泉q ng4tS‡resmH7dl"Ň~wlHpWd6C"֦vlVv/+m0gSG_Pn0tDPFA)ql!9#R )(cR癞dui(pXDXX8C3fćUHaȋGj!w١:o䩡Ig`: ڠT"0d"36ZN {Vd'jTRvEV v?3avaa2P0A-8dIZ\ǤYPI,Z*y@)w~J&t-pD^CsQʧBOj՟4K׸V$J&~pɤ WaH4hAꦋC] 9u1ԥOդO6ڣjinQHU**SJ\gh=7')z"gU>sGEP>99!BD %$3l&|'4Fe(P)"6OEZA' 60$`5O@rʱ %. 'ʡr]*:&ᚢ7ʷ\7QC :s(SXjFcH|A %cȰ2BkCXSXkoR/)d7ȉ˲mz)+zI>9TiԒI]nB9L䘷F/Ϧ `&105kӒZ,ŷ2n*ƺ-lK7&+.o~!ydS % O>C$ƻ&FubEMvB-ʻzZqǕ+1"\;R lh(3*,psUަ:tZvUg@;W'bt֢&-r6o;1˫k,WQ'ps/ m w {.p*Ef<7.6x8-p04{E0,ve*E&{%FCB;h#qS%>//Ru$K< `'NUo0* 0+0ӥWZJWͥ,RWs`LHq (Wa"t1*t7+SP=1Awɮ(9{o()HQvђC b ܤɂAE-s `!'A+eY)7Ǽ;'ߢlB"nY-\j&˶+|nV-K>ԃIPṗ&~O3WJ΄YBpB+!tW'x !\jBeO$RdDQ$F=WzFD2CT6#r$`BgT%r_>5$A<'ʹGC994TKf$҈х1N B7ÇD-#m!LD>ǽ&zD>}fR6$G`5-T< IAt91#NĹMgŜ7Wf#)'kA3yͲ;8\1|461VI?p1c1-n\gtH&bI,lqTƳ8s6!2)--)i !iT"'#qM&0_iB~B:~JW'\+KP$$abCSiXa_-ʃrȁ"FuT~~.B#^"@ s) P3CcS`_xB EV05ρ3"LubAR;to RliQ7F%+``'r%q"`@'PެAD**fvxr`mr,,Eh{td *1~d\)0d26w0Z-T-*$lpGxz1ƌbojVHfqeR m`N$ZySr"y.dbP;tD 5υef\t$JQh*cw6boi$h } ?:XsldbhimپTQ-RU>A1aHaWT7CPXЛr(ă,7)o'S' 2'k `kHX( QA\ԭq({A Ɂf~ ]Ʒ8I;T* &[YN$@\Hb Yt<t"0 ]` 4C#551$<4 Bܰ4HѴA !(TtcHLi <\R!a|/3 "fp0F (S]QM}K5=( D;"+ 18PB "E7Rn ;X ;R: h*aSBALב#@M B8EuoJCGmD ~t Q Hg!Pdۦ/-88DLz{ܐ&!*n;ZOIa:-e1[Qp( |(,VkKa$*& ŋ` wG |A'c9BTX z P4 PK8\jRL>`p:O  ʈ7+P˸J=2'HJHH8$U̚!RTP;|D" Z3Y Y/t+Eѓ6e1ÓdK` iDrz](q@.!+j(Ũ1Ϟ}gݔ޷ NE)4ˇz|h⤩PJ] &ϛN/FŅB,{1A"\$\p)0tt3a-g>Ikt!1(@c;L.r 'Bܕ^:NpQ0\s 92WIDV8LJHHeq5%^!]j\6P]-eŀ0$w2RHdC(*\,iqz# % B=ſct*LEg 9`1J b LJfJ8qQ&)Ri*?ҝ**perDd=N% ޤFT'LV9C9aeHx3Vd m_e"*$FtA[j[qv2H1E*GHEH *s7tH "H`>Թ`ntQ)`9p14d` x$-FT'Huo DcK9hB@,w7 "fJ8n$d8AiRIc%$sPx KER" E%2C(iHQ;3d .3+B3ͿșDT! h3>z*C$et:15.i e>$r2^6:i8oOU>a{GA- HmEHU@ X'kN=Š>ScODb]tDJa!!EP%*Hů4ငXRbOCh$GL)M%jYSR*Y%tI\2Ii4cEdG )1 NvڥwS%sn(Lӕ[SN[ICW\t~/-FiR 8&,d̊F30yқ巈GSybWSHOn9z0 d/@5Pҍ*aXM)rR s5Ep.(Q˙KVmD7%h ,SẢKa0̒NZwG=&_aGěDAx>7B)ᝢz/HQ҅@TQHV hq!^'#>!x:`w`Ž:ȝJDyMeUuSq /&$ If:V @¬z~"tr*t@O<'?1(PUj9`M'Ȁ@`hPYFJGPf7Mف"CE`pF x8 Xm4 KDFf4CT@$DqҧA2:e>^SdO^H{`klZQ'> /?hB,5" ]PAh q,,QexqP+%LH;(ဥ&x\r6h9 av_>"EJA|W">+E#XVR.,)$XGZ`oҕXQB_eOhaMvx)!j S,m-B' lX`tN'#)T5N+"~"Sf BVY,c7TWi cY0^3c^hϚAT+ #Ȕ1ME)# 2 Q06u1'7aظ@モEy0lfdɊn.f<ȱ 5m4%9y漠N9;aL T:a$=9scdșڳ9hFP -ҪMNHcЮU Bŋg5,u7rȈ L֬ H,1oڴ İDrȱ5͛yCgؼS$&*DFboNpFN;e;=tp8FާtDHwں͡zX?=䇀h=ishg- EC;^:/j 0z1At D)" EB~׺`X^`,g wrWx*'@o#[N<,5w*tmh{y҉RZ$HrJ! 4E3AAHpayL`-la_tC5~:P4|(0 #0 BHg?1"؂ ~ 4vJ pn#:Q_VÙ:u36GH*H! M] ڄ[Bb`M TT|HRtDIR[0@l)BԐ'L25bAt7Kw`ԡ)Ќ k$&(}2gI=~jA$(}R yDJe 5V2,k9*L'J$XatƗ.e^11-CE\pwDsឥ9 CTÚČP$Mո O9ԧC!J@YwH8AhA"ݸSxEťuƀ@ǠNkKjnt*䢢T@Y(H0fL aXdB>FLg;J!=m@fw&@ \[$eAxHIpԄ!  qgJh`{X AƐ+B q QV'#["nF‡E OA9낁թjt;SƋzmB&?B-mmK೚fv d1.sx['CD5_JYpwUN *)-&Z z#ؤy Ä2q)Cmܐ"ANӁe1I2MvN6M;tQDU,Z?$k ]2ؾ1_O@eUg^DV+T6c0-lqB 10+cu@ hgA($)pBV,7mPMSMeb8BSl`G"/5ZSt{Q=Qq '=,q%s@8k1p7xS#vuMBkFB8A%?xW|"v\Zxxe"Xn9!.=.,{e.QPDfbq:R#[BVg_z3u-`]IPwRx?` "m@ huӎa'P'TǸ}jD~H# 3gl%P(J 召Jq[pup8O#Ő4QrxS}IbxM"f2oEqy>`gzX*\7l<|REv Xx eeDFNJi`(X&LE3);i$OԔ#-PLؚqV)~uפIwrA2#JBιydݤq()-q"$ZYLۉqbp`B1 1,eHbie<]Ipi}#[;9(1!!#4z6z8R/2 ;D`!d26:$ Dzj7Y:) 6yvХ5yvPT=቙ N!1iJ7Qя4b{P ^2xf0w"'rV$ojoA~X9!XF #5s& Pkqe yHlPV33:+( -sCiV#1 sVuu#6?szR!e9avgBr1jSb:1}.UC5Wp(XQ9J:cK@Z52a T#e2Mt1!))'fӲZit\-UԓD6klt('WjI?ҁ L bq ѵK{FqrsCkDuKmb5ptn=!m#͖ CV*T|%&$68*p 0%Q8fፉc^79 aԹ+:{:ƝBlKKs FCڣ&n@$HRlP@* /81ʡ#ae2Iov^}$r^>?Ģi灸 Tf!r&[T*Ȣ1/$QQ+l\+QK:;N+@A/%ܻK3^bAA\@@A˻~_1,YRZR[‰>\, G;) lDG;n<+ /HwL=d).˳B[EW˪S[@I %{9DzA"f0vr${r#\?˹_U}$ʓPJ8+0nR~wӂL$'ȀdF7I !B|nЧ9}'`'Y- ZP }9b*/uw{ĮL4ʨY J}rLjz5"Or$p'&(~;e|{%X"wB6;)Um_*Y,^լs<0n 勂|[]d2մ%Hw;u}תQCZRƜ@f?*П5hxtPܻs< و6E[PٲM`[blqih`ثO /&qdK+yĹ|RHRlQq$m"݂A!1ڟ]l: ñ:}]:g!wapQ-1!vyѨ$dP^/9&d!0s0x9B've Tw[N.NI^VP2phr*7d]r* -NH)oUPт!B1^L&[=E[]._n 8P=.㈳\'%*NuB$9Ud#xf9\쉒!,XZ|Nnч>"L߂*l[EԬL.K_c!oe!$}.vl$jKZt3Zl*锖r9pv+"p0+͚[*0;p*׎t."⮽ʮlQ&(J *y!!AeC]T4!63Z{bJb` -S! poUqJD;iL,N$b>/oU$b}ۃ%,&#5+w#Jlej,Tڣ+;:69L|=d7=<,=FV@2'Ky$#F?årz/ Zm_g/ep g'_C*g?d`t{/+)|A?՗JK(4go{3*DC;.+ A]__j= @l`w̸.97'93_cm!Xrpb^'OF!i. p Dj\dLIazB q2RIh1!L̀!ڣ, ?nE +NDP<+LcH5(_ 60%A] SEodiX<:k\_g6Qh >+lFG?1~_{JHI}a` `q$RRQQG 24&tU1Sd8TpH c@ث21uOa`,A{R+Qܲ740u1ueIlOq" rx zC,,8\ wβX FpRnvY{`!3l*C4?jQ*pGAC!P1ct6Ґ) "1q!H8MƚtZIɈH9B: %,8$qchAf)ae)H׆eݡhh0YP̃ “@K5Nw 㸗>n0xA>=Oͣ;58@aa QYR &uE2s|Ot$0 ؈, 7A(Oګ28KeKY&CE \0XLPъ4 tKRaӢ4@`@ 6B6x-",SAvL8s!v7N=OtĢJӜbUDž$(M':Ԡؒ5]:RlL `tϔAO R>1 %rξ *,B_{ID=.FɛhuҸAQ{/u$ڊw}9p+SܒҳuVXbr{/^D>YE"ג؆j54}|*vz5dOX̰&_JƘ ӭ]#k` kLLcR &AZa*`#gya+ntiW7SLC#ȘB9iK3K0 aKW$8 RȘԌȦ= 3zLѐ6f eH8FSYȉ!|j0@Ei:a!B:/dXV 30F`dXJ6c#Ƭ+81 \,ȇq.Y&CTM%b)N[[;}.xzq,Vy6Ak_wwe(7bJsuʇ#i*Qъ,y[^A9΢"uwwTSL GTu.[oiwrZw&ɹZ@e7HWtAbGa޵  0:r&1Ù YJO9E8|۽xxWާ~ La7֟6_x#% ܫ  cMk!$ZjATf m6Waf{Gpf;rL,Tp&;c2UsL(0CW4**@14EHcLA#TT7tkFJcltf juYQn P4{&a{˂1h27{V~T 8i W҈'ӗWX(ueII< 2;pж{$@f9rA8'pdCUմ|mdpzurHr[vr]%'xFX]@\S&Ixi4"֘]+h! `!x#⍺DpdvxVx9&~hg81{f8-A3"$v9}y!h!93peG&LgcmhvB)ep`hrA 'hx&n?YBY%y=()c0p'0o>&I9rn;pnP7#i Ј] B|~trFixA,6l 9z{zR1-QAM >]1+sr5ueDW PE h rSV)W'b[] iky!%"VU*P~45c3IEatLRVGbs2iE5KQIE ceOakmS1N0P  0ij(.foprE3'k$tpWxty[&fhOѤSYLSxlu}j:F` qh %_3BO0U 3x=?3cMzbƒ{>!]tnP)aq)&BebaSqQ\:=*&]:}yZg-b0k"KRuO:CCO@ElzIEg)[)sfWsol&~@Z$": P$TYbB}#,VrUfĉ(Lix]ܚ.o&ʥak'dx˂*1R ! H)fӝJSoQ.+xڛőӓ: QTbjefJƞVwB,?re33'GfeE [00ZFepbPQt0[VB@($"X*9ѲʄMk1[RhZkS\t`TFv06ax!h΢RTfkXHuSL,ʃxIVr:[#r0R&&%8;ܧ!qh:ȃ.8Fh 2R<1xyv<#,:hzR-:`6B"Azh۰bC[~cwx2"K;=sk~&AcD:cȃya ׻1xDoa,bDY!azyQ-(晠yr`9&T)U?d`K҈a1n#hyaȂ'UT>Z 7z4ē񯰦ʗL%vohk B'qòahyq8dkdkh¥%WiTSyf0F)K_:d1`+4LVl`cRCƬeXxll%OIk3[[/a8ѳPS;RxB̵~浊(1&yޫeU̶7!+du~aLħ5" @,);Qscʻ-p JhÆo>fbŃQJ-I1GCFLAGS=-F -T. l=/lib shobj = sh1.s sh2.s sh3.s sh4.s sh5.s sh6.s sh: $(shobj) sh.h @cc -i -o sh -T. $(shobj) @chmem =13000 sh /* -------- sh.h -------- */ /* * shell */ #define NULL 0 #define LINELIM 1000 #define NPUSH 8 /* limit to input nesting */ #define NOFILE 20 /* Number of open files */ #define NUFILE 10 /* Number of user-accessible files */ #define FDBASE 10 /* First file usable by Shell */ /* * values returned by wait */ #define WAITSIG(s) ((s)&0177) #define WAITVAL(s) (((s)>>8)&0377) #define WAITCORE(s) (((s)&0200)!=0) /* * library and system defintions */ typedef int xint; /* base type of jmp_buf, for broken compilers */ /* * shell components */ /* #include "area.h" */ /* #include "word.h" */ /* #include "io.h" */ /* #include "var.h" */ #define QUOTE 0200 #define NOBLOCK ((struct op *)NULL) #define NOWORD ((char *)NULL) #define NOWORDS ((char **)NULL) #define NOPIPE ((int *)NULL) /* * Description of a command or an operation on commands. * Might eventually use a union. */ struct op { int type; /* operation type, see below */ char **words; /* arguments to a command */ struct ioword **ioact; /* IO actions (eg, < > >>) */ struct op *left; struct op *right; char *str; /* identifier for case and for */ }; #define TCOM 1 /* command */ #define TPAREN 2 /* (c-list) */ #define TPIPE 3 /* a | b */ #define TLIST 4 /* a [&;] b */ #define TOR 5 /* || */ #define TAND 6 /* && */ #define TFOR 7 #define TDO 8 #define TCASE 9 #define TIF 10 #define TWHILE 11 #define TUNTIL 12 #define TELIF 13 #define TPAT 14 /* pattern in case */ #define TBRACE 15 /* {c-list} */ #define TASYNC 16 /* c & */ /* * actions determining the environment of a process */ #define BIT(i) (1<<(i)) #define FEXEC BIT(0) /* execute without forking */ /* * flags to control evaluation of words */ #define DOSUB 1 /* interpret $, `, and quotes */ #define DOBLANK 2 /* perform blank interpretation */ #define DOGLOB 4 /* interpret [?* */ #define DOKEY 8 /* move words with `=' to 2nd arg. list */ #define DOTRIM 16 /* trim resulting string */ #define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) Extern char **dolv; Extern int dolc; Extern int exstat; Extern char gflg; Extern int talking; /* interactive (talking-type wireless) */ Extern int execflg; Extern int multiline; /* \n changed to ; */ Extern struct op *outtree; /* result from parser */ Extern xint *failpt; Extern xint *errpt; struct brkcon { jmp_buf brkpt; struct brkcon *nextlev; } ; Extern struct brkcon *brklist; Extern int isbreak; /* * redirection */ struct ioword { short io_unit; /* unit affected */ short io_flag; /* action (below) */ char *io_name; /* file name */ }; #define IOREAD 1 /* < */ #define IOHERE 2 /* << (here file) */ #define IOWRITE 4 /* > */ #define IOCAT 8 /* >> */ #define IOXHERE 16 /* ${}, ` in << */ #define IODUP 32 /* >&digit */ #define IOCLOSE 64 /* >&- */ #define IODEFAULT (-1) /* token for default IO unit */ Extern struct wdblock *wdlist; Extern struct wdblock *iolist; /* * parsing & execution environment */ extern struct env { char *linep; struct io *iobase; struct io *iop; xint *errpt; int iofd; struct env *oenv; } e; /* * flags: * -e: quit on error * -k: look for name=value everywhere on command line * -n: no execution * -t: exit after reading and executing one command * -v: echo as read * -x: trace * -u: unset variables net diagnostic */ extern char *flag; extern char *null; /* null value for variable */ extern int intr; /* interrupt pending */ Extern char *trap[NSIG]; Extern char ourtrap[NSIG]; Extern int trapset; /* trap pending */ extern int inword; /* defer traps and interrupts */ Extern int yynerrs; /* yacc */ Extern char line[LINELIM]; extern char *elinep; /* * other functions */ int (*inbuilt())(); /* find builtin command */ char *rexecve(); char *space(); char *getwd(); char *strsave(); char *evalstr(); char *putn(); char *itoa(); char *unquote(); struct var *lookup(); struct wdblock *add2args(); struct wdblock *glob(); char **makenv(); struct ioword *addio(); char **eval(); int setstatus(); int waitfor(); int onintr(); /* SIGINT handler */ /* * error handling */ void leave(); /* abort shell (or fail in subshell) */ void fail(); /* fail but return to process next command */ int sig(); /* default signal handler */ /* * library functions and system calls */ long lseek(); char *strncpy(); int strlen(); extern int errno; /* -------- var.h -------- */ struct var { char *value; char *name; struct var *next; char status; }; #define COPYV 1 /* flag to setval, suggesting copy */ #define RONLY 01 /* variable is read-only */ #define EXPORT 02 /* variable is to be exported */ #define GETCELL 04 /* name & value space was got with getcell */ Extern struct var *vlist; /* dictionary */ Extern struct var *homedir; /* home directory */ Extern struct var *prompt; /* main prompt */ Extern struct var *cprompt; /* continuation prompt */ Extern struct var *path; /* search path for commands */ Extern struct var *shell; /* shell to interpret command files */ Extern struct var *ifs; /* field separators */ struct var *lookup(/* char *s */); void setval(/* struct var *, char * */); void nameval(/* struct var *, char *val, *name */); void export(/* struct var * */); void ronly(/* struct var * */); int isassign(/* char *s */); int checkname(/* char *name */); int assign(/* char *s, int copyflag */); void putvlist(/* int key, int fd */); int eqname(/* char *n1, char *n2 */); /* -------- io.h -------- */ /* possible arguments to an IO function */ struct ioarg { char *aword; char **awordlist; int afile; /* file descriptor */ }; /* an input generator's state */ struct io { int (*iofn)(); struct ioarg arg; int peekc; char nlcount; /* for `'s */ char xchar; /* for `'s */ char task; /* reason for pushed IO */ }; Extern struct io iostack[NPUSH]; #define XOTHER 0 /* none of the below */ #define XDOLL 1 /* expanding ${} */ #define XGRAVE 2 /* expanding `'s */ #define XIO 3 /* file IO */ /* in substitution */ #define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) /* * input generators for IO structure */ int nlchar(); int strchar(); int filechar(); int herechar(); int linechar(); int nextchar(); int gravechar(); int qgravechar(); int dolchar(); int wdchar(); /* * IO functions */ int getc(); int readc(); void unget(); void ioecho(); void prs(); void putc(); void prn(); void closef(); void closeall(); /* * IO control */ void pushio(/* struct ioarg arg, int (*gen)() */); int remap(); int openpipe(); void closepipe(); struct io *setbase(/* struct io * */); Extern struct ioarg temparg; /* temporary for PUSHIO */ #define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(temparg,(gen))) #define RUN(what,arg,gen) ((temparg.what = (arg)), run(temparg,(gen))) /* -------- word.h -------- */ #ifndef WORD_H #define WORD_H 1 struct wdblock { short w_bsize; short w_nword; /* bounds are arbitrary */ char *w_words[1]; }; struct wdblock *addword(); struct wdblock *newword(); char **getwords(); #endif /* -------- area.h -------- */ /* * storage allocation */ char *getcell(/* unsigned size */); void garbage(); void setarea(/* char *obj, int to */); int getarea(/* char *obj */); void freearea(/* int area */); void freecell(/* char *obj */); Extern int areanum; /* current allocation area */ #define NEW(type) (type *)getcell(sizeof(type)) #define DELETE(obj) freecell((char *)obj) <...=User_guide>dis88.man?elle.man@man_pagesThis file contains important information not present in the book or elsewhere. Please read it VERY carefully. 1. GENERAL There were a number of changes made to the code after the book was printed. As a result, line X of file Y in the book may actually appear at X+3, or X-5, etc. on the disk version. New features have also been added in various places. 2. PC-AT The distribution for the PC-AT differs from that for the PC in minor ways. For example, there is no /user diskette. Most the files that would normally be on /user fit on /usr. Furthermore, the number and organization of the source diskettes is different, but the same programs are available. Two additional special files are present in /dev: /dev/at0 and /dev/at1. These should be used to access 1.2M diskettes. To access 360K diskettes on the PC-AT, use /dev/fd0 and /dev/fd1. Special files are used by commands such as mount, mkfs, and df, among others. For example, to copy part of a 1.2M diskette, type dd if=/dev/at0 of=file count=100. The difference between /dev/at0 and /dev/fd0 is that in MINIX, special files have sizes to prevent access beyond the end. For /dev/fd0 the size is 360K. For /dev/at0 it is 1.2M. Finally, the executable binary for the PC-AT contains at_wini.c instead of xt_wini.c (see below). 3. HARD DISK DRIVERS MINIX supports the use of the standard IBM hard disks. Unfortunately, IBM chose to use different (and incompatible) disks and controllers on the XT and AT. To find out if MINIX works with your disk, give the command: dd if=/dev/hd0 of=/dev/null count=1000 If this runs to the end without errors, the driver embedded in your MINIX binary is appropriate for your controller and drive. If it gives errors, do a sync, turn the computer off and reboot MINIX. This time run a hard disk check from the initial menu. Start MINIX (even if this check gives errors). Run dd again. If it still fails, try the following. Copy kernel/xt_wini.c to wini.c and recompile the operating system. If this fails, then try kernel/at_wini.c and recompile it once more. Usually, one of these will work. If neither works, your disk is not compatible with either the XT or AT. You will have to modify the driver. For PS/2 Model 30 users, a driver ps_wini.c has been provided for use. You MUST have a kernel/wini.c to recompile the system, even if you do not have a hard disk (in which case, any one will do). 4. INSTALLING MINIX ON A HARD DISK After you have made sure that you have a working hard disk driver, as described above, proceed as follows. To use MINIX on a hard disk, you need a MINIX partition. You may also have MS-DOS, PC-IX, OS/2, XENIX, or other partitions as well if you like. If you understand about making partitions, make one any way you are used to. Otherwise use the MINIX fdisk program. All partitions on the disk must be an even number of sectors even DOS ones. Be warned that the MINIX, MS-DOS, PC-IX, and XENIX parition numbering schemes all differ. Be very careful here, lest you overwrite useful data. It is suggested that you use the program diskcheck to inspect the MINIX partition for bad blocks. The program badblocks will help deal with them. The file man_pages in this directory discusses their use. Once you have a partition available for MINIX (the type does not matter as MINIX does not check), make a file system by booting MINIX from floppy the usual way and run mkfs. If, for example, you have chosen partition 2, which has, say, 40 cylinders (i.e., 40 x 68 = 2720 sectors or 1360 1K blocks), type: mkfs /dev/hd2 1360 to make an empty file system. However, for partition 1 use 1 block less because block 0 is not available (it contains the MS-DOS partition table). In other words, a 40 cylinder partition 1 has 1359 blocks but a 40 cylinder partition 2 or higher has 1360 blocks. Then mount the file system by typing /etc/mount /dev/hd2 /user Next, make whatever directories you like, typically bin, lib, and others, and copy files to the hard disk. With the /usr floppy in drive 0, the command cp /usr/bin/* /user/bin will copy all the binaries from /usr/bin to the hard disk, for example. Alternatively, the cpdir program can be used to copy entire trees, e.g. cpdir /usr/bin /user/bin will create a new directory /user/bin, and put /usr/bin with all its files and subdirectories in it. A few of the files in /usr/bin must be owned by the root (instead of bin) and have mode 4755. Check to make sure. These files are: badblocks chgrp df fsck mkdir mv passwd readall rmdir su Finally, edit /etc/rc to have the hard disk mounted when the system is booted. A line such as /etc/mount /dev/hd2 /usr can be used as a replacement for the mount command initially in /etc/rc. After editing /etc/rc, mount the root file system diskette and copy it to the diskette; otherwise the changes will be lost when the system is rebooted. (There is nothing special about the root file system except its size; it can be mounted and written on like any other file system.) After these steps have been taken, the system can be booted from floppy in the usual way, and the root file system also read in from floppy. The hard disk will automatically be mounted by the /etc/rc. The root device remains on the RAM disk, and the boot process still goes via floppy (for compatibility and to prevent disaster in the event that something goes wrong with the hard disk file system). Hard disk file systems can be checked using fsck, the same as floppies. However, fsck assumes you have 4 heads and 17 sectors/track. If this is not so, change the code accordingly or fsck will give spurious errors. The special file /dev/hd0 refers to the whole disk, without regard to partitions, whereas /dev/hd1 ... /dev/hd4 refer to partitions 1 to 4. If you have a second hard disk, you can make /dev/hd5 ... /dev/hd9 with mknod (major device 3, minor device 5 ... 9) for the second drive, with hd5 for the whole drive, hd6 for partition 1, etc. Fsck also uses this convention. 5. CONFIGURING MINIX ON A HARD DISK When setting up MINIX on a hard disk, the following set of directories is recommended, although the MINIX source tree can go elsewhere if desired. Be sure to edit the cc.c program to make sure it knows where to find the various compiler passes and libraries, which may be in /bin, lib, /usr/bin, or /usr/bin. When a large RAM disk is available, put /bin and /lib on the RAM disk, and include the compiler parts in them. When extracting files from the distribution, note carefully that there is a lib directory on the /usr diskette (for /lib and /usr/lib) and another one among the sources (for /usr/src/minix/lib). Many of the directories listed below have sub- directories. /bin - most common binaries /dev - special files /etc - system administration /lib - most important libraries /tmp - scratch files go here /usr - mount usr file system here /usr/bin - rest of the binaries /usr/include - system include files /usr/lib - rest of the libraries /usr/src - sources go here /usr/src/minix - minix sources go here /usr/src/minix/amoeba - all networking code is here /usr/src/minix/commands - utility program sources /usr/src/minix/fs - file system sources /usr/src/minix/h - operating system header files /usr/src/minix/kernel - kernel and device driver sources /usr/src/minix/lib - libc.a sources /usr/src/minix/mm - memory manager sources /usr/src/minix/test - test programs /usr/src/minix/tools - tools for building new operating systems /usr/tmp - (optional) alternative place for temporaries 6. PUTTING THE ROOT FILE SYSTEM ON A HARD DISK To speed up the boot procedure, you may copy the root file system to /dev/hd3 with the commands cp /dev/fd0 /dev/hd3 or  cp /dev/at0 /dev/hd3 The former is for the PC, the latter is for the AT. /dev/hd3 must not be mounted. When booting, leave the boot diskette in the drive when typing the = sign. MINIX will see that the diskette is not a valid file system, and take the root file system from the default device, /dev/hd3. You can change the choice of default by modifying RAM_IMAGE in fs/main.c 7. USING MS-DOS AS A DEVELOPMENT SYSTEM MINIX is now completely self supporting, so the C86 and PC-IX directories have been deleted. The only time you might need MS-DOS is for formatting blank diskettes. MINIX does not have a format program. 8. EDITING LARGE PROGRAMS WITH MINED Mined has a limit on the size of programs it can edit. To edit larger ones, they must be broken up with split, edited separately and recombined later. Better yet, use elle, which is a much better editor, is emacs compatible, and can handle files as large as the disk. 9. MKNOD MINIX differs from UNIX in that block special files (and even some character special files, such as /dev/kmem) can have sizes. A 360K floppy disk special file, such as /dev/fd0 can have size 360K. Unfortunately, the mknod system call (and mknod program) have no way to express the size, so it uses size 0, which is equal to infinity. When you read past the end of a block special file WITH a size, the file system returns zero bytes. When you go off the end of a device WITHOUT a size, some drivers return end-of-file (e.g., hard disk, RAM disk), but others (e.g., floppy disk) return an I/O error code. Thus if you make a new block special file for 2/0 and 2/1 (floppy disk) with mknod (i.e., no size) the command cp /dev/fd0 /dev/fd1 will terminate with an error on block 360 (but it will copy the disk perfectly). The only way to make a special file with a size is by making a file system with mkfs. 10. NONEXISTENT DEVICES If you try to open /dev/fd1 on a system with only one floppy disk drive, the system may hang. To avoid this problem, the first time you log in, go to the /dev directory, and rename special files that you do not have to something unusual. For example, if you do not have a hard disk, rename hd0 to HARD_DISK_0, hd1 to HARD_DISK_1, etc. Similarly with one one floppy disk, rename fd1 to FLOPPY_DISK_1 to prevent it being typed by accident. You can also remove them, but due to the mknod problem described above, you can not get them back easily, so it is best just to get them out of the way in case you ever need them again later. 11. PRINTER In order to accommodate buffered and unbuffered printers, the printer driver uses a combination of delay loops and interrupts. The net result is that the driver consumes a fair number of CPU cyles when running. If you expect to do a lot of printing, you might want to consider rewriting the printer interrupt handler, pr_char, in assembly code. Note that some printers that are not IBM compatible give spurious out-of-paper messages. 12. DISK SPACE The /usr disk as distributed is nearly full. If you have two floppy disk drives, be sure to mount /user on drive 1 and move your working directory there. If you have only 1 floppy disk drive, remove some files from /usr/bin to make more space. If you have a hard disk, there is no problem. 13. RUNNING /USER TESTS ON A FLOPPY Before running the tests in /user/test, remove the files in /user/commands to create some free space on the disk. Run the tests as superuser. 14. COMMAND LINE LENGTH The maximum initial stack size is 2K. Calls to EXEC which require a larger stack will fail. Thus if you do ls -l * in a large directory, the shell may expand the * so that the command line exceeds 2K and the EXEC will fail, resulting in a message such as "Cannot execute ls". 15. ARCHIVES ON THE DISTRIBUTION DISKETTES To save space on the distribution diskettes, some of the sources have been archived and compressed. Files ending with .Z are compressed files, and can be decompressed by typing: compress -d file.Z In some cases, the resulting file is an archive, ending with the .a suffix. Remove the files with: ar xv file.a Thus a file like fs.a.Z must first be uncompressed to get fs.a and then dearchived. 16. RECOMPILING FSCK AND OTHER LARGE PROGRAMS If for some reason you don't like the tools/fsck binary and want to recompile it, make sure you have plenty of free space for the compiler's temporary files. On a floppy disk system, this may mean putting fsck on an almost empty diskette before compiling it. When the disk is full, the quality of the compiler's error messages deteriorates rapidly. If you are compiling fsck and getting strange results, check for disk space. Normally /tmp is used for temporaries, but the -T flag can override that. 17. NEWS GROUP If you have access to USENET, you may be interested in knowing that there is a news group, comp.os.minix devoted to discussions of MINIX. This is one of the largest news groups, with over 10,000 readers. If you have access to the Arpanet, Bitnet, or EARN, the news group is gatewayed there. Contact info-minix-request@udel.edu to join or send email to ast@cs.vu.nl requesting the MINIX information sheet. 18. SYSTEM PROBLEMS The IBM PC does not have any hardware for checking for stack overflow. The user must allocate the amount of stack for each program with chmem or use the compiler default (64K - program - data size). Some programs in the distribution have been set to a smaller value, and may, in rare instances with certain arguments, hang. If the system ever gets into a situation where it echoes keystrokes, but ignores DEL and CTRL-\ and appears otherwise to be hung up, hit F1 to see what is going on. If some process is running and there is no way to interrupt it, hit CTRL-F9. This key is equivalent to the super-user typing: kill -1 9. The result of CTRL-F9 is that every process in the system is killed, including update and all the shells. Although drastic, CTRL-F9 will dehang the system instantly. Log in again and then type /etc/update & to restart update. The reason for requiring CTRL to be held down while hitting F9 is to prevent F9 from being hit by accident. 19. USE OF EXTENDED MEMORY ON ATs If the size of the root file system (either taken from floppy or from /dev/hd3, as described above), is 256K or more, MINIX puts the root device in extended memory, above 1M, leaving the entire 512K or 640K free for MINIX and user programs. To get full advantage of the extended memory, the size of the root file system should be the same as the amount of extended memory present. If the root file system is < 256K, MINIX assumes that there is no extended memory, and puts the root file system in "low" core (below 640K). This feature only works on ATs, so PCs must never have root file systems >= 256K. If you have a large extended memory, you may want to put the root file system on hard disk, as described above, so the extended memory can be loaded from hard disk quickly at boot time. 20. SOFTWARE SCROLLING FOR EGA CARDS MINIX works with monochrome cards, CGA cards, and IBM compatible EGA cards. However, it does not work with some nonstandard EGA cards. With some cards, the screen will go blank every 25 lines. MINIX can be made to work with these EGA cards by hitting the F3 key to use software scrolling. This is slower than hardware scrolling, so only use it if you have to. You can toggle between the two modes by hitting F3 repeatedly. If you want soft scrolling to be the default, recompile kernel/tty.c with the variable softscroll initialized to 1, and make a new kernel. 21. NEW FLAGS AND FEATURES Various programs have acquired new flags and features and new programs have been included. Please read all the files in this directory carefully. 22. ANSI ESCAPE SEQUENCES The escape sequences used by the tty driver for both input and output have been changed to the ANSI standard ones. To manipulate the cursor etc., print the following (among others): ESC M: scroll a line backwards (cursor must be on line 1) ESC [ y ; x H move to column x, row y; (1,1) is upper right corner ESC [0J clear from cursor to end of screen ESC [7m go to reverse video ESC [0m go to normal video The 9 numeric pad keys, as well as numeric + and - now generate ESC [ x for some x. Just type them to see which x goes with each key. There is an /etc/termcap file for MINIX that uses the allowed sequences. 23. _CLEANUP NO LONGER NEEDED The exit routine has been changed to call _cleanup automatically. As a result, programs using stdio no longer have to call it explicitly. All calls to _cleanup have been removed from the standard distribution. 24. DISTRIBUTION CHANGES The subdirectories PC-IX and C86 have been deleted, as mentioned above. In a few cases, a subdirectory IBM_PC is present for files specific to the IBM PC/XT/AT/386 version of MINIX (as opposed to the Atari ST). These files should be moved up one directory level. In some cases, two makefiles are provided, called pc_makefile and at_makefile. Copy the appropriate one to makefile, depending on whether you have (1) a PC or XT or (2) an AT. Study them both and delete the inappropriate one. The differences are usually related to the assumed size of the RAM disk, rather than any differences between the two processors. 25. LINKS The directory /usr/include now contains several subdirectories and also linked files. If you copy this directory to hard disk, link the following files, if possible. /usr/include/sgtty.h to minix/h/sgtty.h /usr/include/signal.h to minix/h/signal.h /usr/include/minix/callnr.h to minix/h/callnr.h /usr/include/minix/com.h to minix/h/com.h /usr/include/minix/const.h to minix/h/const.h /usr/include/minix/type.h to minix/h/type.h /usr/include/sys/stat.h to minix/h/stat.h /usr/include/fs/buf.h to minix/fs/buf.h /usr/include/fs/const.h to minix/fs/const.h /usr/include/fs/super.h to minix/fs/super.h /usr/include/fs/type.h to minix/fs/type.h In addition, the files dosread, dosdir, and doswrite in /usr/bin should all be links to the same file. It determines which it is by looking at argv[0]. 26. LACK OF SPACE If you are running on a system with limited memory, either 512K RAM or no hard disk, you may encounter difficulties trying to recompile the system. However, there are steps you can take to improve the situation. First, various passes of the compiler are configured with ample stack space. Using chmem you can reduce this stack space to reduce the program's memory requirements. Be careful about not reducing it too much, or strange things will happen. Second, the compiler flag -T can be used to place temporary files in a place other than /tmp. This flag may be useful if /tmp is on the RAM disk, which is too small. Third, the compiler flag -F can be used to run cpp and cem sequentially instead of in parallel. This approach is slower but uses less memory. Fourth, the library, libc.a contains several large routines that are rarely used. By removing these, you can reduce the amount of space the library requires. Fifth, if you are able to compile but not link, after having created all the *.s files, you can remove some of the larger *.c files, replacing them with null files to keep make happy, and then link. Sixth, the size of the RAM disk is determined by the size of the root file system. If the default size is not suitable for your configuration, you can make a new root file system with mkfs. In particular, on an XT, you may wish to move cpp and cem from /lib (RAM disk) to /usr/lib (hard disk), thus making it possible to build a new and smaller RAM disk to free up more "core." If you do this, be sure to modify cc.c, since it has to know where to find cpp and cem. 27. MULTIPLE BIN DIRECTORIES IN THE DISTRIBUTION Since the distribution disks are nearly full, a few of the programs that logically ought to be in the /usr/bin directory have been put on one of the other distribution diskettes in a separate bin directory. On a hard disk system, these programs should be put in /usr/bin. 28. LIBRARY Not all the sources in minix/lib have been included in libc.a (to save space). If you have a hard disk and enough space, compare the sources and binaries and add the missing files. Remember to compile all library routines with cc -c -LIB file.c. The -LIB flag is essential for libraries. The library sources are contained in the lib/libsrc.a archive. 29. RS232 LINES MINIX supports RS232 lines to terminals and modems. Baudrate, parity, and bits/character are user settable. The special files /dev/tty[12] are used to access the RS232 lines. They can be opened for reading and writing. As shipped, the system is configured for only one line, /dev/tty1. To enable the second one, change NR_RS_LINES in tty.c to 2. Doing so will increase kernel size by 1K, due to the extra table and buffer space needed. The file /etc/ttys can be configured to have a shell be started for either line, thus making MINIX a multi-terminal system. The second char of the three-character /etc/ttys entry gives the line parameters. See the comment at the start of tools/init.c for details. The program stty can be used to set baud rates, bits/character and parity for its standard input, e.g. stty 9600 8 -even -odd End of whole buffer. DELETING CTRL-D Deletes forward one character (the one the cursor is under). DELETE Deletes backward one character (the one to left of cursor). ESC D Kills forward one word. ESC DEL Kills backward one word. CTRL-K Kills the rest of the line (to the right of the cursor). ESC \ Deletes spaces around the cursor. CTRL-X CTRL-O Deletes blank lines around the cursor. CASE CHANGE ESC C Capitalizes word : first letter becomes uppercase; rest lower ESC L Makes the whole next word lowercase. ESC U Makes the whole next word uppercase. CTRL-X CTRL-L Makes whole region lowercase. CTRL-X CTRL-U Makes whole region uppercase. SEARCHING (If no string is given, previous string is used) CTRL-S Incremental Search forward; prompts "I-search:" CTRL-R Reverse Incremental Search; prompts "R-search:" During an incremental search, the following characters have special effects: "normal" chars - Begin searching immediately. ^G - Cancel I-search, return to start. DEL - Erase last char, return to last match. ^S, ^R - Repeat search (or change direction). ESC or CR - Exit I-search at current point. ESC % Query Replace. Asks for a search string, then for the replacement string, and begins searching. Stops at each match and waits for a command. Type "?" to see your options. CTRL-X % Replace String. Like Query Replace, but simply replaces all matches, without stopping to ask. MARKING AREAS CTRL-^ Set mark CTRL-X CTRL-X Exchange cursor and mark. ESC H Mark Paragraph. Sets mark and cursor to surround a para. CTRL-W Wipe-out -- kills a "region": ESC W Copy region. Like CTRL-W then CTRL-Y but does modify buffer CTRL-Y Yanks-back (un-kills) whatever you have most recently killed. ESC Y Yanks-back (un-kills) the next most recently killed text. ESC CTRL-W Append Next Kill. Accumulates stuff from several kills FILLING TEXT ESC Q Fill the paragraph to the size of the Fill Column. ESC G Fill the region. CTRL-X F Set Fill Column. ESC Q will use this line size. CTRL-X . Set Fill Prefix. Asks for prefix string CTRL-X T Toggles Auto Fill Mode. WINDOWS CTRL-X 2 Make two windows (split screen). CTRL-X 1 Make one window (delete window) (make one screen). CTRL-X O Go to Other window. CTRL-X ^ Grow window: makes current window bigger. BUFFERS CTRL-X CTRL-F Find a file and make a buffer for it. CTRL-X B Select Buffer: goes to specified buffer or makes new one CTRL-X CTRL-B Show the names of the buffers used in this editing session. CTRL-X K Kill Buffer. ESC ~ Say buffer is not modified. CTRL-X CTRL-M Toggle EOL mode (per-buffer flag). KEYBOARD MACRO CTRL-X ( Start collecting a keyboard macro. CTRL-X ) Stop collecting. CTRL-X E Execute the collected macro. CTRL-X * Display the collected macro. FILES CTRL-X CTRL-I Insert a file where cursor is. CTRL-X CTRL-R Read a new file into current buffer. CTRL-X CTRL-V Same as ^X ^R above (reads a file). CTRL-X CTRL-W Write buffer out to new file name. CTRL-X CTRL-S Save file: write out buffer to its file name. CTRL-X CTRL-E Write region out to new file name. MISCELLANEOUS CTRL-X CTRL-Z Exit from ELLE. CTRL-X ! Escape to shell (CTRL-D to return) CTRL-O Open up line LINEFEED Same as typing RETURN and TAB. CTRL-T Transposes characters. ESC T Transposes words. CTRL-U Makes the next command happen four times. CTRL-U number Makes the next command happen "number" times. ESC number Same as CTRL-U number. CTRL-L Refreshes screen. CTRL-U CTRL-L Refresh only the line cursor is on. CTRL-U n CTRL-L Change window so the cursor is on line n CTRL-Q Quote: insert the next character no matter what it is. CTRL-G Quit: use to avoid answering a question. ESC ; Inserts comment (for writing C programs). ESC I Inserts indentation equal to previous line. ESC M Move to end of this line's indentation. CTRL-_ Describes a command is command database is online UNUSED CONTROLS CTRL-\ Special debugging command. Not for normal users! CTRL-^ Special debugging command. Not for normal users! CTRL-C Not used. CTRL-Z Not used. CTRL-] Not used. 4. INSTALLING ELLE ON MINIX Files: elle (executable binary of the editor) ellec (executable binary of the profile compiler) .ellepro.e (mined profile in source form) .ellepro.b1 (mined profile in binary form) help.dat (help file) HOW TO INSTALL ELLE Step 1: Check to see if /etc/termcap is present and has an entry for 'minix'. Step 2: Set the environment properly by typing: TERM=minix. You can also put it in the appropriate .profile, but be sure to include a line: export TERM. You can check the current environment with: printenv. If the entry TERM=minix does not appear, ELLE will not work. Step 3: Install 'elle' and 'ellec' in your /bin or /usr/bin directory. Step 4: Install help.dat in /usr/src/elle/help.dat Step 5: If you want to use the mined-like commands, install .ellepro.b1 in $HOME Step 6: Type 'elle filename' and you are up and running. HOW TO CREATE YOUR OWN USER PROFILE Step 1: Modify .ellepro.e to suit your taste Step 2: Install .ellepro.e in $HOME Step 3: Type: ellec -Profile Step 4: Check to see if $HOME/.ellepro.b1 was created This file contains the man pages for those programs not listed in the book or which have been significantly modified since the first release. It should be installed as /usr/lib/helpfile. --------------------------------------------------------------------------- # animals Command: animals - twenty questions type guessing game about animals Syntax: animals [database] Flags: (none) Example: animals Animals is a guessing game. The user picks an animal and the computer tries to guess it by posing questions that should be answered by typing "y" for yes and "n" for no. Whenever the computer loses, it asks some questions that allow it to improve its data base, so as time goes on, it learns. The default data base should be in /usr/lib/animals. # ar Command: ar - archiver Syntax: ar [qrxdpmt][abivulc] [posname] archive file ... Flags: (none) Examples: ar r libc.a sort.s # replace sort.s in libc.a ar rb a.s libc.a b.s # insert b.s before a.s in libc.a Ar allows groups of files to be put together into a single archive. It is normally used for libraries of compiled procedures. The following keys are allowed: q: quickly append to the end of the archive file. m: move named files. Ar expects 'a', 'b', or 'i' to be specified. r: replace (append when not in archive). d: delete. Ar will delete the name members. t: print the archive's table of contents. p: print the named files (list them on standard output) x: extract The keys may optionally concatencated with one or more of the following: l: local temporary file for work instead of /tmp/ar.$$$$$ v: verbose a: after 'posname' b: before 'posname' i: before 'posname' c: create (suppresses creation message) u: replace only if dated later than member in archive # ascii Command: ascii - strip all the pure ASCII lines from a file Syntax: ascii [-n] [file] Flags: -n Extract the lines containing nonASCII characters Examples: ascii file >outf # put all the ASCII lines on outf ascii -n outf # write nonASCII lines to outf Sometimes a file contains some nonASCII characters that are in the way. This program allows the lines containing only ASCII characters to be grepped from the file. With the -n flag, the nonASCII lines are grepped. No matter whether the flag is used or not, the program returns an exit status of true if the file is pure ASCII, and false otherwise. # ast Command: ast - add symbol table to executable file Syntax: ast -xX [file] [symbol_file] Flags: -x do not preserve local symbols -X preserve local symbols (except compiler generated ones) Example: ast -X a.out # add symbols from symbol.out to a.out Ast adds the symbol table produced by the -s option of asld to the executable file. If no symbol table file is listed, the default name 'symbol.out' is used. The symbol table can be generated by the command cc -s file.c >symbol.out. # at Command: at - execute commands at a later time Syntax: at time [month day] [file] Flags: (none) Examples: at 2315 Jan 31 myfile # myfile executed Jan 31 at 11:15 pm at 0900 # job input read from stdin at 0711 4 29 # read from stdin, exec on April 29 At prepares a file to be executed later at the specified time by creating a special entry in /usr/spool/at. The program atrun should be started periodically, for example, every minute by cron. Atrun checks to see if any files in /usr/spool/at should now be run, and if so, it runs them and then puts them in /usr/spool/at/past. The name of the file created in /usr/spool/at by at is YY.DDD.HHMM.UU (where YY, DDD, HH, and MM give the time to execute and UU is a unique number). Note that when the command runs, it will not be able to use standard input or standard output unless specifically redirected. In the first example above, it might be necessary to put >/dev/tty0 on some lines in the shell script myfile. The same holds for the commands typed directly to at. # badblocks Command: badblocks - put a list of bad blocks in a file Syntax: badblocks block_special Flags: (none) Example: badblocks /dev/fd1 If a device develops bad sectors, it is important to not have them allocated to important files. This program makes it possible to collect up to 7 bad blocks into a file, so they will not be allocated for a "real" file. When the program starts up, it asks for a list of bad blocks. Then it creates a file whose name is of the form .Bad_xxxxx, where xxxxx is a pid. # banner Command: banner - print a banner Syntax: banner arg ... Flags: (none) Example: banner happy birthday # print a banner saying happy birthday Banner prints its arguments on standard output using a matrix of 6 x 6 pixels per character. The @ sign is used for the pixels. # cal Command: cal - print a calendar Syntax: cal [month] year Flags: (none) Example: cal 3 1987 # print March 1987 Cal prints a calendar for a month or year. The year can be between 1 and 9999. Note that the year 87 is not a synonym for 1987, but is itself a valid year about 19 centuries ago. The calendar produced is the one used by England and her colonies. Try Sept. 1752, Feb 1900, and Feb 2000. If you don't understand what is going on, look up "Calendar, Gregorian" in a good encyclopedia. # cdiff Command: cdiff - context diff Syntax: cdiff [-c] old new Flags: -cN how much context to provide Example: cdiff old new >f # write context diff on f Cdiff produces a context diff by first running 'diff' and then adding context. Some update programs, like patch, can use context diffs to update files, even in the presence of other, independent changes. #chmod Command: chmod - change access mode for files Syntax: chmod octal-number files chmod [augo][+-=][rwxst] files Flags: (none) Examples: chmod 755 file # Owner: rwx Group: r-x Others: r-x chmod +x file1 file2 # Make file1 and file2 executable chmod a-w file # Make file read only chmod u+s file # Turn on SETUID for file chmod g=u # group perms set to same as user perms. The given mode is applied to each file in the file list. The mode can be either absolute or symbolic. Absolute modes are given as an octal number that represents the new file mode. The mode bits are defined as follows: 4000 Set effective user id on execution to file's owner id 2000 Set effective group id on execution to file's group id 0400 file is readable by the owner of the file 0200 writeable by owner 0100 executable by owner 0070 same as above, for other users in the same group 0007 same as above, for all other users Symbolic modes modify the current file mode in a specified way. They take the form: [who] op permissions { op permissions } The possibilities for [who] are 'u', 'g', 'o', and 'a'; standing for user, group, other and all, respectively. If who is omitted, 'a' is assumed, but the current umask is used. The op can be '+', '-', or '='; '+' turns on the given permissions, '-' turns them off; '=' sets the permissions exclusively for the given who. For example 'g=x' sets the group permissions to '--x'. The possible permissions are 'r', 'w', 'x'; which stand for read, write, and execute; 's' turns on the set effective user/group id bits. 'u', 'g' and 'o' in the permissions field stand for the current user, group, or other permission bits, respectively. Only one of these may be used at a time. 's' only makes sense with 'u' and 'g'; 'o+s' is harmless and does nothing. Multiple symbolic modes may be specified, separated by commas. # compress Command: compress - compress a file using modified Lempel-Ziv coding Syntax: compress [-cdfv] [file] ... Flags: -c Put output on standard output instead of on file.Z -d Decompress instead of compress -f Force output even if there is no saving -v Verbose mode Examples: compress outfile # compress 1 file compress x y z # compress 3 files to x.Z, y.Z, and z.Z The listed files (or standard input, if none are given) are comp "#$%&'()*+,-./0123456789:;<=>?ressed using the Ziv-Lempel algorithm. If the output is smaller than the input, the output is put on file.Z or standard output if no files are listed. If compress is linked to uncompress, the latter is the same as "compress -d". Similarly, a link to "zcat" decompresses to standard output. # cpdir Command: cpdir - copy a directory and its subdirectories Syntax: cpdir [-v] srcdir destdir Flags: -v Verbose; cpdir tells what it is doing Example: cpdir dir1 dir2 # creat dir2 and copy dir1's files into it Cpdir creates the target directory, goes into it, and copies all the files in the source directory to it. When it is done, the target directory contains the same files as the source directory. Subdirectories are copied Recursively. Links and special files are ignored. # cron Command: cron - clock daemon Syntax: cron Flags: (none) Example: /usr/bin/cron # use absolute path in /etc/rc Cron is clock daemon. It is typically started up by including the command /usr/bin/cron in the /etc/rc file. Once started, cron puts itself in the background, so no & is needed. It runs forever, sleeping most of the time. Once a minute it wakes up and examines /usr/lib/crontab to see if there is any work to do. If there is, the work is done. The entries of /usr/lib/crontab contain 6 elements each. Some examples follow: min hr dat mo day command * * * * * /usr/bin/date >/dev/tty0 #print date every minute 0 * * * * /usr/bin/date >/dev/tty0 #print date on the hour 30 4 * * 1-5 /bin/backup /dev/fd1 #do backup Mon-Fri at 0430 30 19 * * 1,3,5 /etc/backup /dev/fd1 #Mon, Wed, Fri at 1930 0 9 25 12 * /usr/bin/sing >/dev/tty0 #Xmas morning at 0900 only # diff Command: diff - print differences between two files Syntax: diff file1 file2 Flags: (none) Example: diff file1 file2 # print differences between 2 files Diff compares two files and generates a list of lines telling how the two files differ. Lines may not be longer than 128 characters. # diskcheck Command: diskcheck - check a disk for bad sectors Syntax: diskcheck device start count Flags: (none) Examples: diskcheck /dev/at0 0 1200 # check 1.2 MB floppy diskcheck /dev/at0 100 1100 # check floppy from block 100 Diskcheck checks a disk for bad sectors by reading in each sector, writing a known bit pattern onto it, reading it back in and comparing with what was written. This check is then done a second time. Bad sectors are reported. After each sector is tested, the original sector is restored. # dis88 Command: dis88 - disassembler Syntax: dis88 [-o] infile [outfile] Flags: -o List the object code along with the assembly code Examples: dis88 a.out >listing # disassemble a.out dis88 -o a.out listing # ditto, but with object code Dis88 is a disassembler. It takes an executable file and prints the symbolic assembly code that corresponds to it. If the executable file contains a symbol table (added by the program ast), the symbol table information is used to give a more readable asembly listing. # dosdir Command: dosdir - read a DOS directory Syntax: du [-lr] drive dir Flags: -l long -r recursive Example: dosdir -l c # list drive c Dosdir/dosread/doswrite have been extended to handle hard disks using the letters c,d,e, and f. The letters a and b can be used for floppies as synonyms for 0 and 1. # du Command: du - print disk usage Syntax: du [-s] dir Flags: -s Summary only Example: du dir # list disk space used by files in dir Du examines a directory and prints the amount of space occupied by the files in that directory and its subdirectories. # ed Command: ed - editor Syntax: ed file Flags: (none) Example: ed prog.c # edit prog.c Ed is functionally equivalent to the standard V7 editor, ed. It supports the following commands: (.) a: append (.,.) c: change (.,.) d: delete e: edit new file f: print name of edited file (1,$) g: global command (.) i: insert (.,.+1) j: join lines together (.) k: mark (.) l: print with special characters in octal (.,.) m: move (.,.) p: print q: quit editor (.) r: read in new file (.,.) s: substitute (1,$) v: like g, except select lines that do not match (1,$) w: write out edited file Many of the commands can take one or two addresses, as indicated above. The defaults are shown in parentheses. Thus 'a' appends to the current line, and g works on the whole file as default. The dot refers to the current line. Below is a sample editing session with comments given following the # symbol. ed prog.c # edit prog.c 3,20p # print lines 3 through 20 /whole/ # find next occurence of 'whole' s/whole/while/ # replace 'whole' by 'while' g/MAXBUF/s//MAX_BUF/g # replace 'MAXBUF' by 'MAX_BUF' everywhere w # write the file back q # exit the editor # expr Command: expr - evaluate experession Syntax: expr arg ... Flags: (none) Example: x=`expr $x + 1` # add 1 to shell variable x Expr computes the value of its argument and writes the result on standard output. The valid operators, in order of increasing precedence, are listed below. Operators grouped by {...} have the same precedence. Operators: |, &, {<, <=, ==, !=, >=, >}, {+, -}, *. Note that the V7 ":" operator is missing. Parentheses are permitted. # factor Command: factor - factor an integer less than 2**31 Syntax: factor number Flags: (none) Example: factor 450180 # print the prime factors of 450180 Factor prints the prime factors of its argument in increasing order. Each factor is printed as many times as it appears in the number. # fgrep Command: fgrep - fast grep Syntax: fgrep [-cfhlnsv] [file] [string] [file] ... Flags: -c count matching lines and only print count, not the lines -f take strings from file named in following argument -h omit file headers from printout -l list file names once only -n each line is preceded by its line number -s status only, no output -v print only lines not matching Examples: fgrep # prog.c # print lines containing # sign fgrep -f pattern prog.c # take strings from 'pattern' Fgrep is essentially the same as grep, except that it only searches for lines containing literal strings (no wildcard characters), and it is much faster. # file Command: file - make a guess as to a file's type based on contents Syntax: file name ... Flags: (none) Example: file a.out /usr/include/ar.h # guess at types File reads the first block of a file and tries to make an intelligent guess about what kind of file it is. It understands about archives, C source programs, executable binaries, shell scripts, and English text. # find Command: find - find files meeting a given condition Syntax: find directory expression Flags: (none) Examples: find / -name a.out -print # print all a.out paths find /usr/ast ! -newer f -ok rm {} \; # ask before removing find /usr -size +20 -exec mv {} /big \; # move files > 20 blks find / \( -name a.out -o -name `*.o` \) -exec rm {}\; Find descends the file tree starting at the given directory checking each file in that directory and its subdirectories against a predicate. If the predicate is true, an action is taken. The predicates may be connected by -a (Boolean and), -o (Boolean or) and ! (Boolean negation). Each predicate is true under the conditions specified below. The integer n may also be +n to mean any value greater than n, -n to mean any value less than n, or just n for exactly n. -name s true if current filename is s (include shell wild cards) -size n true if file size is n blocks -inum n true if the current file's i-node number is n -mtime n true if modification time relative to today (in days) is n -links n true if the number of links to the file is n -newer f true if the file is newer than f -perm n true if the file's permission bits = n (n is in octal) -user u true if the uid = u (a numerical value, not a login name) -grogp g true if the gid = g (a numerical value, not a group name) -type x where x is bcdfug (block, char, dir, regular, setuid, setgid) Following the expression can be one of the following, telling what to do when a file is found: -print print the file name on standard output -exec execute a MINIX command, {} stands for the file name -ok prompts before executing the command # fdisk Command: fdisk - partition a hard disk Syntax: fdisk file Flags: (none) Example: fdisk /dev/hd1 When fdisk starts up, it reads in the partition table and displays it. It then presents a menu to allow the user to modify partitions, store the partition table on a file, or load it from a file. Partitions can be marked as DOS or non-DOS, and active or not. MINIX doesn't care what kind of a partition it uses. Using fdisk is self-explanatory. However, be aware that repartitioning a disk may cause information on it to be lost. Rebooting the system is mandatory after changing partition sizes. MINIX, XENIX, PC-IX, and MS-DOS all have different ideas about how partitions are numbered. # fix Command: fix - generate new file from old one and diff listing Syntax: fix oldfile difflist >newfile Flags: (none) Example: fix old difflist >new # generate new from old and diffs Fix accepts a diff listing produced by diff and reconstructs the new file. It is common for people to take a file, modify it, and then send the diff listing between the old and new files to other people. Using fix, the old file, and the diff listing, it is possible to creat the new file. For example: diff oldfile newfile >difflist fix oldfile difflist >new2 will generate a file new2 that is identical to newfile. # from Command: from - input half of a connection Syntax: from port Flags: (none) Examples: from port | sort >x # fetch and sort an incoming file from port | sh # primitive sherver To and from are used together to provide connection-oriented service. On the sending machine, the last member of a pipeline is 'to port'. On the receiving machine, the first member of a pipe line is 'from port'. The net result is that the output of the sending pipeline goes into the input of the receiving pipeline, making pipelines work across the network. #fsck Command: fsck - perform file system consistency check Syntax: fsck [-aclmrs] [device] ... Flags: -a automatically repair inconsistencies -c inode ... check and list only the specified inodes -l list the files and directories in the filesytem -m make a new file system -r prompt user for repairs if inconsistencies are found -s list the superblock of the file system Examples: fsck /dev/hd4 # check file system on /dev/hd4 fsck -a /dev/at0 # automatically fix errors on /dev/at0 fsck -l /dev/fd0 # list the contents of /dev/fd0 fsck -c 2 3 /dev/hd3 # check and list /dev/hd3 inodes 2 & 3 Fsck performs consistency checks on the file systems which reside on the specified devices. It may also be used to list the contents of a file system or to make a new file system. Fsck can be run from the initial menu and during normal production. The number of heads and sectors/track are built in to the program (4 and 17, respectively). To change these, modify the code and recompile. If they are set wrong, fsck will give absurd errors. # help Command: help - give help about a command Syntax: help [name] Flags: (none) Example: help uuencode Help gives help about a given command name (or help itself, if none is specified). It gets its information from /usr/lib/helpfile, which should be linked to doc/man_pages. To improve performance, it builds an index file, /usr/lib/helpfile.idx, which is updated when it is observed to be older than /usr/lib/helpfile. The lines beginning with # are the keywords for help. The helpfile contains all the manual pages not present in the book. # lorder Command: lorder - compute the order for library modules Syntax: lorder file ... Flags: (none) Example: lorder proc1.s proc2.s Lorder accepts a series of packed or unpacked .s files and libraries, and produces a partial ordering suitable for processing by tsort. # master Command: master - control the creation of shervers Syntax: master count uid gid command Flags: (none) Example: master 2 1 1 /usr/bin/sherver port If a machine is intended to be used as a server, its /etc/rc file should have a command similar to the example above. When the system is booted, master runs and forks off the required number of shervers (max 4). They run with the indicated uid and gid, and listen to the indicated port. When an rsh is done on a client machine, the command is given to one of the shervers for execution. When the sherver is done, it exits, master, which is always running, sees this, and creates a new sherver. Thus master is very similar to init, only it makes new shervers (usually) instead of new login programs. Master must run as root to be able to do setuid and setgid. # more Command: more - pager Syntax: more file ... Flags: (none) Example: more file # display file on the screen More is an alternative to mined as a pager, for people used to the 4.x BSD pager. This version only implements three commands: - display next page - display next line q - exit more # nm Command: nm - print name list Syntax: nm [-gnopru] [file] ... Flags: -g print only external symbols. -n sort numerically rather than alphabetically. -o prepend file name to each line rather than only once. -p don't sort, print in symbol-table order. -r sort in reverse order. -u print only undefined symbols. Examples: nm -n a.out # print all symbols in numerical order nm -g a.out # print global symbols alphabetically Nm prints the symbol table of executable files when it is available. If no file is given, the symbols in a.out are used. The format of the table is somewhat compatible with the one produced by asld when used with the -s option. The symbol table can be added with ast. Archives are not supported. Note that assembly language files don't have symbol tables. # paste Command: paste - paste multiple files together Syntax: paste [-s] [-ddelim] file ... Flags: -s print files sequentially, file k on line k -ddelim set delimiter used to separate columns Examples: paste file1 file2 # print file1 in col 1, file2 in col 2 paste -s f1 f2 f3 f4 # print f1 on line 1, f2 on line 2, etc Paste displays multiple files in parallel. Suppose a set of k files each have one word per line. Then the paste output will have k columns, with the contents of file j in column j. The columns are separate by tabs unless the separator is changed with the -d flag. If the -s flag is given, then the first file is on line 1, the second file on line 2, etc. In effect, -s turns the files sideways. # patch Command: patch - patches up a file from the original and a diff Syntax: patch [-bcdDefFlnNop] Flags: -b next argument is backup extension, instead of .orig -c interpret the patch file as a context diff -d cd to the next arg (assumed a dir) before doing anything -D mark changes with "#ifdef...#endif"; next arg gives label -e interpret the patch file as an ed script -f forces patch to do its work without asking any questions -F# sets the maximum fuzz factor -l do matching loosely (e.g., all white space is equivalent) -n interpret the patch file as a normal diff -N ignore patches that are reversed or already applied -o next argument is the output file name -p# sets the pathname strip count Example: patch file difflist # fix up the file Patch takes an original file and a diff listing and recreates the new file. It is functionally similar to fix, but much more powerful. Not only can it handle normal diffs, but also context diffs produced by cdiff. In addition, it works even when the file being patched has other changes to it. It deduces the type of difflist itself (unless given -c, -e, or -n). The normal usage is given in the example above. In this case patch will modify 'file' to incorporate all the patches. The original file will be put on 'file~. # prep Command: prep - prepare a text file for statistical analysis Syntax: prep [file] Flags: (none) Examples: prep infile >outfile # prep infile prep outfile # prep infile Prep strips off most of the troff commands from a text file and then outputs all the words, one word per line, in the order they occur in the file. This file can then be sorted and compared to a dictionary (as a spelling checker), or used for statistical analyses. # printenv Command: printenv - print out the current environment Syntax: printenv Flags: (none) Example: printenv # print the environment Printenv prints out the current environment strings, one per line. # rcp Command: rcp - remote copy Syntax: rcp [mach1]!file1 [mach2]!file2 Flags: (none) Examples: rcp file mach1!/usr/ast/x # local file to remote machine rcp mach2!/usr/ast/x file # fetch remote file Rcp is not a program. It is a shell script that does remote copying. It makes use of the programs 'to' and 'from'. # readall Command: readall - read a device quickly to check for bad blocks Syntax: readall file Flags: (none) Example: readall /dev/hd0 # read all of /dev/hd0 Readall reads all of the named device in large chunks. It reports about blocks that it cannot read. Unlike diskcheck, it does not attempt to write on the disk, making it "safer" to use when one is worried about a sick system. # readclock Command: readclock - read the AT's real time clock Syntax: readclock Flags: (none) Example: date `/usr/bin/readclock` f # fetch remote file rsh foobar # log onto remote machine The remote shell command is the way to have a distant server carry out a command over the Ethernet. The port given as the first argument can be any string of up to 6 characters, but it must match the port used by some sherver. The command will be executed and the results returned on stdout. Unless the -e flag is given, the remote stderr and stdout are merged onto the local stdout. Giving rsh with just a port and no argument is the standard way to log onto a remote machine. # sherver Command: sherver - shell server Syntax: sherver port Flags: (none) Example: sherver machine1 The rsh command does its remote execution by doing a remote procedure call to some sherver. The sherver executes the command and then exits. Usually a master will be running to make a new one. Because shervers get their input from a pipe, remote execution cannot handle signals and CTRL-D, because they cannot be sent down a pipe. # spell Command: spell - print all words in a file not present in the dictionary Syntax: spell file Flags: (none) Example: spell document # print the spelling errors on stdout Spell is the MINIX spelling checker. It is actually a short shell script. First, the program prep strips off the roff, nroff, and troff control lines, and the punctuation, and lists each word on a separate line. These words are then sorted. The resulting output is then compared to the dictionary. Words present in the file but not present in the dictionary are listed. The dictionary should be located in /usr/lib (or the shell script changed). # strings Command: strings - print all the strings in a binary file Syntax: strings file ... Flags: - # search whole file, not just data seg -o # print octal offset of each string -n # n is minimum length string (def. = 4) Examples: strings -5 a.out # print the strings >= 5 chars in a.out strings - /bin/sh # search entire shell file Strings looks for sequences of ASCII characters followed by a zero byte. These are usually strings. This program is typically used to help identify unknown binary programs # strip Command: strip - remove symbol table from executable file Syntax: strip [file] ... Flags: (none) Example: strip a.out # remove symbols from a.out For each file argument, strip removes the symbol table. Strip makes a copy of the file being stripped, so links are lost. # term Command: term - turn PC into a dumb terminal Syntax: term [baudrate] [parity] [bits_per_character] Flags: (none) Examples: term 2400 # talk to modem at 2400 baud term 1200 7 even # 1200 baud, 7 bits/char, even parity term 8 9600 # 9600 baud, 8 bits/char, no parity Term allows MINIX to talk to a terminal or modem over RS232 port 1. The program first sets the baudrate, parity and character length, and then forks. The parent sits in a loop copying from standard input (usually the console's keyboard), to the terminal or modem (/dev/tty1). The child sits in a loop copying from the terminal or modem (/dev/tty1) to standard output. Thus when RS232 port 1 is connected to a modem, every keystroke typed on the keyboard is sent to the modem, and every character arriving from the modem is displayed. Standard input and output may be redirected, to provide a primitive file transfer program, with no checking. To exit term, type three ESC characters. Important note: to use term, it is essential that /etc/ttys is configured so that there is no shell hanging on /dev/tty1. If there is, both the shell and term will try to read from /dev/tty1, and nothing will work. # termcap Command: termcap - print the current termcap entry Syntax: termcap [type] Flags: (none) Example: termcap # print the termcap entry Termcap reads the /etc/termcap entry corresponding to the terminal type supplied as the argument. If none is given, the current $TERM is used. It then prints out all the parameters that apply. # test Command: test - test for a condition Syntax: test expr Flags: (none) Example: test -r file # see if file is readable Test checks to see if files exist, are readable, etc. and returns an exit status of zero if true and nonzero if false. The legal operators are -r file true if the file is readable -w file true if the file is writable -x file true if the file is executable -f file true if the file is not a directory -d file true if the file is a directory -s file true if the file exists and has a size > 0 -t fd true if file descriptor fd (default 1) is a terminal -z s true if the string s has zero length -n s true if the string s has nonzero length s1 = s2 true if the strings s1 and s2 are identical s1 != s2 true if the strings s1 and s2 are different m -eq m true if the integers m and n are numerically equal The operators -gt, -ge, -ne, -le, -lt may be used as well These operands may be combined with -a (Boolean and), -o (Boolean or), ! (negation). The priority of -a is higher than that of -o. Parentheses are permitted, but must be escaped to keep the shell from trying to interpret them. # to Command: to - output half of a connection Syntax: to port Flags: (none) Example: cat f1 f2 | to mach4 # send the catted files to port To and from are used together to provide connection-oriented service. On the sending machine, the last member of a pipeline is 'to port'. On the receiving machine, the first member of a pipe line is 'from port'. The net result is that the output of the sending pipeline goes into the input of the receiving pipeline, making pipelines work across the network. As a simple example, consider: on machine1: cat f1 f2 | to Johnny on machine2: from Johnny | sort >x The effect of these two commands is that the files f1 and f2 are concatenated, transferred to machine 2, and sorted their, with the output going to a file x on machine 2. The string Johnny is used by the transaction system to identify which sender goes with which receiver; any unique string can be used. # traverse Command: traverse - print directory tree under the named directory Syntax: traverse dir Flags: (none) Example: traverse . # print tree starting at working dir Traverse prints the tree structure starting at the named directory. All the subdirectories are listed, with the depth shown by indentation. # tset Command: tset - set the $TERM variable Syntax: tset [device] Flags: (none) Example: eval `tset` # set TERM Tset is used almost exclusively to set the shell variable TERM from inside profiles. If an argument is supplied, that is used as the value of TERM. Otherwise it looks in /etc/ttytype. # tsort Command: tsort - topological sort Syntax: tsort file Flags: (none) Example: ar cr libc.a `lorder *.s | tsort` # build library Tsort accepts a file of lines containing ordered pairs and builds a total ordering from the partial orderings. # treecmp Command: treecmp - recursively list differences in two directory trees Syntax: treecmp [-v] dir1 dir2 Flags: -v (verbose) list all directories processed Example: treecmp -v /usr/ast/V1 /usr/ast/V2 Treecmp recursively descends the directory tree of its first argument and compares all files to those at the corresponding position in the second argument. If the two trees are identical, i.e., all the corresponding directories and files are the same, there is no output. Otherwise, a list of files missing from one of the trees or present in both but whose contents are not identical in both are printed. # tty Command: tty - print the device name of this tty Syntax: tty Flags: -s silent mode (return status only) Example: tty Print the name of the controlling tty # vol Command: vol - split standard input into diskette-sized volumes Syntax: vol [-u] size block-special Flags: -u unsave from diskettes Examples: tar c - . | vol 360 /dev/fd0 # prompt for disk every 360K vol -u 360 /dev/fd0 | tar x - # restore a saved file system It occasionally happens that a program generates an output stream intended for diskette but the stream is to large to fit on one diskette. Vol is a program that accepts such a stream, and pauses every n blocks to request a new diskette to be inserted. This makes it possible to save arbitrarily long streams on a series of diskettes, as shown in the examples above. # whereis Command: whereis - examine system directories for a given file Syntax: whereis file Flags: (none) Example: whereis stat.h # prints: /usr/include/sys/stat.h Whereis searches a fixed set of system directories, /bin, /lib, /usr/bin, and others, and prints all occurrences of the argument name in any of them. # which Command: which - examine $PATH to see which file will be executed Syntax: which name Flags: (none) Example: which a.out # tells which a.out will be executed The $PATH shell variable controls the MINIX search rules. If a command a.out is given, the shell first tries to find an executable file in the working directory. If that fails, it looks in various system directories, such as /bin and /usr/bin. The which command makes the same search and gives the absolute path of the program that will be chosen. # who Command: who - print list of currently logged in users Syntax: who Flags: (none) Example: who # print user names, terminals and times Who prints a list of currently logged in users. For each one, the user name, terminal, and login time is printed. This program gets its information from the file /usr/adm/wtmp, which is updated by init and login. If the file does not exist, neither of these will create it, and 'who' will not work. Note that if you decide to create an empty /usr/adm/wtmp to enable the login accounting, it will grow forever and eventually fill up your disk unless you manually truncate it from time to time. # whoami Command: whoami - print current user name Syntax: whoami Flags: (none) Example: whoami # print user name In case you forget who you are logged in as, whoami will tell you. If you use 'su' to become somebody else, whoami will give the current effective user. # uuencode Command: uuencode - encode a binary file to ASCII (e.g., for mailing) Syntax: uuencode [input] output Flags: (none) Example: uuencode infile outfile # encode infile Uuencode takes an input file, typically a binary file, and converts it to pure ASCII by encoding 3 bytes (24 bits) as 4 bytes in ASCII. Only 64 different characters are used, all of them valid ASCII characters. # uudecode Command: uudecode - decode a binary file encoded with uuencode Syntax: uudecode file Flags: (none) Example: uudecode encodedfile # re-create the original file Uudecode takes an input file, typically a uuencoded binary file, and converts it back to the original file. The decoded file is given the name that the original file had. The name information is part of the encoded file. # write Command: write - write a message to a terminal Syntax: write ttyn Flags: (none) Example: write tty1 # write to /dev/tty1 Write is a shell script that is used to send a message to another logged in user on the system. The user is identified by tty number. After the message has been typed, the user types CTRL-D to exit. ...a.out.hstdio.hassert.hfcntl.hctype.herrno.herror.hgrp.hlib.hpwd.hregexp.hsetjmp.hamoeba.hsignal.hlimits.hmemory.hstring.har.hunistd.htime.hutime.hutmp.hfs/* a.out header file */ struct exec { /* a.out header */ unsigned char a_magic[2]; /* magic number */ unsigned char a_flags; /* flags, see below */ unsigned char a_cpu; /* cpu id */ unsigned char a_hdrlen; /* length of header */ unsigned char a_unused; /* reserved for future use */ unsigned short a_version; /* version stamp */ /* not used */ long a_text; /* size of text segement in bytes */ long a_data; /* size of data segment in bytes */ long a_bss; /* size of bss segment in bytes */ long a_no_entry; /* in fact: entry point, a_entry */ long a_total; /* total memory allocated */ long a_syms; /* size of symbol table */ /* SHORT FORM ENDS HERE */ long a_trsize; /* text relocation size */ long a_drsize; /* data relocation size */ long a_tbase; /* text relocation base */ long a_dbase; /* data relocation base */ }; #define A_MAGIC0 (unsigned char) 0x01 #define A_MAGIC1 (unsigned char) 0x03 #define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 ||\ (X).a_magic[1] != A_MAGIC1) /* CPU Id of TARGET machine */ /* byte order coded in low order two bits */ #define A_NONE 0x00 /* unknown */ #define A_I8086 0x04 /* intel i8086/8088 */ #define A_M68K 0x0B /* motorola m68000 */ #define A_NS16K 0x0C /* national semiconductor 16032 */ #define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */ #define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ /* flags: */ #define A_EXEC 0x10 /* executable */ #define A_SEP 0x20 /* separate I/D */ #define A_PURE 0x40 /* pure text */ /* not used */ #define A_TOVLY 0x80 /* text overlay */ /* not used */ /* offsets of various things: */ #define A_MINHDR 32 #define A_TEXTPOS(X) ((long)(X).a_hdrlen) #define A_DATAPOS(X) (A_TEXTPOS(X) + (X).a_text) #define A_HASRELS(X) ((X).a_hdrlen > (unsigned char) A_MINHDR) #define A_HASEXT(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 8)) #define A_HASLNS(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16)) #define A_HASTOFF(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24)) #define A_TRELPOS(X) (A_DATAPOS(X) + (X).a_data) #define A_DRELPOS(X) (A_TRELPOS(X) + (X).a_trsize) #define A_SYMPOS(X) (A_TRELPOS(X) + (A_HASRELS(X) ? \ ((X).a_trsize + (X).a_drsize) : 0)) struct reloc { long r_vaddr; /* virtual address of reference */ unsigned short r_symndx; /* internal segnum or extern symbol num */ unsigned short r_type; /* relocation type */ }; /* r_tyep values: */ #define R_ABBS 0 #define R_RELLBYTE 2 #define R_PCRBYTE 3 #define R_RELWORD 4 #define R_PCRWORD 5 #define R_RELLONG 6 #define R_PCRLONG 7 #define R_REL3BYTE 8 #define R_KBRANCHE 9 /* r_symndx for internal segments */ #define S_ABS ((unsigned short)-1) #define S_TEXT ((unsigned short)-2) #define S_DATA ((unsigned short)-3) #define S_BSS ((unsigned short)-4) struct nlist { /* symbol table entry */ char n_name[8]; /* symbol name */ long n_value; /* value */ unsigned char n_sclass; /* storage class */ unsigned char n_numaux; /* number of auxiliary entries */ /* not used */ unsigned short n_type; /* language base and derived type */ /* not used */ }; /* low bits of storage class (section) */ #define N_SECT 07 /* section mask */ #define N_UNDF 00 /* undefined */ #define N_ABS 01 /* absolute */ #define N_TEXT 02 /* text */ #define N_DATA 03 /* data */ #define N_BSS 04 /* bss */ #define N_COMM 05 /* (common) */ /* high bits of storage class */ #define N_CLASS 0370 /* storage class mask */ #define C_NULL #define C_EXT 0020 /* external symbol */ #define C_STAT 0030 /* static */ /* there are many others, but they are not supported */ #define BUFSIZ 1024 #define NFILES 20 #define NULL 0 #define EOF (-1) #define CMASK 0377 #define READMODE 1 #define WRITEMODE 2 #define UNBUFF 4 #define _EOF 8 #define _ERR 16 #define IOMYBUF 32 #define PERPRINTF 64 #define STRINGS 128 #ifndef FILE extern struct _io_buf { int _fd; int _count; int _flags; char *_buf; char *_ptr; } *_io_table[NFILES]; #endif /* FILE */ #define FILE struct _io_buf #define stdin (_io_table[0]) #define stdout (_io_table[1]) #define stderr (_io_table[2]) #define getchar() getc(stdin) #define putchar(c) putc(c,stdout) #define getc(f) fgetc(f) #define putc(c,f) fputc(c,f) #define feof(p) (((p)->_flags & _EOF) != 0) #define ferror(p) (((p)->_flags & _ERR) != 0) #define fileno(p) ((p)->_fd) #define rewind(f) fseek(f, 0L, 0) #define testflag(p,x) ((p)->_flags & (x)) /* If you want a stream to be flushed after each printf use: * * perprintf(stream); * * If you want to stop with this kind of buffering use: * * noperprintf(stream); */ #define noperprintf(p) ((p)->_flags &= ~PERPRINTF) #define perprintf(p) ((p)->_flags |= PERPRINTF) extern FILE *fopen(); extern FILE *freopen(); extern long ftell(); extern char *fgets(); extern char *gets(); #ifndef NDEBUG #define assert(xxx) {if(!(xxx)){fprintf(stderr, "False assertion at line %d in file \"%s\"\n", __LINE__, __FILE__); exit(1);}} #endif /* For fcntl(3) */ #define F_DUPFD 0 #define F_GETFD 1 /* reserved for future use */ #define F_SETFD 2 /* reserved for future use */ #define F_GETFL 3 /* reserved for future use */ #define F_SETFL 4 /* reserved for future use */ /* For open(2) */ #define O_RDONLY 0 #define O_WRONLY 1 #define O_RDWR 2 extern char _ctype_[]; #define _U 0001 #define _L 0002 #define _N 0004 #define _S 0010 #define _P 0020 #define _C 0040 #define _X 0100 #define isalpha(c) ((_ctype_+1)[c]&(_U|_L)) #define isupper(c) ((_ctype_+1)[c]&_U) #define islower(c) ((_ctype_+1)[c]&_L) #define isdigit(c) ((_ctype_+1)[c]&_N) #define isxdigit(c) ((_ctype_+1)[c]&(_N|_X)) #define isspace(c) ((_ctype_+1)[c]&_S) #define ispunct(c) ((_ctype_+1)[c]&_P) #define isalnum(c) ((_ctype_+1)[c]&(_U|_L|_N)) #define isprint(c) ((_ctype_+1)[c]&(_P|_U|_L|_N)) #define iscntrl(c) ((_ctype_+1)[c]&_C) #define isascii(c) ((unsigned)(c)<=0177) #define toupper(c) ((c) - 'a' + 'A') #define tolower(c) ((c) - 'A' + 'a') #define OK 0 #define ERROR 1 #define EPERM 1 #define ENOENT 2 #define ESRCH 3 #define EINTR 4 #define EIO 5 #define ENXIO 6 #define E2BIG 7 #define ENOEXEC 8 #define EBADF 9 #define ECHILD 10 #define EAGAIN 11 #define ENOMEM 12 #define EACCES 13 #define EFAULT 14 #define ENOTBLK 15 #define EBUSY 16 #define EEXIST 17 #define EXDEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 #define EDOM 33 #define ERANGE 34 #define E_LOCKED 101 #define E_BAD_CALL 102 #define E_LONG_STRING 103 /* Error codes. They are negative since a few system calls, such as READ, can * either return a positive number indicating success, or an error code. */ #define NERROR 34 #define OK 0 #define ERROR -1 #define EPERM -1 #define ENOENT -2 #define ESRCH -3 #define EINTR -4 #define EIO -5 #define ENXIO -6 #define E2BIG -7 #define ENOEXEC -8 #define EBADF -9 #define ECHILD -10 #define EAGAIN -11 #define ENOMEM -12 #define EACCES -13 #define EFAULT -14 #define ENOTBLK -15 #define EBUSY -16 #define EEXIST -17 #define EXDEV -18 #define ENODEV -19 #define ENOTDIR -20 #define EISDIR -21 #define EINVAL -22 #define ENFILE -23 #define EMFILE -24 #define ENOTTY -25 #define ETXTBSY -26 #define EFBIG -27 #define ENOSPC -28 #define ESPIPE -29 #define EROFS -30 #define EMLINK -31 #define EPIPE -32 #define EDOM -33 #define ERANGE -34 #define E_LOCKED -101 #define E_BAD_CALL -102 #define E_LONG_STRING -103 #define EOF -104 /* End Of File - used by drivers */ /* The following error codes are generated by the kernel itself. */ #define E_BAD_DEST -1 /* destination address illegal */ #define E_BAD_SRC -2 /* source address illegal */ #define E_TRY_AGAIN -3 /* can't send-- tables full */ #define E_OVERRUN -4 /* interrupt for task that is not waiting */ #define E_BAD_BUF -5 /* message buf outside caller's addr space */ #define E_TASK -6 /* can't send to task */ #define E_NO_MESSAGE -7 /* RECEIVE failed: no message present */ #define E_NO_PERM -8 /* ordinary users can't send to tasks */ #define E_BAD_FCN -9 /* only valid fcns are SEND, RECEIVE, BOTH */ #define E_BAD_ADDR -10 /* bad address given to utility routine */ #define E_BAD_PROC -11 /* bad proc number given to utility */ struct group { char *gr_name; char *gr_passwd; int gr_gid; }; #include #include #include #include extern message M; #define MM 0 #define FS 1 extern int callm1(), callm3(), callx(), len(); extern int errno; extern int begsig(); /* interrupts all vector here */ struct passwd { char *pw_name; char *pw_passwd; int pw_uid; int pw_gid; char *pw_gecos; char *pw_dir; char *pw_shell; }; /* * Definitions etc. for regexp(3) routines. * * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], * not the System V one. */ #define void int #define CHARBITS 0377 #define strchr index #define NSUBEXP 10 typedef struct regexp { char *startp[NSUBEXP]; char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; extern regexp *regcomp(); extern int regexec(); extern void regsub(); extern void regerror(); /* _JBLEN should be 3 for IBM PC, 13 for ATARI. */ #define _JBLEN 3 typedef int jmp_buf[_JBLEN]; /****************************************************************************/ /* */ /* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */ /* */ /* This product is part of the Amoeba distributed operating system. */ /* */ /* Permission to use, sell, duplicate or disclose this software must be */ /* obtained in writing. Requests for such permissions may be sent to */ /* */ /* */ /* Dr. Andrew S. Tanenbaum */ /* Dept. of Mathematics and Computer Science */ /* Vrije Universiteit */ /* Postbus 7161 */ /* 1007 MC Amsterdam */ /* The Netherlands */ /* */ /****************************************************************************/ /* ** If the host operating system for amoeba transactions is not amoeba ** then several things may need to be done to make the amoeba code ** compatible. These are provided in host_os.h. */ #include "host_os.h" #define PORTSIZE 6 #define OOBSIZE 20 #define HEADERSIZE 32 #define PRIVSIZE 10 #define CAPSIZE 16 #define FAIL ((unshort) -1) #define NOTFOUND ((unshort) -2) #define BADADDRESS ((unshort) -3) #define ABORTED ((unshort) -4) #define TRYAGAIN ((unshort) -5) #define sizeoftable(t) (sizeof(t) / sizeof((t)[0])) #define NILPORT ((port *) 0) #define NILBUF ((bufptr) 0) #define _FP(p) ((struct _fakeport *) (p)) #ifndef lint #define PortCmp(p, q) (_FP(p)->_p1==_FP(q)->_p1 && _FP(p)->_p2==_FP(q)->_p2) #define NullPort(p) (_FP(p)->_p1==0L && _FP(p)->_p2==0) #else #define PortCmp(p, q) ((p)->_portbytes[0] == (q)->_portbytes[0]) #define NullPort(p) ((p)->_portbytes[0] == 0) #endif typedef char *bufptr; #ifndef MAX_BLOCK_NR typedef unsigned short unshort; #endif typedef char *event_t; typedef struct { char _portbytes[PORTSIZE]; } port; struct _fakeport { long _p1; short _p2; }; typedef struct { /* private part of capability */ char prv_object[3]; char prv_rights; port prv_random; } private; typedef struct { port cap_port; private cap_priv; } capability; typedef struct { port h_port; port h_signature; private h_priv; unshort h_command; long h_offset; unshort h_size; unshort h_extra; } header; #define h_status h_command /* alias: reply status */ /* ** Some function declarations that people tend to forget ** because they are lazy. */ extern unshort trans(), getreq(), putrep(), timeout(); #define NSIG 16 /* number of signals used */ #define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt (DEL) */ #define SIGQUIT 3 /* quit (ASCII FS) */ #define SIGILL 4 /* illegal instruction (not reset when caught)*/ #define SIGTRAP 5 /* trace trap (not reset when caught) */ #define SIGIOT 6 /* IOT instruction */ #define SIGEMT 7 /* EMT instruction */ #define SIGFPE 8 /* floating point exception */ #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10 /* bus error */ #define SIGSEGV 11 /* segmentation violation */ #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ #define STACK_FAULT 16 /* used by kernel to signal stack fault */ #define NR_SIGS NSIG int (*signal())(); #define SIG_DFL (int (*)())0 #define SIG_IGN (int (*)())1 /* limits.h */ #define CHAR_BIT 8 /* number of bits in char */ #define WORD_BIT 16 /* number of bits in int */ #define CHAR_MAX 127 /* max value of char */ #define CHAR_MIN -128 /* min value of char */ #define SCHAR_MAX 127 /* max value of signed char */ #define SCHAR_MIN -128 /* min value of signed char */ #define UCHAR_MAX 255 /* max value of unsigned char */ #define SHRT_MAX 32767 /* max value of short */ #define SHRT_MIN -32768 /* min value of short */ #define USHRT_MAX 65535 /* max value of unsigned short */ #define INT_MAX 32767 /* max value of int */ #define INT_MIN -32768 /* min value of int */ #define UINT_MAX 65535 /* max value of unsigned int */ #define LONG_MAX 2147483647 /* max value of long */ #define LONG_MIN -2147483648 /* min value of long */ #define ULONG_MAX 4294967295 /* max value of unsigned long */ #define NAME_MAX 14 /* characters in a file name */ #define PATH_MAX 127 /* number chars in path name */ /* SHOULD BE >= 255 */ #define FCHR_MAX 67108864 /* max file size */ #define LINK_MAX 127 /* max links to a file */ #define LOCK_MAX 0 /* max number of file locks */ /* SHOULD BE >= 32 */ #define OPEN_MAX 20 /* max number open files */ #define SYS_OPEN 64 /* max open files per system */ #define STD_BLK 1024 /* bytes per block */ #define PIPE_MAX 7168 /* max size of write to pipe */ #define PIPE_BUF PIPE_MAX /* size of atomic write to pipe */ #define PID_MAX 30000 /* max process id */ #define PROC_MAX 16 /* max number of processes */ #define CHILD_MAX (PROC_MAX-1) /* number of process children */ #define NGROUPS_MAX 0 /* no multiple group ids */ #define UID_MAX 255 /* max user or group id */ /* SHOULD BE >= 32000 */ #define ARG_MAX 2048 /* execve() arg & environ space */ /* SHOULD BE >= 4096 */ #define CLK_TCK 60 /* clock ticks per second */ #define MAX_CHAR 256 /* characters for terminal i/p */ #define PASS_MAX 8 /* max number chars in password */ #define SYS_NMLN 9 /* length of uname() strings */ /* including '\0' */ char *memcpy(); char *memccpy(); char *memchr(); char *memset(); int memcmp(); /* string.h (a.k.a. strings.h) */ int strlen(); int strcmp(), strncmp(); int strspn(), strcspn(); char *strcpy(), *strncpy(); char *strcat(), *strncat(); char *index(), *rindex(); char *strchr(), *strrchr(); char *strpbrk(); char *strtok(); char *strstr(); #define ARMAG 0177545 struct ar_hdr { char ar_name[14]; long ar_date; char ar_uid; char ar_gid; int ar_mode; long ar_size; }; /* For access(2) */ #define R_OK 4 #define W_OK 2 #define X_OK 1 #define F_OK 0 /* For lockf() */ #define F_ULOCK 0 #define F_LOCK 1 #define F_TLOCK 2 #define F_TEST 3 /* For lseek(2) */ #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #define IN_PATH "/etc/include" struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; }; /* For utime(2) */ struct utimbuf { time_t actime; time_t modtime; }; /* utmp.h - Used by login(1), init, and who(1) */ #define WTMP "/usr/adm/wtmp" struct utmp { char ut_line[8]; /* terminal name */ char ut_name[8]; /* user name */ long ut_time; /* login/out time */ }; ...buf.hconst.h/* Buffer (block) cache. To acquire a block, a routine calls get_block(), * telling which block it wants. The block is then regarded as "in use" * and has its 'b_count' field incremented. All the blocks, whether in use * or not, are chained together in an LRU list, with 'front' pointing * to the least recently used block, and 'rear' to the most recently used * block. A reverse chain, using the field b_prev is also maintained. * Usage for LRU is measured by the time the put_block() is done. The second * parameter to put_block() can violate the LRU order and put a block on the * front of the list, if it will probably not be needed soon. If a block * is modified, the modifying routine must set b_dirt to DIRTY, so the block * will eventually be rewritten to the disk. */ EXTERN struct buf { /* Data portion of the buffer. */ union { char b__data[BLOCK_SIZE]; /* ordinary user data */ dir_struct b__dir[NR_DIR_ENTRIES]; /* directory block */ zone_nr b__ind[NR_INDIRECTS]; /* indirect block */ d_inode b__inode[INODES_PER_BLOCK]; /* inode block */ int b__int[INTS_PER_BLOCK]; /* block full of integers */ } b; /* Header portion of the buffer. */ struct buf *b_next; /* used to link bufs in a chain */ struct buf *b_prev; /* used to link bufs the other way */ struct buf *b_hash; /* used to link bufs on hash chains */ block_nr b_blocknr; /* block number of its (minor) device */ dev_nr b_dev; /* major | minor device where block resides */ char b_dirt; /* CLEAN or DIRTY */ char b_count; /* number of users of this buffer */ } buf[NR_BUFS]; /* A block is free if b_dev == NO_DEV. */ #define NIL_BUF (struct buf *) 0 /* indicates absence of a buffer */ /* These defs make it possible to use to bp->b_data instead of bp->b.b__data */ #define b_data b.b__data #define b_dir b.b__dir #define b_ind b.b__ind #define b_inode b.b__inode #define b_int b.b__int EXTERN struct buf *buf_hash[NR_BUF_HASH]; /* the buffer hash table */ EXTERN struct buf *front; /* points to least recently used free block */ EXTERN struct buf *rear; /* points to most recently used free block */ EXTERN int bufs_in_use; /* # bufs currently in use (not on free list) */ /* When a block is released, the type of usage is passed to put_block(). */ #define WRITE_IMMED 0100 /* block should be written to disk now */ #define ONE_SHOT 0200 /* set if block not likely to be needed soon */ #define INODE_BLOCK 0 + WRITE_IMMED /* inode block */ #define DIRECTORY_BLOCK 1 + WRITE_IMMED /* directory block */ #define INDIRECT_BLOCK 2 + WRITE_IMMED /* pointer block */ #define I_MAP_BLOCK 3 + WRITE_IMMED + ONE_SHOT /* inode bit map */ #define ZMAP_BLOCK 4 + WRITE_IMMED + ONE_SHOT /* free zone map */ #define ZUPER_BLOCK 5 + WRITE_IMMED + ONE_SHOT /* super block */ #define FULL_DATA_BLOCK 6 /* data, fully used */ #define PARTIAL_DATA_BLOCK 7 /* data, partly used */ /* Tables sizes */ #define NR_ZONE_NUMS 9 /* # zone numbers in an inode */ #define NR_BUFS 30 /* # blocks in the buffer cache */ #define NR_BUF_HASH 32 /* size of buf hash table; MUST BE POWER OF 2*/ #define NR_FDS 20 /* max file descriptors per process */ #define NR_FILPS 64 /* # slots in filp table */ #define I_MAP_SLOTS 4 /* max # of blocks in the inode bit map */ #define ZMAP_SLOTS 6 /* max # of blocks in the zone bit map */ #define NR_INODES 32 /* # slots in "in core" inode table */ #define NR_SUPERS 5 /* # slots in super block table */ #define NAME_SIZE 14 /* # bytes in a directory component */ #ifdef i8088 #define FS_STACK_BYTES 512 /* size of file system stack */ #endif #ifdef ATARI_ST #define FS_STACK_BYTES 2048 /* size of file system stack */ #endif /* Miscellaneous constants */ #define SUPER_MAGIC 0x137F /* magic number contained in super-block */ #define SU_UID (uid) 0 /* super_user's uid */ #define SYS