jkp@sauna.hut.fi (Jyrki Kuoppala) (02/21/91)
In article <9102191835.AA07256@lev.seri.gov>, sverre@lev (Sverre Froyen) writes: In article <9102191835.AA07256@lev.seri.gov>, sverre@lev (Sverre Froyen) writes: >Couple of bugs in Minix 1.5/1.3 that appeared: > >Pipes fail intermittently! This caused the yinstall.sh script >to fail and may be the cause of the failure of GNU diff3. >My guess is that this is a kernel bug since I have seen it under >shell, bash, and diff3 (both with Minix stdio and with Estdio). Kludge fix: Change #define PIPE_SIZE (NR_DZONE_NUM*BLOCK_SIZE) /* pipe size in bytes */ to #define PIPE_SIZE (NR_DZONE_NUM*BLOCK_SIZE*8) /* pipe size in bytes */ in fs/const.h and recompile the kernel. Works fine for me. While you're at it, also change: #define MAX_STACK_GROWTH_PGS 16 to #define MAX_STACK_GROWTH_PGS 1000 in kernel-1.3/alloc_32k.c, you'll need it when linking GNU emacs with GNU ld (alloca doesn't work for anything bigger than a few bytes or so with the original definition). What the hell, here's all of my kernel diffs so far, they're supposed to add non-blocking IO on ttys and fix some bugs. Don't trust them or ask me why they won't work for you or why they're so ugly ;-), they just happen to work for me and might be useful for someone. More kernel diffs like those for ptys, TCP/IP, host-to-host scsi device etc., and bug fixes to these are welcome, however. You should also add FIONREAD to libc, I don't have the lib diffs at hand now. And one more of those nice limits you'll want to fix is the exec-family maximum argv / environment size - should be easy to find somewhere in libc, don't have it handy now. PS. There's some of my backup stuff in nic.funet.fi:pub/misc/pc532/jkp-backups/1.5 for the 1.5 kernel. No GNU binaries yet, but perhaps soon. Bad news, many of the GNU binaries for 1.3 don't work with the 1.5 kernel because a bit different mechanism is used. diff -cr orig-1.5.10/fs/const.h kernel/fs/const.h *** orig-1.5.10/fs/const.h Fri Feb 15 13:31:52 1991 --- kernel/fs/const.h Sun Feb 17 02:23:18 1991 *************** *** 53,59 **** #define NR_INDIRECTS (BLOCK_SIZE/ZONE_NUM_SIZE) /* # zones/indir block */ #define INTS_PER_BLOCK (BLOCK_SIZE/sizeof(int)) /* # integers/block */ #define SUPER_SIZE sizeof(struct super_block) /* super_block size */ ! #define PIPE_SIZE (NR_DZONE_NUM*BLOCK_SIZE) /* pipe size in bytes */ #define MAX_ZONES (NR_DZONE_NUM+NR_INDIRECTS+(long)NR_INDIRECTS*NR_INDIRECTS) /* max zones in a file */ #if (MACHINE == PC532) --- 53,59 ---- #define NR_INDIRECTS (BLOCK_SIZE/ZONE_NUM_SIZE) /* # zones/indir block */ #define INTS_PER_BLOCK (BLOCK_SIZE/sizeof(int)) /* # integers/block */ #define SUPER_SIZE sizeof(struct super_block) /* super_block size */ ! #define PIPE_SIZE (NR_DZONE_NUM*BLOCK_SIZE*8) /* pipe size in bytes */ #define MAX_ZONES (NR_DZONE_NUM+NR_INDIRECTS+(long)NR_INDIRECTS*NR_INDIRECTS) /* max zones in a file */ #if (MACHINE == PC532) diff -cr orig-1.5.10/fs/device.c kernel/fs/device.c *** orig-1.5.10/fs/device.c Fri Feb 15 13:31:54 1991 --- kernel/fs/device.c Sun Feb 17 17:10:13 1991 *************** *** 194,199 **** --- 194,202 ---- */ int task_nr, major_device; + register struct fproc *fp; /* jkp */ + + fp = &fproc[ mess_ptr->PROC_NR ]; /* jkp */ if (fp->fs_tty == 0) { mess_ptr->DEVICE = NULL_DEV; diff -cr orig-1.5.10/fs/open.c kernel/fs/open.c *** orig-1.5.10/fs/open.c Fri Feb 15 13:31:57 1991 --- kernel/fs/open.c Sun Feb 17 16:44:28 1991 *************** *** 262,269 **** */ if (find_filp(rip, bits & W_BIT ? R_BIT : W_BIT) == NIL_FILP) { ! if (oflags & O_NONBLOCK) return(bits & W_BIT ? ENXIO : OK); ! suspend(XOPEN); /* suspend caller */ } else if (susp_count > 0) {/* revive blocked processes */ release(rip, OPEN, susp_count); release(rip, CREAT, susp_count); --- 262,272 ---- */ if (find_filp(rip, bits & W_BIT ? R_BIT : W_BIT) == NIL_FILP) { ! if (oflags & O_NONBLOCK) { ! if (bits & W_BIT) ! return ENXIO ; ! } else ! suspend(XOPEN); /* suspend caller */ } else if (susp_count > 0) {/* revive blocked processes */ release(rip, OPEN, susp_count); release(rip, CREAT, susp_count); diff -cr orig-1.5.10/kernel-1.3/alloc_32k.c kernel/kernel-1.3/alloc_32k.c *** orig-1.5.10/kernel-1.3/alloc_32k.c Fri Feb 15 13:32:43 1991 --- kernel/kernel-1.3/alloc_32k.c Sun Feb 17 17:34:01 1991 *************** *** 61,67 **** #include "proc.h" #include <minix/mmu.h> ! #define MAX_STACK_GROWTH_PGS 16 extern char end[]; /* end of data segment, symbol created by ld */ static long first_page_adr; --- 61,67 ---- #include "proc.h" #include <minix/mmu.h> ! #define MAX_STACK_GROWTH_PGS 1000 extern char end[]; /* end of data segment, symbol created by ld */ static long first_page_adr; diff -cr orig-1.5.10/kernel-1.3/tty.c kernel/kernel-1.3/tty.c *** orig-1.5.10/kernel-1.3/tty.c Fri Feb 15 13:32:54 1991 --- kernel/kernel-1.3/tty.c Sun Feb 17 19:22:06 1991 *************** *** 428,433 **** --- 428,435 ---- { /* A process wants to read from a terminal. */ + int code; + if (tp->tty_inleft > 0) { /* if someone else is hanging, give up */ tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EIO); return; *************** *** 440,446 **** tp->tty_inleft = m_ptr->COUNT; /* Try to get chars. This call either gets enough, or gets nothing. */ ! tty_reply(TASK_REPLY, m_ptr->m_source, (int) tp->tty_inproc, rd_chars(tp)); } --- 442,453 ---- tp->tty_inleft = m_ptr->COUNT; /* Try to get chars. This call either gets enough, or gets nothing. */ ! code = rd_chars(tp); ! if (code == SUSPEND && m_ptr->TTY_FLAGS) { /* hja */ ! code = EAGAIN; /* NONBLOCK */ ! tp->tty_inleft = 0; ! } ! tty_reply(TASK_REPLY, m_ptr->m_source, (int) tp->tty_inproc, code); } *************** *** 613,620 **** * Oops, even bitmapped terminals need suspension after an XOFF. */ if (tp->tty_outleft > 0) { tty_reply(TASK_REPLY, (int) tp->tty_otcaller, (int) tp->tty_outproc, ! SUSPEND); tp->tty_waiting = SUSPENDED; } } --- 620,630 ---- * Oops, even bitmapped terminals need suspension after an XOFF. */ if (tp->tty_outleft > 0) { + int code; + if (m_ptr->TTY_FLAGS) code = EAGAIN; /* hja */ + else code = SUSPEND; tty_reply(TASK_REPLY, (int) tp->tty_otcaller, (int) tp->tty_outproc, ! code); tp->tty_waiting = SUSPENDED; } } *************** *** 714,719 **** --- 724,738 ---- /* Discard current input and output. */ tty_icancel(tp); tty_ocancel(tp); + break; + #endif + #ifdef FIONREAD + case FIONREAD: + r = tp->tty_mode & (CBREAK | RAW); + if (tp->tty_lfct > 0 || (r != 0 && tp->tty_incount > 0)) + flags = tp->tty_incount; + else flags = 0; + r = OK; break; #endif } Real fix for the pipes (I haven't tested this): From: kevin@nuchat.UUCP (Kevin Brown) Newsgroups: comp.os.minix Subject: Fix to Minix pipes (1.5.10)... Message-ID: <1991Jan15.194514.3841@menudo.uh.edu> Date: 15 Jan 91 19:45:14 GMT Reply-To: kevin@nuchat.UUCP (Kevin Brown) Organization: Teenage Mutant Ninja NiceGuys [tm] :-) Lines: 288 When playing with GNU tar, I discovered that Minix pipes have an arbitrary limit of how much you can write to them using the write() system call (and, it turns out, how much you can read from them). Needless to say, this limit should not exist at all (it doesn't on any Unix I've ever played with. On most versions of Unix, large writes to pipes are just blocked). So instead of fixing GNU tar to work with this arbitrary limit, I decided to fix Minix itself. The following patch reflects the changes I made. UUdecode the following, and then decompress it. This will give you a file, pipe.patch, which you should apply by moving it to the directory containing your fs source code and doing a "patch <pipe.patch". Be sure to save the originals somewhere, just in case (I did enclose most of the changes in an #ifdef/ #endif pair. You can define WIMPY_PIPES if you don't want most of my patches to be compiled, though the field additions to the fproc structure will still be there. See the comments I put in there for an explanation). These changes have NOT been extensively tested, so be sure to keep your current Minix image around in case it acts up on you! I had some strange problems, but I think I've fixed them (you have to treat MM's requests differently from that of other processes. Sigh. Since the file system is a Minix process, and is SUPPOSED to be "generic", it shouldn't have to treat MM's requests any differently from anyone else's). There were a couple of times I was REAL WORRIED about the consistency of my file systems on my hard drive in testing the previous versions of this thing. :-) Right now, it seems to be stable. Either way, though, I would NOT recommend trying out this code on your hard disk without making sure it works properly on a floppy-based system or, better yet, the RAMdisk. This is easy to test: make a root file system on a floppy and tell the menu that it's your root file system. If you have shoelace, then ask someone how to test the kernel in floppy mode only. I don't use shoelace, so I don't really know... If anyone sees any fatal flaws in my logic, please notify me immediately (preferably by posting a message to this newsgroup)! The way it works is this: The file system's main loop looks through the list of processes for one that has been suspended (i.e. had not finished servicing a system call when the resource being used ran out. This manifests itself mainly in writes to or reads from a pipe). If it finds one, it simply repeats the same system call that had previously been made, but with fewer bytes left to process (the part of the message that contains how many bytes to process, nbytes, is modified by the system call code itself, so this value always reflects how much work, if any, is left). I have added two fields to the file system process structure. One keeps track of how many bytes were originally requested, and how many are actually left to process. This was necessary to insure that do_read() and do_write() will return the proper values for large reads/writes dealing with pipes. So let's say we're writing to a pipe, and we want to write 10000 bytes. Well, the pipe size itself is only 7168 bytes, so we have to break the write up into multiple writes of at most 7168 bytes each. This is done in do_read() and do_write(). These two routines had originally just called read_write() with the appropriate flag (read or write). They now do the following: * Check to see if the file being operated on is a pipe. If not, then just call read_write() with the appropriate flag and return the appropriate result. * Otherwise, check to see if the amount of work to do is less than the size of the pipe. If so, then just call read_write() with the appropriate flag and return the appropriate result. * Otherwise, we have a request that's bigger than the pipe proper, so we loop, calling read_write() with nbytes of at most PIPE_SIZE bytes. Each time we go through the loop, we decrement the amount of work left to do by the file system by the amount read or written as a result of the call to read_write(). Now, the reason I added the two new fields to the process structure in fs is so that if you try to request a large data transfer to/from a pipe, the proper number of bytes that have actually been processed will be returned to the caller. Since read_write() and everything that read_write() calls depends on nbytes, which is basically a global associated with the given process, we can't store the large value there because read_write() doesn't like large values for nbytes when dealing with pipes. So we keep track of how much work we actually have to do, and how much work was requested, by keeping those values in the process structure itself. This is guaranteed to work, because the process' request will be repeatedly invoked until the system call is done (either because the work is finished or because of an error). GNU tar is happy now, and so I'm happy now. At least until I find that there's some nasty and subtle bug in my code...:-) So here's the compressed and uuencoded patch file. Enjoy! -- Kevin Brown Addresses in preferred order: csci31f7@cl.uh.edu nuchat!kevin@uunet.uu.net table !"#$%&'()*+,-./0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ begin 644 pipe.patch.Z M'YV-*@*">,.&S(LQ;]S,H>,"30(J=<J 4!+@8-2[.T#$CA@X8,2[FR!%#z M08N3(! J9.@0HD2*%C%JY.A1!@V1)!4$W,FSIPJ= F^PB#$#!$\%($",(%/&y M3!HW$IU(^9+$R1,B1:8DW<IUAHP$+U0H!3&'S1LZ<T \!2%B+4(Y942H=?.&x M*0@Z8<2PD:CB!5*E3)U"!2'URY0J4(I(T<JU<0VP8D>0-8MV+MDZ<,K( :'Ww MS9@U=_/N->HWJ8(0@)L^E6ADBF$J088L^2(D"Y6L25'(N"'#*-DT>LJ\,0,"v MQ1@T83:K2)$"1-C?P0<2=SIZ3IZ%9=J0Q?N9]-^_SYNDF3.F#!LV%8772:MRu M8<7*??\N53WX<.*I38(<23)D*PP\1-U@!&0@M!'&&6F, 8(;=;0AAF8I)837t M:F18-@=FFK7067?QG=0""$(1!8*'+<@7V&J$35755;@UMI57!$I6UEEIK=66s M16_%-5==$N&E%U^EI2985%/9IQAC+B;UV',R4E:C11=FMMF&H/DX6GRFH3;?r MD""T]EILL]5V&V,HQ "#3;[- 9QPQ!F'G'+,.2>6FM$-!P)U$EF'G7;N<1@Dq M>&*)1YYYZ$'UQGH1KO1>6E@*B:*1^.G'GW\ SB @@08BJ""##D*HTH105;A6p ME!E2Z9U/J 8$E%@TQ, "#388M9-)*+7Z*@XC>F@B?1)59<0320;[U7-WH*&9o M1&N1$09>7[PAQQEJ/6G&&W?*\89V8M211D'>);4EBD4X0<073QCQA1%),%%$n M8RV820.!;(+ %!UEC$%OA8TJL(*C@QDQ;GY3+)% C#<< .F8>!QY[82,46>m M'&G 08>ST8)@0U'Q[0LH"$1HEH8=951(9QF,!OGM8%H\X4017SA111.&):'%l MNEN-/!P*>B14QA=NR)%" HTQR5D>]#X)0LZ#]9Q4HR<3^041*:_<\LN-H5!8k MU"R[W,04+<CP<]"1':VST4_QR%5\.PU4T MFP&'M& T]%-%$%5V4$5$T?112j M#".5Y.&=;GL6MTMTQW3W1C/ H$,-.>!44JJHK@J"##*PL)NLJOY-^:LPY'K2i M7TD=EQS@7^ UQQH[#$Q@L0FB$=KI%0>NX(5S9.8&4Q4FU.U63]%!.AQID)'Zh MP,_)3G*-^ :95.^_GR$'',,3:/P<:3E_*!S>:;SO<U08>R=!9MWQ%+1TW$&Mg M4^:1D59R$JT7LF5T>"^"@<=1"WQF<J71!AQ[M5&&&WBA0QH2P@+.U($.^EH:f M")(@KX2<P'?_&X-9YM C8VEG+74;01K,<+NF@. *26@"%++P!2@D(3%:>= 8e MPN"^XH2A.7DXU DJA!R0)= W$P,!7+*UK0K%3R+_$R!<0+ &S4"%#6HA3@SKd M (([O.=].12=&\Y008G<KPPW%(O^^)>=("YK@&XH8$4JA (Q-,=]FPF<\\+0c MAK3$;UGR*H/M<F>1^(UG.W*H@[WJ )<"EL$%9W!!%D$ ASD4T'QUX%8->T2Mb M!T5H?PRKD/CB=Q?OS8&-$@&A"$EH0A3&43!I$*#NPC"'0;[1=W;Z(1&-:!X0a MU*&#FV'=<=3BNSM&"0YOH* /J95'-[@@*=U;U@G<^ 9JM4&/:!BD^>2PA@+.z M@5H,# ,;G'B=N4BP#G91Y;3.\P;Q3?$NYEM8^M)2K#+\<#,_S,,)AAB&/4J3y M#7D8I/MRMQFZ,"2+?MG7\@"8E+:5[BS2% /12#:\YTP,+T@4:-'N0BTRG(]Bx M=DS+&Z3T1=UEC'?\))U"2;87,]"AH&+9:%HZZKL<.O1[Z$3#'2>JF8I:Y*)_w MZ0/@WK:%PD!!"D\8PA2ZL(/O).4Y1DA#^D!@!VE&9 Z_1)M "&*0,YAE<'.#v MB=UFTA&].8Y6'W+J&Z#ZDKK)!&^)6USC^)83R/E$<F8:2D:.\K>TQB!6)/I+u M$;!P&RDX82Z^<R@ OP 7_N4!I MREH'.DP<0P& '9#$G0R^RV*>H5 RAU*$<t MX;F[N=;UKLRC'1R^@)!7?I1X8N'4@S9C)]FE1;/_P]U +'+%RM)5,9CE)USLs M\+'Q 5:T$"IMQ*SXMN.1;+&.G.W'WG=1R\(6KPLJPQTX^T[ AF2#R;T#6:Y#r M+^VL\#Q^9 ,%#>O:RTK'#*73H;*,109<S@&PY@TE&!<+ES!4* S&<F]WC[N0q M/-IK1W91@1S&&[(OE(TIJ2O>&WH'H1S^EY&2E2]\RR#?1AG7KBEYTYWZM(8Mp M>&D*L)$-;6R3%9X22)5!'<T4J)N=86ZGG6M(JE_2QM07&.@I+AB#W+IJ.*IZo M!"17_=N+?2ECPDGUJXA3'..N:M:>2"YQ+)A!K(Z2E%])X0I!D (1B#K@"F4+n MO+@D" I2T-,F/^')49ZR':H\8?^Z(91;[G*7O@QE*5,Y>""@(AV^((9BSAD.m MR<$DO>0PAS2?9LU@=O.8X2SG+RQS#7[V<J"GS!0[A-<L[N4K&Q,-Z#:+F<R0l M)L,72"4'2F,5!$A6LN=*I&A+O]G*=<!R,=E :2>;>M 5,L,<S(QF+O_%U6$^k M=9S-26<[?P'/<M"S9OIL:]3@VLW,*_2A6\WF7#?ZT6^(=+#;P.Q%ZSK3F\90j MIVUMFB(?)6TVJ)P-<,5D$(!.3B#HWAWOJ,H=@\ L$ZTD'.5,3F<UDY"]I=YOi M0RG&VR7V=FGI*QN$BM3=)85UHT$!%:10A2(T9P]_3H"R[9UFT":V,L6BUAC+h M?%TDYBLI"6@;"'H A.TC:89][" "8Q.^[TM-#_"HQY]UZ@$</H+:!QY<=K6g M A_XLREFT%:%>D#RPWRA"DF8\@_2S?!UZ:!+06#"%!R.V)_.J0Y+[Q!*PLV"f M<8_:IUOAGDIKY$;ON1O>V#OEKC%N[P).CX(UHD._19;:@$^6X"H^-\(EHO"Fe M/SSB4%ENQW4^<696G$ 4Q#@:-.YO63/W/+O[2\BQ1W*3RVX+*0^P6'#)\L7*d M#N;5H8-]:1XDFVL;YQ3<#,E1P'.?;Q;H0A]YT:MP]*2#8.D+;S@(GFZ$J$^=c MRV&_>M97[&U5I0T'-6!!#FY2[K 0_?G0C[[TIT_]ZEO_^M;_R594H#J)\_K0b MW6^,]I>&_?*;__SHCWY\4'/3)%@A"+?1=>$1G8(_[R%+P2>,8-]96"=&=EKUa MI%QS 0<']$L@@ 3=5 8@(P<%!%WKI("U-44G$"U_MGV!Y0;!82UB=!FUDUKOz M\W8%LAZ^XTAAX$1%%"J")'Y_PA5P@2#8L1GU-7,SY1E&\3P]]3?(IWP9$5=6y MEWX^^(- V /C9Q3=-W_A=S:@HP)!N(1,6'WK!P+M]W[QEVS?1W'UAQKW9VZHx M877Z)P>#15G^YSL &%T#6(!)@8!WH(":T8#$\8"T15L22(%;J$!T@8&:\08;w MB%H=5"$@>$P+P1D248)A<((A8X!28$Y\I!",M4$5J$!I*%GE,5SO52#'<R!Ev M4$ 4DX'4 EV/*%P@,XEOEX)GLX);T8+CL6<R=U\G1X/Z!3VKXFUH!0/)%P.Tu MB#GCISK/TW/^I(>J17)6006&4053D!CB4@1$@%AA01?OEA!4M!G(,47C4W,#t MDXNNQU<0^(DZ]XM?( 5%8 7N5Q5'H&:X>(WC<Q(]A1KC2 >)*(X)T >2AV=Gs M-@8H( +S%R&)1 9N\$"2]8:!Z 8Q!!4B4$!6,35-P&U;X8YM!0,V,!0QT!L\r M" *X" >ZN%F\^#Z^^ 3 >!C#&"Y8<8QRHHQF,440\HP(,D72F #4Z$^>:)&$q M@9';V(W?Z 3A*'G32(Y39(X15Y/J* <6@0(P8) #XXX@!X\),H_UV%D%D8^^p MLY(@4!'_&!<"^00$:9!)X8[%9WP"08NS* .=PU8H08L+V9 .J2NFP149IW-Mo MX )ML&F'(@?EH6;]-&N#1W)IN99TD >9T5/Z)%D[V9,Q8)!":6[=ME1KTUYDn M$&,S5CA3!58WUAMDY3<H89B(Z6->=3AY P.=\YBO6&22(P.N(@/D-BO>\A37m M9!<B &QLU! B(!^DR0;8)!$BP&FJ^1T?TC1=\B]!$##!DA0%<S#/82 *@R=Ql M]# 1,S&;<4<7XQT?\A=1"'_KXC_48XFN!)WG97'4*9UC2$IK,#X@, 59@&&Yk MN00HY4JI%R%P4%@?5VFYQCQR('AH\$KT=X,HX9F6 U>Z<I4_D39>D62AJ2K;j MUX0 &J"- @55( 1,,"G,XU#6Z%Y;]A<0-X=PT9<H8)B&!C'T@@+<& 1$ ([,i MH6:!29LH@61O=1,/:10!>J)+.* %>J#]D:!OL*!DT*!)\:!:J!0;U$'$H4DCh M5$(GE!4$0@3&U$Z+1TB[E1:OM!?4PU#<<A;&TI[C 22-&(/W=6 U&#'G6#.Bg M)X/4@3TJ8 97FA2F^(+(-3)?*EDNB(JB(P=BT09Y<&57VHC/<07'0DN!)880f MY3UFT$XEA1R^<T5IL4A-"1T2,7!MP&]-Z6_Q@RB(5!"-Z!MTX87\QY>)" )%e M8 1"D 1'D$25)!%N(%*$E&?^@XII.$030RWH\2R7V$02L:ADT*ABH08BF!+Od ME&":=@<66@9;=JA6UC ZTT2AY#JA9(!5X 8 J(Y/!$]N5Z0-Y*H@ *AJ5Q%Tc MD0?<^2 U-$ ,2!;4\H@(L3__<TGT,IZ1U:1_Y*I^@1IP*A9!Q6>^HZW&TATYb M1$'(0ARA9&+MEAW.4E@&X@:6F%+"Q![OQ)WK(4ASZ!M)0!S/5$ _9!&/"*M_a MB&=)JH9R0#0J]4W2Q(SLQ6"U>JM;=D@J=1S,BA=%Y*]#9"=-T 3C&;!)(:=-z M23T-(A$EVT0.Y#LMY*<N4+/D^F>-"%TH<)9$!P(E6T(X-00M(P57")$1.JD3y MBK$5&DI\EZ$;*I,=BK-S*';_HZH15B]50BWPJJD153':E ;J>A?ZLZIE< (@x M XA5VW'O X ?.W:2%0='Q1!)4;!T.AX(:RP*BRQG)D#2M":;*JA$952_-88_w MQ*RAF!1/<$[B0T&'-*@,=K9V-$7K$Y+C.K!/F+-M$GB/QP9_AXXCHW.=.E#Gv M%7&MYT\'%5"BJW-D2KH268TB15*JNR9EZH[F.K5BX03=9+5R]K=;JJM_2Z6<u M!T":88!TFX8/6*<-Q)UA0*29P0)M6[4+&ZN#1Z&VRK1;1KS$8;Q#](QD,' 4t MR[RI&C^'<@9HX+R6NZEYVZQA +G4(GH,5DN^0TJ!VH%CD ;2)*L4)+"C*+6\s MTR8[1WB\MJ6L1P9QTK-.D"[GDBY0T!Q'RY/%H1ERP%D\4FS]6QPA@ *LIXO;r MLEEEDP(]EP:_MEO,$7$-W)/4J[%.RZ$4S+]<B+O2Q:Y8NUA;"UVJQ$:'PD]Vq M<F@# 3$E&:EP ;<D<R^R:A$/PJQ!QP;4L1>2]*NK)1&#ET,G;+TI,'>:>K!6p MR["^TW',&L47VAP;5\+ZNWWE6J/+TR:ENUFGRP:>R@,DUTDL,P4RXW @0*-_o MID%F$!@<4P1"4 5'$'%NTSMM(@(*:IA;]G2&R9TE8&6IFQ#E4;,NP 5N$) +n M(E(4G !_#$"!C )I[*DDE\@I ,F2?,;_A%"4?*4CD%J,6+M&BX@.G+215KT7m MFL)0N\)S2+MDC&Y!L*=W%+QRIZIF"T3NH1?C05[RMJZKNBU(Y*R-U%Z@@1F;l MNL5E ,1_V#L:YSM[04HE%4[ AA8&* 0'5$EWY#\5479PI$JM-1Y*R:R0!2W_k M,[ZNDT/<.QK:E$A(],-Q:X!R>KQG4 =Y)KQ0U$AFT1VOQ!1RT+:YY,0)00;Jj ME1"&A*V:*I56X00&FE/BZ42GE1GUBSZ2)!%8+*D.7 3Z$015$<9+,\:8NW,:i MS :;90;H<09I80(@ -$J,]&R4;0HR<H]"=)'(-).0,OYAP3'0J_R(\YT(!>Ih MY#W2= ;.\JMIF12Y#,YIP<N-^\L)-G#!X4-\RJS:*Q%*S9WORC^1Y<RJ=&@&g MV#T2X11A&[G0\H@G94OK&XC4]+PIP4=PP4^\#"%79@804D;UPD+;]8CB WDMf M%%D&IA!\5$'E;"S0?+]Y#2%W?9RGI5C.'#A20EEKP6"SQ+3!)DIND (D[1USe MR*97IG-NDAS+T=AR\*:VJW\O/*C%A#V>M2V;"A<FIHQMX"RK:F_ Q:M0D7=Sd MN'<[U[K^]+I-X3L^8%B="Y&ANU"K)\K$[5$@<-QN'#,STQQ+-]UP/#.[!S@3c M26>B2U*FO$%XC!5[W,?H>,ET$,B#C+&%'%C2=<C?E,A#4S2.#,H%M-PD0\&Gb M?#NI#)&?2W)<C*NR? 0^32#Y?+8&DDW>8\]!?+&OK+&>G;)\:K4G90;6HAWBa M&G&^P11S)%%UM. X';BN2;9Q=A;8^[<E+.)S,QX:+A9(2LX6H8EW"[U<?1:'z M"@(0["Q4W+5W5"QPU(DXW>*+I4IJ*P<G_HA*';]'<X<SGKXIOGAIN( %XI1"y M[JG(L:M5^W90])YID:>;@0+KP<^$%:B:2(GC7,Q";L[Y1D[(#(B<$=!%1 ;.x MU+[>4U0C;K4I'M@)A47HB$-H8"UW8!&"6%AKH78KQ+@&I.1E+DW/9.:*J'9Cw M?:L%W>=B@1SL,4%;;D6[Y;NSJDK*@A?PXSVM=>5-R0:&&4^4CK86(9E)T00,v M=F;?]*Q+;BU#7.J-+LX6403ELEI_>T6>+>3%6^-*GEX"=+9V'A%-;K5.H3"Ju MA-J$-&#"VW)"SLM#CJ=@^X<;5<SJ.P=*J>KXYAF^52%Y8$YS)^1*S1DH5NV,t M! ?Z"S27BXXZ^[D\@-QS7,?B[4'DS<<YB=[J_:*$G )/E^.;8<@XC<AD8-^"s MJM^H; 8YF>(H,#*5;,L1]QRZ;@0[S(&VHR:Z4UIKCL^\K8\KU$=7'*LE+.10r M'H*SI,/&>[9ZE2?GDQSM#MH0&>]^V[,_V? ASGK"C<8 I<:I^R'._=W%7>#/q M<00VOKS$/EPJ'J^ZJUA=Z^5SKNQIH#!BK=BI[NR/;1EN(T=YQMGCJ4I0@0?Pp MVU*<'?-/F #.3I=MFFH@L"^KBXZBS?8DA]JSR\+H-@6D2>(K1,1YLAYS]#X8o M!'D1U;CJR[YN?B%P\;&\%.(U[$Y(A%ND11R>VO((V_,&&/1%0U+,&LX588F*n M3*M+V\51S]8Q6_@(=E).J=:-=4^6.\9V/-YZK.]SR._%(<C^SMX #P*'V)<&m M/]^_99C5<BW@^\B17$"-RMW5N,D_C_S#+?0>I?#\S? 0FO.BK/P+!?0[[]V9l M/_2JK13FL5W/(01E *@#5T1_N]0]C$3KS:!>[&\=/;U*"\NX&N%/Z/ !CJ$@k M_;0$#OT*31QQ&D([RHUIA4;QH093\9$<(V$HR");=&YDRO>3"! 'Y.BL]O0%j M6-J!D#T?1 HD 2H CDH.3*,2FP:C8<"?5.] #H$8 NT*-& 0,E!4W$!YD&%Ei M@.D))ST79P =0VDD:2"0R+R!H;.2GNXX;H6&TTRHB/'!OD"C\6 ^8-8 ITWCh MMSX$?DL+]<<$WC0)5:DN%8%3,S3I.1R'&#:&I%(0@ +$:,I80&BA=3X$Y4@^g M,J C?!VNX "U"P24/!-PN8Q!#'@%-" 'E$D>\,UYAC40 NO%"/P[)O YH, 8f MM@);X M\5S%04\W -F<]I$NIX@PYT+=!I 30 W/)0K,(0)#7"$&(T;I V!'Le M.4HP83#!Z. $*1E-FH*)" 5404QED+*@6-B"W:$+?H$O& ;O1$L[%5<)K<P d M'# 4: #&F!6:PP;0 ,O!&];@)'P.50 .?#J$YEF&C>]Z; 5'&CF[%4!RC@-\c MTCSD":^E&KVV&=P+&8 +24H:/<$140W?DQM '03"4XV[DM)() +PNRAV#$=]b M$ #(27K4%$@@ P/S<93B1@XCS#5,AZEK'>XV6E7Y$$KV\'[1CR:-@0;A7Z@%a M-?2'YQ ;>BK@U^B\W.X8&#[0(CQ$:Q@1I8<E]'J39&+Q+H9Q$:T283((\F\Rz M197*9&,^@F/J&Y\F)?:8E5AC&--'R$PP$3\AP*'0GW["W\@!EB,DE*CTI$%<y MH&LR3;)F-NV+HEB:) (/, -C ("P@8;@ Q((4SR*3K%0G1D\<!"N!55D34;Qx M-;&%*S.;1E-81(H,HRS:J+,(FU81W$ #J\DL-D6V<&"4XEJ<BZ<)5*G%JR@6w M8Y.V48NWIMD@&WXB_[Z @8 #?D8GIHW-(0,:1[DQ42@J,J8?%66@$!0_45#Rv M3T;5.]3P'*" 9@! VB'26:\[5D!0VWVC9--E3\BJ\R )P11.<V49RWK5P0VHu MPCP4V/DT,F 6#9FA*!E[H_FAC"P*N6!&".>@^%<\Q&,ZJAZBD!\5I.H'^#)2t M;N#%*:G<H;B>E,Q+"E*JEM"%_,()RU1V7!@JS2AXJ484IE!19I%=Y+$,G"E/s M\2;6U-H;CZJ,"\FI(1)9[,G7PU-Z2MOY*=,WO_P6H3)4&R=1U9M[Q*P>U1<Jr M+"EN%68J&N8]QB%J"E408E0Q$E.5'*@(X6-5S.K]S:K[U_YV50,9#"&1E@@Kq M8N4LC)7P0E;/<5F=+V<UX:#5&Y!6WX1:K2]K-?H0&K=2",OBK%&,<'4L/MN[p MRS_IZ@_!,'>EM1(A=)E794<B^(_;%K&FG+YJ1L7,Q'0<@(54F!7=LF():^0Uo M+%*2%B"6Q%)>(8E\++X')\4X5NOX6(/HMX0\B4"R3-880ED?)!"Q+/_ALTR6n M^>AV,ZM(.;*;%1\UU<X:4CWK9]V4G#*T;)K]BW^WJCC,QCNX_[H?%S)KZ0L6m M9JW$PO1X7))<&&EM;/FRL_4@TM8[65O.HFW=$0:W$$Y<9+%;Z,MJ/07UTK>Bl M@RKY7,=N<-TI/G<VOEUYH!X&*'$UJ<65JA[1-8-<$\NEE3J=X2--VAS269JKk MXR0WFU/S)IGHNE*3I[M9O]]"<MX>1-*'98$?5DOT6,OLWG-P84UO3YVU#>:[j M5 GP@G9[YLB5K2%B'QV*\@)?YJM69LGH]8?@'YGL8NKR>,6S=WE%[I8[BY<6i M:%Y*!&5V%]H+_%I9\PNCV2\D<N@JU_[JDSKK?Y&<0B/ [E@!\T4(#%TP@07Fh MT7H2!)-@3(&"E3$+AL',0$KC8'0!"8(P7V<H<][]6Y2UD7^=*]9FM20E#*R4g M2.VV>1;I +.8R0[+@4_!AT6SN/4^]AX@,F*))(F]CQ#9JY[8F(R-HL]W01<Kf M1B^SV#M9;%!S_ODN,,8G;YG.JGX];XVUL1Y%W>08'=,2]XXXY#OS!I%HWSP:e MCE+LZ<"RWN>I&-D?J5D([PE6,K<I C19V$Q=G8R (3RP2<I$%__K;R3,92)*d MV6@'8V:?E'BK[:EU+:FV*8&9E1AF6^[''3/(0S#% #-S)6G'ZM5*4JD=<P@<c MN69_J'S8C^3 S9*"-]-E:0'7D3-Q";ZB13H[7^L,Q]&%.D"^%DL\JR)W@IZ]b MK7N6LM8E5^-GP<:?[1(]*-!@B4';+BI!H7&VAM;HH(M,DVA,@*(U$?E%OS:(a M4-EH(*"C)<B0-M*ZYDG+8#YG@U7 EO;28EK+F&G9LZ8ESKY4''0:3_-I7 BHz MT;9+.3_>EU$C#C6,#2@U"X4&FAH(D)QNBW*N/'?(8*Q:YD0@YVNKE3BOIK7 y MFLP*G;F-F90U:Y?6@B6%VT2GY:TUI;AVOH@<70LBSZ[S.#N^MD):"&!K<X.-x M'<X%Q(?8Q.5B2RC;T+&A2PAA2R0;]J!LFL&R603,!JSVC$OY=:VO$<4]XK!Zw MTM1IRZ&IS5O>KMSE*U^;*P$@LNV<E*VT8-MP6\^<E(ZDY;7&)J)2$@ZVA%W'v MC032J 0P#IM;]GMNQ@T*D<WL)L>NVQR-8]OMC!:W\';'\%WL8YN6#&)@LMH'u M-[O8TZ$++\Q"T4W15=^*G[,L&H=3^OFW9ODR&R?4ZGX&KFPA./<"/$FG@\N:t MUTO":<X&$OPPW+$0<ARN[O Z59+B8J7N,G%S"X""./KI2EE<JI..;R3&,;E4s MB>2.WA"5 ];B6@5(M]7C)AR0ZTMICLXYL4]IY&+I*U5TNU1@=LQFE8"D7+Y"r M=1#)-U@Y^=(I6<N:VW*(PB*"N0L1J997F9.=:"[5J3EPEZ1HH".A$B$CZJD2q M5WI,)Y4[I97NKI( .D%'34(='&F8I?&;F=,[9.N,R:N;G7]+_DVZ;%KIY)<$p M.6A83=-E!DXG^+S'IUM>A4[4;3I2)TU.796+@:L.8QD@5U<1O%J+G'74PF@Ro M.H-:-RK>*M6HF0&),M0%DKV$7:!*>L9.<"6[1[3L_A;6VZ'2+M51NQSRM<)6n MME,[EJ[;=5-;&>Y P#HL=ZGNW(F!=$=4O<?$8'<MSEC.O#8A[^@=C7I]?K2\m M[3M!FMX(Z8O*C+E/X&VW$F;P$![$,V4+#^?1SX>W)B(>_R(0+I5BZ"&-9Q$Xl M'CLM.''R0X(\]D'XQ&>02W4G[YBD/-VV0#^DR[L3,"^K1AR:%QULGDU#A:V,k M<**NZ\?\-@L<)7IBP>@-NX^H]&II35T[4 VR7JM&QU.G'NA\9E</BJ;0:*?Uj M^DK76R^$JT&6 ;%'2\@>&#%[8PSMR5:U-]K<'K>$2$M4Y]"]1@0Y\P_><X%Zi MKVXXDHHD*@1=1465CZAS]KW$5T(7'_UL?,;J\36(T<(S)Y_.*(C2Y/*]4><'h M06LEYWN2[T.@@#ZT6B,%J^\@F*C/'ZD^ \/Z'J:-ZJ-J\X\V(KY92.??T]E]g MB6B1+A181B_JB/W8+<1/DAT_S>KS.*L>?7YP-2%.O[E*83T5]NMNG[7[G3(Wf MB&[$'_E+ ^9/E:"_H*G^SBJ$\UT:$O)P2$EX*.\EKH*9LRS#]C]TDQQYE"<Ae #@+<1d c end -- Kevin Brown Addresses in preferred order: csci31f7@cl.uh.edu nuchat!kevin@uunet.uu.net //Jyrki