page@swan.ulowell.edu (Bob Page) (11/29/88)
Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert) Posting-number: Volume 2, Issue 66 Archive-name: devices/rdf.1 Raw trackdisk.device interface for DOS, based somewhat on Matthew Dillon's excellent PIPE:. This first version handle packets one at a time, so we avoid problems with having several IO requests outstanding (which must be replied to the reader/writer in order). Implemented functions are: Open() Close() Read() Write() Seek() Usage: RDF:/dtrackdisk.device /uunit # /fflags /ooffset /llength /eeof (maintain a virtual end-of-file) /E (get eof from last closed file) [uuencoded doc because it's got escape sequences in it. ..Bob] # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # Mountlist # Notice # RCopy.c # include.c # misc.c # rdf.c # rdf.man.uu # This archive created: Mon Nov 28 20:05:56 1988 cat << \SHAR_EOF > Makefile #DB = -DDEBUG CFLAGS = +BCDL +Isyms $(DB) OBJ = rdf.o misc.o .c.o: cc $(CFLAGS) $*.c .c.asm: cc $(CFLAGS) -at $*.c RDF-Handler: $(OBJ) ln $(OBJ) -lcl32 -w -o RDF-Handler syms: include.c cc +BCDL +Hsyms -a -o nil: include.c RCopy: RCopy.c cc RCopy.c ln RCopy.o -lc SHAR_EOF cat << \SHAR_EOF > Mountlist RDF: Handler = devs:RDF-Handler Device = trackdisk.device Unit = 1 Flags = 0 Stacksize = 4096 Priority = 4 GlobVec = -1 # SHAR_EOF cat << \SHAR_EOF > Notice This software is (C) Copyright 1988 by Olaf Seibert. All Rights Reserved. This software is NOT in the public domain. It may not be sold or used for profit without prior written consent from the author, Olaf Seibert. Conditions for redistribution are: - This notice must remain included at all times. It may not be modified in any way. - No charge may be made for distribution above media and transportation costs. - The source and documentation of the program must always be distributed with the binary, unless the distributor of said binary agrees to supply the source and documentation on request, with no expiration date on availability of said source and documentation. - If any part of this program (source or binary) or its documentation is included in any other software package, either integrated or separately, these redistribution conditions automatically apply to the entire package, unless prior written permission is obtained from the author. - No claim is made regarding the quality of this software or its documentation. It is supplied purely as-is. The author cannot be held responsible for any damages occurring directly or indirectly from using or not using this program. The author can be reached at: Olaf Seibert p/a Beek 5 5815 CS Merselo The Netherlands SHAR_EOF cat << \SHAR_EOF > RCopy.c /* * RCOPY * * Very plain copy program. No frills at all. * Just Open() Read() Write() and Close(). * */ long Output(), Read(), Write(), Open(); void *AllocMem(); #define MEMF_PUBLIC (1L << 0) #define MEMF_CHIP (1L << 1) #define MODE_OLDFILE 1005L #define MODE_NEWFILE 1006L #define BUFSIZE (11 * 1024L) main(argc, argv) int argc; char **argv; { register long from, to, size, output; register void *buffer; output = Output(); if (argc != 3) { Write(output, "Usage: RCOPY source dest\n", 26L); exit(10); } if (buffer = AllocMem(BUFSIZE, MEMF_CHIP | MEMF_PUBLIC)) { if (from = Open(argv[1], MODE_OLDFILE)) { if (to = Open(argv[2], MODE_NEWFILE)) { while ((size = Read(from, buffer, BUFSIZE)) > 0) { if (size != Write(to, buffer, size)) { Write(output, "Write error\n", 12L); break; } if (Chk_Abort()) { Write(output, "^C\n", 3L); break; } } Close(to); } else Write(output, "Cannot open destination\n", 24L); Close(from); } else Write(output, "Cannot open source\n", 19L); FreeMem(buffer, BUFSIZE); } else Write(output, "Cannot allocate copy buffer\n", 28L); } SHAR_EOF cat << \SHAR_EOF > include.c #include <exec/types.h> #include <exec/nodes.h> #include <exec/lists.h> #include <exec/ports.h> #include <exec/libraries.h> #include <exec/devices.h> #include <exec/io.h> #include <exec/memory.h> #include <devices/trackdisk.h> #include <libraries/dos.h> #include <libraries/dosextens.h> #include <libraries/filehandler.h> /*#include "xmisc.h"*/ SHAR_EOF cat << \SHAR_EOF > misc.c /* * MISC.C - support routines - Phillip Lindsay (C) Commodore 1986 * You may freely distribute this source and use it for Amiga Development - * as long as the Copyright notice is left intact. * * 30-SEP-86 * * major modifications by Matthew Dillon for my PIPE: and other devices, * but basic theorem still Phil's. * * 09-OKT-88 * * (Olaf Seibert) added provision for an external taskwait routine. * Changed returnpkt and returnpktplain. */ #include <exec/types.h> #include <exec/nodes.h> #include <exec/lists.h> #include <exec/ports.h> #include <libraries/dos.h> #include <libraries/dosextens.h> extern void returnpkt(); extern char *GetMsg(); void returnpktplain(packet, myproc) struct DosPacket *packet; struct Process *myproc; { register struct Message *mess; register struct MsgPort *replyport; replyport = packet->dp_Port; mess = packet->dp_Link; packet->dp_Port = &myproc->pr_MsgPort; mess->mn_Node.ln_Name = (char *)packet; mess->mn_Node.ln_Succ = NULL; mess->mn_Node.ln_Pred = NULL; PutMsg(replyport, mess); } void returnpkt(packet, myproc, res1, res2) register struct DosPacket *packet; struct Process *myproc; long res1, res2; { packet->dp_Res1 = res1; packet->dp_Res2 = res2; returnpktplain(packet, myproc); } /* * taskwait() ... Waits for a message to arrive at your port and * extracts the packet address which is returned to you. */ typedef struct Message *(*funcptr)(); struct DosPacket * taskwait(myproc) register struct Process *myproc; { register struct MsgPort *myport; register struct Message *mymess; if (myproc->pr_PktWait) { /* As per AmigaDOS tech. ref. man (V1.1) page 265: */ /* ``In the same way as GetMsg, the function should */ /* return a message when one is available.'' */ mymess = (*(funcptr)myproc->pr_PktWait)(myproc); } else { myport = &myproc->pr_MsgPort; WaitPort(myport); mymess = (struct Message *)GetMsg(myport); } return((struct DosPacket *)mymess->mn_Node.ln_Name); } taskpktrdy(myproc) struct Process *myproc; { if (myproc->pr_MsgPort.mp_MsgList.lh_Tail == NULL) return(0); return(1); } SHAR_EOF cat << \SHAR_EOF > rdf.c /* * Raw trackdisk.device interface for DOS. * * Based somewhat on Mattew Dillons excellent PIPE: (hello Matt!). * * First version: handle packets one at a time. This way, we avoid * problems with having several IO requests outstanding, which * must be replied to the reader/writer in order. * * Usage: * RDF:/dtrackdisk.device * /uunit # * /fflags * /ooffset * /llength * /eeof (maintain a virtual end-of-file) * /E (get eof from last closed file) * * If you open a file with /E and then read at least * 4 bytes from it, you will get the eof offset from the last closed * file. * * Implemented functions are: * * Open() Close() * Read() Write() * Seek() * * These are more or less just dummies: * * Lock() UnLock() DupLock() * DeleteFile() */ #include <exec/types.h> #include <exec/nodes.h> #include <exec/lists.h> #include <exec/ports.h> #include <exec/libraries.h> #include <exec/devices.h> #include <exec/io.h> #include <exec/memory.h> #include <devices/trackdisk.h> #include <libraries/dos.h> #include <libraries/dosextens.h> #include <libraries/filehandler.h> /* Various ACTION's supported */ #define ACTION_FIND_RW 1004 /* name ?? */ #define ACTION_FIND_INPUT MODE_OLDFILE /* 1005 */ #define ACTION_FIND_OUTPUT MODE_NEWFILE /* 1006 */ #define ACTION_END 1007 #define ACTION_SEEK 1008 #undef BADDR #define BADDR(x) ((APTR)((long)x << 2)) /* convert BCPL->APTR */ #define DOS_FALSE 0 #define DOS_TRUE -1 #define TD_SECMASK (TD_SECTOR - 1) /* Assumes it is a power of 2 */ #define branchto goto /* (-: Avoid goto's :-) */ typedef struct DosPacket DOSPACKET; typedef struct Process PROC; typedef struct DeviceNode DEVNODE; typedef struct FileHandle FH; typedef unsigned char uchar; typedef struct Message MSG; typedef struct _FILE { struct IOExtTD *file_IO; ULONG file_MinOffset; /* <= Offset */ ULONG file_Offset; /* <= EofOffset */ ULONG file_EofOffset; /* <= MaxOffset */ ULONG file_MaxOffset; } File; /* * NOTE: Globals in the Bss space are not automatically initialized to * 0 when you don't use Aztec's startup _main, which we can't since * this is a packet handler. */ extern long AbsExecBase; /* Absolute global address 4 */ extern DOSPACKET *taskwait(); /* wait for a message */ extern void *AllocMem(); extern PROC *FindTask(); extern struct IOExtTD *CreateExtIO(); extern struct MsgPort *CreatePort(); ULONG PerformIO(); /* Encapsulate DoIO() */ long ntoi(); /* Our own fancy atoi() */ long SysBase; /* required to make Exec calls */ uchar Buf[256]; /* Scratch buffer */ long DOSBase; #ifdef DEBUG long Fh; /* Debugging.. */ #endif exec_handler() { PROC *MyProc; /* my process */ DEVNODE *MyNode; /* our device node passed in parmpkt Arg3 */ uchar Expunge = 0; uchar NotDone; uchar *default_Device; ULONG default_Unit; ULONG default_Flags; ULONG OpenCount = 0; /* must be 4 bytes... used as temp BPTR */ char *TDBuffer = NULL; ULONG save_Eof = 0; struct MsgPort *IOPort; SysBase = AbsExecBase; /* Initialize SysBase */ #ifdef DEBUG Fh = NULL; /* Debugging OFF */ #endif MyProc = (PROC *)FindTask(0L); DOSBase = OpenLibrary("dos.library", 0); #ifdef DEBUG /* DEBUGGING * Note that the debugging uses normal DOS calls, so the same * MsgPort is being used that our own commands arrive on. * So when debugging is enabled, please have only one open file * on RDF: at a time, or face the dreaded AN_AsyncPkt guru. */ Fh = Open("CON:0/0/600/150/RDF-handler", MODE_NEWFILE); #endif /* * INITIAL STARTUP MESSAGE */ { register DOSPACKET *MyPkt; /* long *environ; */ MyPkt = taskwait(MyProc); IOPort = CreatePort(0, 0); TDBuffer = AllocMem(TD_SECTOR, MEMF_PUBLIC | MEMF_CHIP); if (IOPort && TDBuffer) { struct FileSysStartupMsg *fssm; MyNode = (DEVNODE *)BADDR(MyPkt->dp_Arg3); fssm = (struct FileSysStartupMsg *)BADDR(MyNode->dn_Startup); /* Same as BADDR(MyPkt->dp_Arg2) */ default_Device = (uchar *)BADDR(fssm->fssm_Device) + 1; default_Unit = fssm->fssm_Unit; default_Flags = fssm->fssm_Flags; MyNode->dn_Task = &MyProc->pr_MsgPort; returnpkt(MyPkt, MyProc, DOS_TRUE, 0); } else { returnpkt(MyPkt, MyProc, DOS_FALSE, ERROR_NO_FREE_STORE); Alert(0x00018014, 0); /* AG_NoMemory | AO_TrackDiskDev */ branchto exit; } #ifdef DEBUG if (Fh) { sprintf(Buf, "'%s', %ld flags %ld\n", default_Device, default_Unit, default_Flags); Write(Fh, Buf, strlen(Buf)); } #endif } top: /* * MAIN LOOP */ NotDone = 1; while (NotDone) { register DOSPACKET *MyPkt; /* dos packet received */ register File *file; /* pointer to current File */ struct IOExtTD *iotd; long type; /* type of packet */ MyPkt = taskwait(MyProc); /* wait/get next packet */ MyPkt->dp_Res1 = DOS_TRUE; /* default return value */ MyPkt->dp_Res2 = 0; /* default no error */ type = MyPkt->dp_Type; /* packet type */ /* * Extract File pointer. Doesn't apply to Open() */ file = (File *)MyPkt->dp_Arg1; #ifdef DEBUG if (Fh) { sprintf(Buf, "Packet: %4ld arg3 %ld, file: %-8lx arg2: %ld\n", MyPkt->dp_Type, MyPkt->dp_Arg3, file, MyPkt->dp_Arg2); Write(Fh, Buf, strlen(Buf)); } #endif switch(type) { case ACTION_FIND_INPUT: case ACTION_FIND_OUTPUT: case ACTION_FIND_RW: { uchar *this_Device = default_Device; long this_Unit = default_Unit; long these_Flags = default_Flags; long this_Offset = 0; long this_Length = 880 * 1024L; long this_Eof = -1; register uchar *name = (uchar *)BADDR(MyPkt->dp_Arg3); /* Parse the given filename */ strncpy(Buf, name + 1, *name); Buf[*name] = '\0'; #ifdef DEBUG if (Fh) { Write(Fh, Buf, strlen(Buf)); Write(Fh, "\n", 1); } #endif for (name = Buf; *name; ) { if (*name == '/') { *name++ = '\0'; switch (*name) { case 'd': this_Device = ++name; break; case 'u': this_Unit = ntoi(++name); break; case 'f': these_Flags = ntoi(++name); break; case 'o': this_Offset = ntoi(++name); break; case 'l': this_Length = ntoi(++name); break; case 'e': this_Eof = ntoi(++name); break; case 'E': this_Offset = -1; } } else name++; /* Don't fail on /e/o */ } file = (File *)AllocMem(sizeof(File), MEMF_CLEAR); if (file == NULL) branchto openfail1; iotd = CreateExtIO(IOPort, sizeof(struct IOExtTD)); if (iotd == NULL) branchto openfail2; if (OpenDevice(this_Device, this_Unit, iotd, these_Flags)) branchto openfail3; iotd->iotd_Count = PerformIO(iotd, TD_CHANGENUM, 0, 0, 0); OpenCount++; file->file_IO = iotd; file->file_MinOffset = this_Offset; file->file_Offset = this_Offset; file->file_MaxOffset = this_Offset + this_Length; if (this_Eof == -1) file->file_EofOffset = file->file_MaxOffset; else file->file_EofOffset = this_Offset + this_Eof; } { struct FileHandle *fh; fh = (FH *)BADDR(MyPkt->dp_Arg1); /* File handle */ fh->fh_Arg1 = (long) file; } #ifdef DEBUG if (Fh) { sprintf(Buf, "Open File %08lx iotd: %08lx\n", file, iotd); Write(Fh, Buf, strlen(Buf)); } #endif branchto returnpkt; openfail4: CloseDevice(iotd); openfail3: DeleteExtIO(iotd); openfail2: FreeMem(file, sizeof(*file)); openfail1: returnpkt(MyPkt, MyProc, DOS_FALSE, ERROR_NO_FREE_STORE); break; returnpkt: returnpktplain(MyPkt, MyProc); break; case ACTION_END: /* CLOSE */ iotd = file->file_IO; #ifdef DEBUG if (Fh) { sprintf(Buf, "Close File %08lx iotd: %08lx\n", file, iotd); Write(Fh, Buf, strlen(Buf)); } #endif PerformIO(iotd, CMD_UPDATE, 0, 0, 0); PerformIO(iotd, TD_MOTOR, 0, 0, 0); CloseDevice(iotd); DeleteExtIO(iotd); save_Eof = file->file_EofOffset - file->file_MinOffset; FreeMem(file, sizeof(*file)); returnpktplain(MyPkt, MyProc); --OpenCount; break; case ACTION_READ: /* Arg2: buffer */ iotd = file->file_IO; { /* Arg3: size */ char *buffer = (char *) MyPkt->dp_Arg2; long size = MyPkt->dp_Arg3; long done = 0; int blockoffset = 0; #ifdef DEBUG if (Fh) { sprintf(Buf, "Read File %08lx iotd: %08lx\n", file, iotd); Write(Fh, Buf, strlen(Buf)); sprintf(Buf, " buffer %08lx size %08lx offset %08lx\n", buffer, size, file->file_Offset); Write(Fh, Buf, strlen(Buf)); } #endif /* Is this such a special read-last-eof file? */ if ((LONG) file->file_Offset < 0) { if (size >= 4) { movmem(&save_Eof, buffer, 4); MyPkt->dp_Res1 = 4; } else MyPkt->dp_Res1 = 0; file->file_Offset = 0; file->file_EofOffset = 0; branchto readdone; } /* Don't read past the end of the virtual file */ done = file->file_EofOffset - file->file_Offset; if (size > done) size = done; MyPkt->dp_Res1 = size; blockoffset = file->file_Offset & TD_SECMASK; /* Can we read directly into the user buffer? */ if ((size >= TD_SECTOR) && blockoffset == 0 && (size & 3) == 0 && (((long)buffer) & 3) == 0 && (TypeOfMem(buffer) & MEMF_CHIP)) { done = PerformIO(iotd, ETD_READ, buffer, file->file_Offset, size & ~TD_SECMASK); if (iotd->iotd_Req.io_Error) branchto readfail; file->file_Offset += done; buffer += done; size -= done; } /* Read the rest (or all of it) via our MEMF_CHIP buffer */ while (size > 0) { /* Get one disk block: do a bit of padding at the start */ done = PerformIO(iotd, ETD_READ, TDBuffer, file->file_Offset - blockoffset, TD_SECTOR) - blockoffset; /* and subtract the padding */ if (iotd->iotd_Req.io_Error || done <= 0) { readfail: MyPkt->dp_Res1 = -1; MyPkt->dp_Res2 = ERROR_READ_PROTECTED; /* Silly */ break; } /* Don't copy more than the user wanted */ if (done > size) done = size; movmem(TDBuffer + blockoffset, buffer, done); file->file_Offset += done; /* Normally the block offset becomes 0 now */ blockoffset = file->file_Offset & TD_SECMASK; buffer += done; size -= done; } readdone: ; #ifdef DEBUG if (Fh) { sprintf(Buf, " Read: %ld DoIO: %ld size left: %lx\n", MyPkt->dp_Res1, iotd->iotd_Req.io_Error, size); Write(Fh, Buf, strlen(Buf)); } #endif } branchto returnpkt; case ACTION_WRITE: iotd = file->file_IO; { char *buffer = (char *) MyPkt->dp_Arg2; long size = MyPkt->dp_Arg3; long done = 0; int blockoffset = 0; #ifdef DEBUG if (Fh) { sprintf(Buf, "Write File %08lx iotd: %08lx\n", file,iotd); Write(Fh, Buf, strlen(Buf)); sprintf(Buf, " buffer %08lx size %08lx offset %08lx\n", buffer, size, file->file_Offset); Write(Fh, Buf, strlen(Buf)); } #endif /* Don't write past the end of the device */ done = file->file_MaxOffset - file->file_Offset; if (size > done) { size = done; MyPkt->dp_Res2 = ERROR_DISK_FULL; } MyPkt->dp_Res1 = size; blockoffset = file->file_Offset & TD_SECMASK; /* Can we write directly into the user buffer? */ if ((size >= TD_SECTOR) && blockoffset == 0 && (size & 3) == 0 && (((long)buffer) & 3) == 0 && (TypeOfMem(buffer) & MEMF_CHIP)) { done = PerformIO(iotd, ETD_WRITE, buffer, file->file_Offset, size & ~TD_SECMASK); if (iotd->iotd_Req.io_Error) branchto writefail; file->file_Offset += done; buffer += done; size -= done; } /* Write the rest (or all of it) via our MEMF_CHIP buffer */ while (size > 0) { /* Get a partial disk block */ if (blockoffset || size < TD_SECTOR) { PerformIO(iotd, ETD_READ, TDBuffer, file->file_Offset - blockoffset, TD_SECTOR); if (iotd->iotd_Req.io_Error) branchto writefail; } if (blockoffset + size > TD_SECTOR) done = TD_SECTOR - blockoffset; else done = size; movmem(buffer, TDBuffer + blockoffset, done); /* Write the buffer (back) */ PerformIO(iotd, ETD_WRITE, TDBuffer, file->file_Offset - blockoffset, TD_SECTOR); /* On error we did not write the block */ if (iotd->iotd_Req.io_Error || iotd->iotd_Req.io_Actual != TD_SECTOR) { writefail: MyPkt->dp_Res1 = -1; MyPkt->dp_Res2 = ERROR_WRITE_PROTECTED; /* Silly */ break; } file->file_Offset += done; /* Normally the block offset becomes 0 now */ blockoffset = file->file_Offset & TD_SECMASK; buffer += done; size -= done; } #ifdef DEBUG if (Fh) { sprintf(Buf, " Write: %ld DoIO: %ld size left: %lx\n", MyPkt->dp_Res1, iotd->iotd_Req.io_Error, size); Write(Fh, Buf, strlen(Buf)); } #endif } /* Writing may adjust the end-of-file marker */ if (file->file_Offset > file->file_EofOffset) file->file_EofOffset = file->file_Offset; branchto returnpkt; case ACTION_RENAME_DISK: /* for debugging */ case ACTION_DIE: Expunge = 1; if (OpenCount == 0) NotDone = 0; branchto returnpkt; case ACTION_SEEK: { long Offset = -1; switch (MyPkt->dp_Arg3) { /* seek mode */ case OFFSET_BEGINNING: Offset = file->file_MinOffset + MyPkt->dp_Arg2; break; case OFFSET_CURRENT: Offset = file->file_Offset + MyPkt->dp_Arg2; break; case OFFSET_END: Offset = file->file_EofOffset + MyPkt->dp_Arg2; break; } if (Offset >= file->file_MinOffset && Offset <= file->file_EofOffset) { MyPkt->dp_Res1 = Offset - file->file_MinOffset; file->file_Offset = Offset; } else { MyPkt->dp_Res1 = -1; MyPkt->dp_Res2 = ERROR_SEEK_ERROR; } } branchto returnpkt; case ACTION_LOCATE_OBJECT: /* Just always succeed */ { struct FileLock *lock; if (lock = AllocMem(sizeof (*lock), MEMF_PUBLIC | MEMF_CLEAR)) { lock->fl_Access = MyPkt->dp_Arg3; lock->fl_Task = &MyProc->pr_MsgPort; /* lock->fl_Volume remains NULL */ OpenCount++; } else MyPkt->dp_Res2 = ERROR_NO_FREE_STORE; MyPkt->dp_Res1 = ((long) lock) >> 2; } branchto returnpkt; case ACTION_COPY_DIR: { struct FileLock *lock; if (lock = AllocMem(sizeof (*lock), MEMF_PUBLIC | MEMF_CLEAR)) { *lock = *(struct FileLock *)BADDR(MyPkt->dp_Arg1); OpenCount++; } else MyPkt->dp_Res2 = ERROR_NO_FREE_STORE; MyPkt->dp_Res1 = ((long) lock) >> 2; } branchto returnpkt; case ACTION_FREE_LOCK: { if (MyPkt->dp_Arg1) { FreeMem(BADDR(MyPkt->dp_Arg1), sizeof (struct FileLock)); OpenCount--; } } branchto returnpkt; default: returnpkt(MyPkt, MyProc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN); break; } /* end switch */ } /* end while (NotDone) */ /* * Can only exit if no messages pending. There might be a window * here, but there is nothing that can be done about it. */ #ifdef DEBUG if (!Expunge) branchto top; #endif Forbid(); if (taskpktrdy(MyProc)) { Permit(); branchto top; } MyNode->dn_Task = NULL; Permit(); exit: if (IOPort) DeletePort(IOPort); if (TDBuffer) FreeMem(TDBuffer, TD_SECTOR); #ifdef DEBUG if (Fh) Close(Fh); #endif /* We are a process "so we fall off the end of the world" */ if (Expunge) { OpenCount = MyNode->dn_SegList; /* Temporary */ Forbid(); MyNode->dn_SegList = NULL; UnLoadSeg(OpenCount); /* We execute in unallocated memory now... and Forbid()den. */ } CloseLibrary(DOSBase); /* MUST fall through */ } ULONG PerformIO(ioReq, cmd, buffer, offset, size) register struct IOExtTD *ioReq; ULONG cmd; APTR buffer; ULONG offset; ULONG size; { #ifdef DEBUG if (Fh) { sprintf(Buf, "PerfIO buffer %08lx size %08lx offset %08lx\n", buffer, size, offset); Write(Fh, Buf, strlen(Buf)); } #endif ioReq->iotd_Req.io_Command = cmd; ioReq->iotd_Req.io_Length = size; ioReq->iotd_Req.io_Data = buffer; ioReq->iotd_Req.io_Offset = offset; DoIO(ioReq); return ioReq->iotd_Req.io_Actual; } int todigit(c) register char c; { if ((c -= '0') < 0 || c > ('F' - '0')) return 42; if (c >= ('A' - '0')) { c -= 'A' - '9' - 1; } return c; } long ntoi(str) register char *str; { register long total = 0; register long value; register int digit; register int base; /* First determine the base */ number: if (*str == '0') { if (*++str == 'x') { /* 0x means hexadecimal */ base = 16; str++; } else { base = 8; /* Otherwise, 0 means octal */ } } else { base = 10; /* and any other digit means decimal */ } value = 0; while ((digit = todigit(*str)) < base) { value *= base; value += digit; str++; } suffix: switch (*str++) { case 'm': /* scale with megabytes */ value *= 1024 * 1024; branchto suffix; case 'k': /* scale with kilobytes */ value *= 1024; branchto suffix; case 's': /* scale with sectors */ value *= TD_SECTOR; /* or maybe even kilosectors! */ branchto suffix; case 'b': /* scale with bytes */ branchto suffix; } str--; total += value; if (*str >= '0' && *str <= '9') branchto number; /* Allow 10k512, recursion eliminated */ return total; } SHAR_EOF cat << \SHAR_EOF > rdf.man.uu begin 644 rdf.man M"B`@("`@4D1&*#0I("`@("`@("`@("`@("`@($%M:6=A(%!R;V=R86UM97(G- M<R!-86YU86P@("`@("`@("`@("`@("`@(%)$1B@T*0H*"@H@("`@()LQ;4Y!" M344@"B`@("`@("`@("";,&UR9&8Z("T@<F%W(&EN=&5R9F%C92!T;R!D:7-K` M<R`*"B`@("`@FS%M4UE.3U!325,@"B`@("`@("`@("";,&U-;W5N="!21$8ZS M"B`@("`@("`@("!21$8Z+V0\<V]M92YD979I8V4^("`H<V5T($1E=FEC92!AD M<F=U;65N="!F;W(@3W!E;D1E=FEC92D*("`@("`@("`@("`@("`O=3QU;FET^ M(",^("`@("`@("AS970@56YI="!A<F=U;65N="!F;W(@3W!E;D1E=FEC92D*T M("`@("`@("`@("`@("`O9CQF;&%G<SX@("`@("`@("AS970@1FQA9W,@87)GW M=6UE;G0@9F]R($]P96Y$979I8V4I"B`@("`@("`@("`@("`@+V\\;V9F<V5TF M/B`@("`@("`H<V5T(&EN:71I86P@;V9F<V5T(&]N(&1E=FEC92D*("`@("`@# M("`@("`@("`O;#QL96YG=&@^("`@("`@("AS970@;&5N9W1H(&]F('!H>7-I/ M8V%L(&1E=FEC92D*("`@("`@("`@("`@("`O93QE;V8^("`@("`@("`@("AS6 M970@86YD(&UA:6YT86EN(&$@=FER='5A;"!E;F0M;V8M9FEL92D*("`@("`@> M("`@("`@("`O12`@("`@("`@("`@("`@("AG970@96]F(&9R;VT@;&%S="!C! M;&]S960@9FEL92D*"B`@("`@("`@("!20V]P>2`\<V]U<F-E/B`\9&5S=&EN/ M871I;VX^"@H@("`@()LQ;41%4T-225!424].(`H@("`@("`@("`@FS!MFS-MG M4D1&.B`@()LP;6ES("`@82`@(&1O<RUL979E;"`@('!A8VME="`@(&AA;F1LU M97(@(&EN=&5R9F%C92`@9F]R"B`@("`@("`@("!T<F%C:V1I<VLN9&5V:6-EW M+6QI:V4@97AE8R`@9&5V:6-E<RX@("`@270@(&5N86)L97,@('EO=2`@=&\*) M("`@("`@("`@(&]P97)A=&4@;VX@82!F;&]P<'D@9&ES:R`H;W(@:68@>6]U( M(&QI:V4L('EO=7(@:&%R9"!D:7-K*2!A<PH@("`@("`@("`@82!S97%U96YT7 M:6%L("!S=')E86T@;V8@8GET97,N("!)="!B>7!A<W-E<R!B=69F97)S('1H\ M870@87)E"B`@("`@("`@("!M86YA9V5D(&)Y('1H92!F:6QE('-Y<W1E;2`HM M87,@861D960@8GD@("=!9&1"=69F97)S)RDL("!B=70*("`@("`@("`@(&ET, M("!M86ME<R`@=7-E("!O9B!B=69F97)S(&UA;F%G960@8GD@82!D979I8V4@9 M8G5F9F5R(&-A8VAE+`H@("`@("`@("`@<W5C:"!A<R!&86-C(&%N9"!&86-C8 M($E)+B!9;W4@8V%N($]P96XH,BD@82!F:6QE(&]N('1H92";,VU21$8Z"B`@> M("`@("`@("";,&UD979I8V4L(&%N9"!T:&5N(%)E860H,BD@9G)O;2!A;F0@< M5W)I=&4H,BD@=&\@:70N("!9;W4@(&YE960*("`@("`@("`@(&YO="`@8F4@7 M(&-O;F-E<FYE9"`@86)O=70@('1H92`@<V5C=&]R("!A;&EG;FUE;G0@('1H8 M870@('1H90H@("`@("`@("`@=')A8VMD:7-K+F1E=FEC92!I;7!O<V5S.R!IB M9B!N965D960L()LS;5)$1CH@FS!M=VEL;"!U<V4@(&ET<R`@;W=N"B`@("`@3 M("`@("!P<FEV871E("!B=69F97(@('1O("!R96%D("!O<B`@=W)I=&4@('!AQ M<G1I86P@<V5C=&]R<R!O;B!T:&4*("`@("`@("`@(&1I<VLN("`*("`@("`@* M("`@()LS;5)#;W!Y()LP;6ES(&$@=F5R>2!S:6UP;&4L(&YO(&9R:6QL<R`@" M8V]P>2`@<')O9W)A;2`@=&AA="`@;VYL>0H@("`@("`@("`@=7-E<R!/<&5NB M*"DL($-L;W-E*"DL(%)E860H*2!A;F0@5W)I=&4H*2!T;R!C;W!Y(&$@9FEL& M92X@($ET"B`@("`@("`@("!H87,@(&)E96X@(&]P=&EM:7IE9"`@=&\@8F4@O M=7-E9"!W:71H()LS;5)$1CH@FS!M+"!S:6YC92!I="!U<V5S(&$*("`@("`@< M("`@(&)U9F9E<B!O9B`@,C(@("H@(%1$7U-%0U1/4B`@8GET97,@("AA("!SG M:6YG;&4@(&-Y;&EN9&5R("!O;@H@("`@("`@("`@9FQO<'!I97,I('1H870@, M(&ES("!L;V-A=&5D("!I;B`@0VAI<"`@;65M;W)Y+B`@("!4:&ES("!W87DL/ M"B`@("`@("`@("!U;FYE8V5S<V%R>2!M96UO<GD@8V]P>2!O<&5R871I;VYSR M(&%R92!A=F]I9&5D+B`@"@H@("`@("`@("`@("`@("";,VU21$8Z()LP;7)EV M8V]G;FEZ97,@<V]M92!O<'1I;VYS('1H870@>6]U("!C86X@('-P96-I9GD@U M(&EN"B`@("`@("`@("!T:&4@9FEL92`@;F%M92`@<W5P<&QI960@('1O(&ETI M+B`@36]S="!O<'1I;VYS(&AA=F4@9&5F875L=',*("`@("`@("`@('1H870@4 M87)E('-E="!I;B!T:&4@36]U;G1,:7-T("AS964@8F5L;W<I+B`@3W!T:6]N9 M<R`@8V]N<VES=`H@("`@("`@("`@;V8@(&$@9F]R=V%R9"!S;&%S:"P@9F]L3 M;&]W960@8GD@82!S:6YG;&4@;&5T=&5R+"!O<'1I;VYA;&QY"B`@("`@("`@* M("!F;VQL;W=E9"!B>2!A('9A;'5E+B`@5&AE(&9O;&QO=VEN9R!O<'1I;VYS! M(&%R92!R96-O9VYI>F5D.B`*"B`@("`@("`@("`@("`@()LS;5)$1CHO9#QS# M;VUE($5X96,@9&5V:6-E(&YA;64^()LP;2AS970@1&5V:6-E(&%R9W5M96YTT M("!F;W(*("`@("`@("`@($]P96Y$979I8V4I(`H@("`@("`@("`@5&AE(&YA6 M;64@>6]U('-U<'!L>2!H97)E('=I;&P@8F4@=7-E9"!I;B!T:&4@3W!E;D1EC M=FEC92!C86QL"B`@("`@("`@("!T:&%T("!I<R`@<&%R="`@;V8@=&AE(&%C+ M=&EO;G,@;V8@;W!E;FEN9R!A(&9I;&4@;VX@=&AE()LS;5)$1CH*("`@("`@, M("`@()LP;7!S975D;R!D979I8V4N("`@($%N>2`@17AE8R`@9&5V:6-E("!T7 M:&%T("!L;V]K<R`@;&EK92`@('1H90H@("`@("`@("`@=')A8VMD:7-K+F1EL M=FEC92!I<R`@=F%L:60N("`@26X@<&%R=&EC=6QA<BP@FS-M4D1&.B";,&UOS M;FQY(')E861S"B`@("`@("`@("!A;F0@('=R:71E<R`@8FQO8VMS("!O9B`@P M(%1$7U-%0U1/4B`@(&)Y=&5S("`@;VX@("!41%]314-43U(*("`@("`@("`@\ M(&)O=6YD87)I97,N("!4:&ES(&EM<&QI97,@=&AA="`H<V5Q=65N=&EA;"D@" M9&5V:6-E<R!L:6ME('1H90H@("`@("`@("`@<V5R:6%L+F1E=FEC92`@=VEL] M;"`@;F]T('=O<FLL('-I;F-E(')E<&5A=&5D(')E861S('=I=&@@=&AE"B`@> M("`@("`@("!S86UE($]F9G-E="!W:6QL('5S=6%L;'D@;F]T(')E='5R;B!TY M:&4@<V%M92!D871A+B`@"B`@("`@("`@("!)9B!Y;W4@9&]N)W0@<W5P<&QYZ M('1H:7,@;W!T:6]N+"!T:&4@9&5F875L="!I<R`@=&%K96X@(&9R;VT*("`@0 M("`@("`@('1H92!-;W5N=$QI<W0@96YT<GD@)T1E=FEC92`])RX@(`H*("`@_ M("`@("`@("`@("`@FS-M4D1&.B]U/'5N:70@(SX@FS!M*'-E="!5;FET(&%RQ M9W5M96YT(&9O<B!/<&5N1&5V:6-E*2`*("`@("`@("`@(%1H:7,@56YI="!W[ M:6QL(&)E(&]P96YE9"!O;B!T:&4@<W!E8VEF:65D(&]R(&1E9F%U;'0@1&5VR M:6-E+@H@("`@("`@("`@268@('EO=2`@9&]N)W0@<W5P<&QY('1H:7,@;W!TI M:6]N+"!T:&4@9&5F875L="!I<R!T86ME;B!F<F]M"@H*("`@("!+;W-M;U-OD M9G0@("`@("`@("`@("`@("`@("`@("`@("`M,2T@("`@("`@("`@("`@("`@E M("`@("`@(%)E;&5A<V4@,2XP"@H*("`@("!21$8H-"D@("`@("`@("`@("`@/ M("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@("`@("`@("`@("`@S M4D1&*#0I"@H*("`@("`@("`@('1H92!-;W5N=$QI<W0@96YT<GD@)U5N:70@H M/2<N("`*"B`@("`@("`@("`@("`@()LS;5)$1CHO9CQF;&%G<SX@FS!M*'-E+ M="!&;&%G<R!A<F=U;65N="!F;W(@3W!E;D1E=FEC92D@"B`@("`@("`@("!44 M:&5S92!&;&%G<R!W:6QL(&)E('-P96-I9FEE9"!O;B!T:&4@;W!E;B!O9B`@B M=&AE("!S<&5C:69I960*("`@("`@("`@(&]R("!D969A=6QT("!$979I8V4N[ M("!)9B`@>6]U("!D;VXG="!S=7!P;'D@=&AI<R!O<'1I;VXL('1H90H@("`@= M("`@("`@9&5F875L="!I<R!T86ME;B!F<F]M('1H92!-;W5N=$QI<W0@96YT_ M<GD@)T9L86=S(#TG+B`@"@H@("`@("`@("`@("`@("";,VU21$8Z+V\\;V9FK M<V5T/B";,&TH<V5T(&EN:71I86P@;V9F<V5T(&]N(&1E=FEC92D@"B`@("`@' M("`@("!4:&ES(&]P=&EO;B!L971S('EO=2!S<&5C:69Y('=H97)E('EO=7(@C M=FER='5A;"!F:6QE("!S=&%R=',*("`@("`@("`@(&]N('1H92`@<&AY<VEC` M86P@(&1E=FEC92X@("`@5&AE<F4@:7,@;F\@=V%Y('EO=2!C86X@<F5A9"!OG M<@H@("`@("`@("`@=W)I=&4@9&%T82!B969O<F4@=&AI<R!P;VEN="`@;VX@3 M('1H92`@9&ES:RX@("`@06YY("!3965K*#(I"B`@("`@("`@("!O9F9S970@> M=VEL;"!B92!R96QA=&EV92!T;R!T:&ES('!O:6YT+B`@5&AE(&1E9F%U;'0@T M9F]R('1H:7,*("`@("`@("`@(&]P=&EO;B!I<R`P+B`@"@H@("`@("`@("`@0 M("`@("";,VU21$8Z+VP\;&5N9W1H/B";,&TH<V5T(&QE;F=T:"!O9B!P:'ES/ M:6-A;"!D979I8V4I(`H@("`@("`@("`@5&AI<R`@;W!T:6]N("!L971S("!Y> M;W4@('-P96-I9GD@('1H92!L96YG=&@@;V8@=&AE('!H>7-I8V%L"B`@("`@W M("`@("!D979I8V4N("";,VU21$8Z()LP;7=O;B=T(&%T=&5M<'0@=&\@<F5A0 M9"!O<B!W<FET92!M;W)E('1H86X@('1H:7,*("`@("`@("`@(&%M;W5N="!OS M9B`@8GET97,@('!A<W0@('1H92`@:6YI=&EA;"!O9F9S970N("!)9B!Y;W4@1 M<W!E8VEF>0H@("`@("`@("`@=&AI<R!V86QU92!T;V\@;&%R9V4@9F]R('1HR M92!P:'ES:6-A;"`@9&5V:6-E+"`@=&AE("!$;TE/*#(I"B`@("`@("`@("!CZ M86QL('=I;&P@<F5T=7)N(&%N(&5R<F]R+"!S;R!T:&4@4F5A9"@I(&]R(%=RP M:71E*"D@=VEL;"!N;W0*("`@("`@("`@(')E='5R;B!T:&4@(&YU;6)E<B`@P M;V8@(&)Y=&5S("!R97%U97-T960N("!)9B!T:&ES(&]P=&EO;B!I<PH@("`@" M("`@("`@=7-E9"!P<F]P97)L>2P@FS-M4D1&.B";,&UW;VXG="!E=F5N("!TT M<GD@(&1O("!A8V-E<W,@('1H92`@9&5V:6-E"B`@("`@("`@("!B97EO;F0@, M:71S("!L:6UI="X@($]R('EO=2!C86X@;6%K92!S=7)E('1H870@;VYL>2!A^ M('!A<G0@;V8*("`@("`@("`@('1H92!D979I8V4@8V%N(&)E(&%C8V5S<V5D[ M+B`@5&AE(&1E9F%U;'0@9F]R('1H:7,@;W!T:6]N("!I<PH@("`@("`@("`@R M.#@P:RX@(`H*("`@("`@("`@("`@("`@FS-M4D1&.B]E/&5O9CX@FS!M*'-E> M="!A;F0@;6%I;G1A:6X@82!V:7)T=6%L(&5N9"UO9BUF:6QE*2`*("`@("`@9 M("`@(%1H:7,@(&]P=&EO;B`@<W!E8VEF:65S("!T:&%T()LS;5)$1CH@FS!MF M<VAO=6QD(&UA:6YT86EN(&$@=FER='5A;`H@("`@("`@("`@96YD(&]F(&9I- M;&4@;6%R:V5R+B`@5&AI<R!M86ME<R!A(&9I;&4@;VX@FS-M4D1&.B`@FS!M1 M;&]O:R`@82`@8FET"B`@("`@("`@("!M;W)E(&QI:V4@(&$@(&YO<FUA;"`@! M9&ES:R`@9FEL92X@("!!;GD@871T96UP="!T;R!296%D*"D@;W(*("`@("`@; M("`@(%-E96LH*2!P87-T('1H92!E;F0@;V8@9FEL92!M87)K97(@:7,@<F5J= M96-T960N("!(;W=E=F5R+"`@80H@("`@("`@("`@5W)I=&4H*2`@<&%S="`@^ M=&AE("!E;F0@;V8@9FEL92!M87)K(&ES(&%L;&]W960L(&%N9"!I;B!T:&%T# M"B`@("`@("`@("!C87-E('1H92!E;F0@;V8@9FEL92!I<R!U<&1A=&5D('1O9 M(')E9FQE8W0@=&AA="!T:&4@('9I<G1U86P*("`@("`@("`@(&9I;&4@:&%S$ M("!G<F]W;BX@("`@5&AI<R`@:7,@<&%R=&EC=6QA<GD@=7-E9G5L(&9O<B!P* M<F]G<F%M<PH@("`@("`@("`@=&AA="!3965K*"D@<F5L871I=F4@=&\@=&AE/ M(&5N9"!O9B!T:&4@9FEL92X@("`@5&AE("!D969A=6QT"B`@("`@("`@("!F1 M;W(@('1H:7,@(&]P=&EO;B`@:7,@('1H92`@=F%L=64@9F]R("]L+B!)9B!YD M;W4@<W!E8VEF>2!T:&4*("`@("`@("`@(&]P=&EO;B!W:71H;W5T(&$@=F%L3 M=64L(#`@:7,@87-S=6UE9"X@(`H*("`@("`@("`@("`@("`@FS-M4D1&.B]%+ M()LP;2AG970@96]F(&9R;VT@;&%S="!C;&]S960@9FEL92D@"B`@("`@("`@O M("!3;VUE=&EM97,@:70@;6%Y(&)E(&YE8V5S<V%R>2!T;R!K;F]W+"!H;W<@* M;&%R9V4@=&AE('9I<G1U86P*("`@("`@("`@(&9I;&4@:&%S(&=R;W=N+B`@4 M1F]R(&5X86UP;&4L('EO=2!M87D@;&%T97(@=V%N="!T;R!A9&0@9&%T80H@% M("`@("`@("`@=&\@=&AE(&5N9"X@(%1H97)E9F]R92P@=&AE(&9O;&QO=VEND M9R!H86-K('=A<R!C;VYC96EV960N("`*("`@("`@("`@($EF('EO=2!O<&5N/ M('1H92!F:6QE(%)$1CHO12!A;F0@=&AE;B!R96%D(&%T(&QE87-T(#0@(&)Y& M=&5S+`H@("`@("`@("`@>6]U('=I;&P@9V5T('1H92!E;F0@;V8@9FEL92!V: M86QU92!F<F]M('1H92!L87-T(&-L;W-E9"!F:6QE"B`@("`@("`@("!I;G1O. M('EO=7(@(&)U9F9E<B`@87,@(&$@('-I9VYE9"`@;&]N9W=O<F0N("!4:&4@S M4F5A9"@I('=I;&P*("`@("`@("`@(')E='5R;B`T(&EN('1H:7,@8V%S92X@\ M($]T:&5R=VES92!T:&4@4F5A9"@I('=I;&P@<F5T=7)N("`P+@H@("`@("`@( M("`@26X@86YY("!C87-E+"`@<W5B<V5Q=65N="!296%D*"ES(&%L=V%Y<R!RY M971U<FX@,"X@(%=R:71E*"ES"B`@("`@("`@("!T;R!T:&ES(&9I;&4@87)E8 M(&YO="!A;&QO=V5D+"!A;F0@=&AE(')E<W5L="!I<R!U;F1E9FEN960N("`*> M"@H@("`@("`@("`@("`@("!4:&4@;G5M97)I8R!A<F=U;65N=',@>6]U(&-A_ M;B!S=7!P;'D@=VET:"`@=&AE("!V87)I;W5S"B`@("`@("`@("!O<'1I;VYSW M("!C86X@(&)E("!D96-I;6%L("`H;F\@('!R969I>"DL(&]C=&%L("AP<F5F8 M:7@@,"D@;W(*("`@("`@("`@(&AE>&%D96-I;6%L("AP<F5F:7@@,'@I+B!4# M:&4@:&5X861E8VEM86P@9&EG:71S($$@=&AR;W5G:"`@1@H@("`@("`@("`@8 M;75S="!B92`@9VEV96X@(&EN('5P<&5R8V%S92X@($9O;&QO=VEN9R!T:&4@H M;G5M8F5R+"!A('-C86QE"B`@("`@("`@("!F86-T;W(@;6%Y(&)E(&=I=F5NN M(&EN(&QO=V5R8V%S92X@(%1H92!C=7)R96YT;'D@(')E8V]G;FEZ960*("`@' M("`@("`@('-C86QE<R!A<F4@FS-M;2";,&UF;W(@;65G86)Y=&5S+"";,VUKM M()LP;69O<B!K:6QO8GET97,L()LS;7,@FS!M9F]R('1R86-K9&ES:PH@("`@8 M("`@("`@<V5C=&]R<R!A;F0@FS-M8B";,&UF;W(@8GET97,N("!-=6QT:7!L. M92!F86-T;W)S(&%R92!A;'-O(&%L;&]W960L"B`@("`@("`@("!W:&EC:"!S" M=&%N9"!F;W(@=&AE('!R;V1U8W0@;V8@=&AE:7(@<F5S<&5C=&EV92!F86-T9 M;W)S+B`@"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@E M("`M,BT@("`@("`@("`@("`@("`@("`@("`@(%)E;&5A<V4@,2XP"@H*("`@: M("!21$8H-"D@("`@("`@("`@("`@("`@06UI9V$@4')O9W)A;6UE<B=S($UAD M;G5A;"`@("`@("`@("`@("`@("`@4D1&*#0I"@H*("`@("`@("`@($9O;&QO+ M=VEN9R`@=&AE("!S97%U96YC92`@;V8@('-C86QE("!F86-T;W)S+"`@82`@K M;F5W("!D:6=I=`H@("`@("`@("`@<VEG;FEF:65S('1H870@86YO=&AE<B!N6 M=6UB97(@9F]L;&]W<RX@(%1H870@;G5M8F5R(&ES(&%D9&5D"B`@("`@("`@! M("!T;R!T:&4@=F%L=64@86QR96%D>2!C86QC=6QA=&5D+B`@5&AI<R!I<R!U, M<V5F=6P@=&\@('-P96-I9GD*("`@("`@("`@(&$@=F%L=64@;V8@,C`@2R!PO M;'5S(#,R(&)Y=&5S.B`R,&LS,BX@(`H*("`@("`@("`@("`@("`@06YY=&AI[ M;F<@=&AA="`@:7,@;F]T('!A<G0@;V8@82!N=6UB97(L(&DN92X@(&IU;FL@W M;&EK90H@("`@("`@("`@<W5F9FEX97,@861D960@8GD@<V]M92!P<F]G<F%M5 M<RP@:7,@:6=N;W)E9"X@($%L<V\@(&%N>71H:6YG"B`@("`@("`@("!B971W^ M965N('1H92!C;VQO;B!O9B";,VU21$8Z()LP;6%N9"!T:&4@9FER<W0@<VQA. M<V@@:7,@:6=N;W)E9"P@:6X*("`@("`@("`@(&-A<V4@('EO=2`@=VES:"`@` M=&\@=7-E(&9I;&4@;F%M92!S>6YT87@@8V]M<&%T:6)L92!W:71H('1H90H@_ M("`@("`@("`@<F5S="!O9B!T:&4@<WES=&5M+B`@3VYL>2!T:&4@9FER<W0@2 M;&5T=&5R(&9O;&QO=VEN9R!A('-L87-H"B`@("`@("`@("!I<R`@<VEG;FEFC M:6-A;G0L("!A;F0@(&UU<W0@(&)E("!F;VQL;W=E9"`@9&ER96-T;'D@(&)Y5 M("!A;GD*("`@("`@("`@(')E<75I<F5D(&%R9W5M96YT+B`@"@H@("`@("`@8 M("`@("`@("!9;W4@(&UA>2`@4F5A9"@I(&%N9"!7<FET92@I(&%N>2!N=6UB: M97(@;V8@8GET97,@;VX@86YY"B`@("`@("`@("!O9F9S970N("!)9B!T:&4@G M22]/(&ES(&YO="!S=6ET86)L>2!A;&EG;F5D+"!D871A(&ES("!C;W!I960*5 M("`@("`@("`@('1H<F]U9V@@82`@8G5F9F5R('!R:79A=&4@=&\@4D1&+B`@$ M0F5C875S92!T:&5R92!I<R!O;FQY(&]N90H@("`@("`@("`@<V5C=&]R("`@J M8G5F9F5R+"`@(&%L;"`@(&EN8V]M:6YG("`@<&%C:V5T<R`@(&%R92`@("!H^ M86YD;&5D"B`@("`@("`@("!S>6YC:')O;F]U<VQY+B`@(%1H:7,@(&ES("!T8 M;R`@879O:60@:&%V:6YG(&UU;'1I<&QE($E/17AT5$0*("`@("`@("`@(')E- M<75E<W1S(&]U='-T86YD:6YG+"!W:&EC:"`@;6%Y("!B96-O;64@('%U:71EN M("!C;VUP;&EC871E9`H@("`@("`@("`@=VAE;B`@;75L=&EP;&4@(')E<75E/ M<W1S("!A<F4@(&]U='-T86YD:6YG(&]N('1H92!S86UE(&9I;&4N"B`@("`@^ M("`@("!4:&ES(&ES(&%L<V\@=&AE(&]N;'D@*'-I;7!L92D@=V%Y('1H870@C M(&9U;&P@('-E<FEA;&ES871I;VX*("`@("`@("`@(&]F("!)+T\@('1H<F]UB M9V@@FS-M4D1&.B";,&UC86X@8F4@9W5A<F%N=&5E9"`H=VAI8V@@<V5E;7,@I M=&\@8F4@80H@("`@("`@("`@9V]O9"!T:&EN9RDN("`*"B`@("`@("`@("`@# M("`@($EF('EO=2!W<FET92!A('!A<G1I86P@9&ES:R!B;&]C:RP@(&ET("!IM M<R`@9FER<W0@(')E860*("`@("`@("`@(&EN=&\@('1H92!P<FEV871E(&)U. M9F9E<BP@=&AE;B!M;V1I9FEE9"!A8V-O<F1I;F<@=&\@=&AE($DO3PH@("`@> M("`@("`@<F5Q=65S="P@86YD('1H96X@=W)I='1E;B!B86-K+B`@268@>6]U/ M("!W<FET92`@;6%N>2`@;&ET=&QE"B`@("`@("`@("!P:65C97,L('1H:7,@5 M(&=E=',@=F5R>2!I;F5F9FEC:65N="X@($ET(&-A;FYO="!B92!O<'1I;6EZ^ M960*("`@("`@("`@('1H;W5G:"P@<VEN8V4@('-O;65B;V1Y("!E;'-E("!MX M87D@('=R:71E("!T;R`@=&AE("!D:7-K("!I;@H@("`@("`@("`@8F5T=V5EQ M;BX@(`H*("`@("`@("`@("`@("`@1F]R("!C;VUP871I8FEL:71Y("!W:71HM M("!P<F]G<F%M<R`@=&AA="`@3&]C:R@I(&$@9FEL90H@("`@("`@("`@8F5FN M;W)E("!O<&5N:6YG("!I="P@(&%S("`@<F5C;VUM96YD960@("!I;B`@('1HI M92`@($%M:6=A1$]3"B`@("`@("`@("!$979E;&]P97(G<R`@36%N=6%L("`H: M<V5E($QO8VLH*2!A;F0@3W!E;B@I*2P@>6]U(&-A;B!,;V-K*"D*("`@("`@U M("`@("=F:6QE<R<@;VX@FS-M4D1&.B";,&TN(%1H92!R97-U;'1I;F<@1FEL. M94QO8VL@:7,@(&9A:V4L("!H;W=E=F5R+@H@("`@("`@("`@270@(&ES;B=T' M("!U<V5F=6P@(&%T("!A;&PL("!S:6YC92`@;F\@(&9U;F-T:6]N<R`@<F5Q> M=6ER:6YG"B`@("`@("`@("!&:6QE3&]C:W,@87)E('-U<'!O<G1E9"X@("A/7 M;FQY(%5N3&]C:R@I(&%N9"`@1'5P3&]C:R@I+"`@;V8*("`@("`@("`@(&-O# M=7)S92DN("`@(%-O;64@('!R;V=R86US("!M87D@(&YO="`@;&EK92`@=&AE3 M("`H861M:71T961L>0H@("`@("`@("`@=6YU<W5A;"D@<VET=6%T:6]N('1H5 M870@=&AE>2!S=6-C97-S9G5L;'D@:&%V92`@82`@;&]C:R`@8G5T"B`@("`@W M("`@("!C86YN;W0@17AA;6EN92@I(&ET+B`@*%-E92!T:&4@8G5G<R!S96-T, M:6]N*2X@(`H*("`@("";,6U%6$%-4$Q%4R`*("`@("`@("`@()LP;5EO=2`@( M8V%N("!U<V4@('1H92";,VU21$8Z()LP;6EN=&5R9F%C92!I;B!C;VYJ=6YC! M=&EO;B!W:71H(&$@9FEL90H@("`@("`@("`@87)C:&EV92!P<F]G<F%M(&QI0 M:V4@6F]O+B!4:&ES(&AA<R!T:&4@(&%D=F%N=&%G92`@=&AA="`@>6]U"B`@. M("`@("`@("!H879E(&UO<F4@969F96-T:79E('-P86-E(&]N('EO=7(@9FQO! M<'!Y('1H86X@=VAE;B!Y;W4@=W)I=&4*("`@("`@("`@('1H92`@87)C:&EV& M92`@;VX@=&AE(&1I<VL@=7-I;F<@=&AE($]&4R`H3VQD($9I;&EN9R!3>7-T0 M96TI+@H@("`@("`@("`@06QS;RP@86-C97-S('=I;&P@8F4@9F%S=&5R(&)E+ M8V%U<V4@=&AE<F4@(&ES("!N;R`@;F5E9"`@9F]R"B`@("`@("`@("!E>'1EE M;G-I;VX@(&)L;V-K<R!T;R!T96QL('=H97)E(&5A8V@@8FQO8VL@;V8@=&AEF M(&9I;&4@:7,@;VX*("`@("`@("`@(&1I<VLN("`*("`@("`@("`@($9O<B!E2 M>&%M<&QE+"!T;R!A<F-H:79E(&$@;G5M8F5R(&]F(&9I;&5S(&9R;VT@('1HZ M92`@8W5R<F5N=`H@("`@("`@("`@9&ER96-T;W)Y('1O(&$@<F%W(&9L;W!PV M>3H@"@H@("`@("`@("`@("`@($UO=6YT(%)$1CH*("`@("`@("`@("`@("!:4 M;V\@82!21$8Z+V4@*BYC"@H@("`@("`@("`@5&AE("`N>F]O("!E>'1E;G-I_ M;VX@('1H870@(%IO;R`@861D<R`@=&\@('1H92`@9FEL92!N86UE(&ES"B`@M M("`@("`@("!I9VYO<F5D+"!S:6YC92!I="!I<R!N;W0@82!V86QI9"!N=6UBS M97(N("!4:&4@+V4@(&]P=&EO;B`@:7,*("`@("`@("`@(&YE8V5S<V%R>2`@F M<VEN8V4@(%IO;R`@:7,@(&]N92`@;V8@('1H;W-E('!R;V=R86US('1H870@< M=7-E<PH*"B`@("`@2V]S;6]3;V9T("`@("`@("`@("`@("`@("`@("`@("`@C M+3,M("`@("`@("`@("`@("`@("`@("`@("!296QE87-E(#$N,`H*"B`@("`@; M4D1&*#0I("`@("`@("`@("`@("`@($%M:6=A(%!R;V=R86UM97(G<R!-86YU' M86P@("`@("`@("`@("`@("`@(%)$1B@T*0H*"B`@("`@("`@("!3965K*"ESX M(')E;&%T:79E('1O('1H92!E;F0@;V8@=&AE(&9I;&4N("`*("`@("`@("`@E M($EF('EO=2!M:6=H="!L871E<B!W86YT('1O(&%D9"!S;VUE(&UO<F4@9FELE M97,@=&\@('1H:7,@(')A=PH@("`@("`@("`@87)C:&EV92P@>6]U("!N965D. M("!T;R`@:VYO=R`@=&AE("!E;F0M;V8M9FEL92`@;6%R:RX@("`@66]U"B`@) M("`@("`@("!R971R:65V92!T:&ES('9A;'5E('5S:6YG(`H*("`@("`@("`@5 M("`@("!4>7!E(#P@4D1&.B]%(&]P="!H"@H@("`@("`@("`@5&AI<R!M:6=HT M="!R97-U;'0@:6X@=&AE('9A;'5E(#!X,3=!0B!B96EN9R!D:7-P;&%Y960NM M("!7:&5N"B`@("`@("`@("!Y;W4@;&%T97(@=V%N="!T;R!A9&0@<V]M92!MX M;W)E(&9I;&5S+"!D;R`*"B`@("`@("`@("`@("`@6F]O(&$@4D1&.B]E,'@QH M-T%"("HN:`H*("`@("`@("`@($YO=&4@=&AA="!T:&4@:&5X861E8VEM86P@K M9&EG:71S($$@('1H<F]U9V@@($8@(&UU<W0@(&)E("!I;@H@("`@("`@("`@= M=7!P97(@8V%S92X@(`H@("`@("`@("`@5&\@(&QI<W0@('1H92!C;VYT96YT[ M<R!O9B!T:&4@<F%W(&%R8VAI=F4L('EO=2!U;F9O<G1U;F%T96QY"B`@("`@( M("`@("!C86YN;W0@=7-E(%IO;R!I='-E;&8L('-I;F-E(&ET("AF;W(@=6YKG M;F]W;B!R96%S;VYS*2!A;'=A>7,*("`@("`@("`@(&EN<VES=',@;VX@9&]IG M;F<@86X@($5X86UI;F4H,BDN("!4:&ES("!I<R`@82`@;F]N+7-U<'!O<G1E+ M9`H@("`@("`@("`@9G5N8W1I;VXN("`@26YS=&5A9"P@('EO=2`@;6%Y("!UO M<V4@0F]O>BP@=&AE(&)A<F4M8F]N97,@>F]O"B`@("`@("`@("!E>'1R86-T: M;W(O;&ES=&5R+B`@270@<V5E;7,@=&AA="!";V]Z('5S=6%L;'D@8V%N(&1E` M=&5C="!T:&4*("`@("`@("`@(&QO9VEC86P@96YD(&]F(&%N(&%R8VAI=F4@3 M9G)O;2!I=',@8V]N=&5N=',N("`*"B`@("`@("`@("`@("`@($EF("!Y;W4@` M(&AA=F4@(&$@(&1I<V%S<V5M8FQE<B`@('1H870@("!A8V-E<'1S("`@9FEL2 M97,*("`@("`@("`@(&-O;G1A:6YI;F<@(&UE;6]R>2`@9'5M<',L('EO=2!CZ M86X@9&ES87-S96UB;&4@=&AE(&)O;W1B;&]C:PH@("`@("`@("`@;V8@82!D? M:7-K.B`*"B`@("`@("`@("`@("`@1&ES07-S96UB;&4@4D1&.B]L,6L*"@H@L M("`@()LQ;5-!35!,12!-3U5.5$Q)4U0@"B`@("`@("`@("";,&U21$8Z("`@" M($AA;F1L97(@/2!L.E)$1BU(86YD;&5R"B`@("`@("`@("`@("`@("`@($1E[ M=FEC92`]('1R86-K9&ES:RYD979I8V4*("`@("`@("`@("`@("`@("`@56YIX M="`](#$*("`@("`@("`@("`@("`@("`@1FQA9W,@/2`P"B`@("`@("`@("`@P M("`@("`@(%-T86-K<VEZ92`](#0P.38*("`@("`@("`@("`@("`@("`@4')I6 M;W)I='D@/2`T"B`@("`@("`@("`@("`@("`@($=L;V)696,@(#T@+3$*("`@Y M("`@("`@(",*"B`@("`@FS%M4$%#2T544R!355!03U)4140@"B`@("`@("`@+ M("";,&V;,VU!0U1)3TY?1DE.1%])3E!55*";,&V@H*!);7!L96UE;G1S("`@6 M("!/<&5N*"DN("`@("!$;V5S("`@("`@86X*("`@("`@("`@("`@("`@("`@5 M("`@("`@("`@("`@($]P96Y$979I8V4H*2X@(`H@("`@("`@("`@FS-M04-4> M24].7T9)3D1?3U544%54H)LP;:"@26UP;&5M96YT<R`@("`@($]P96XH*2X@= M("`@($1O97,@("`@(&%N"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@D M("!/<&5N1&5V:6-E*"DN("`@("`@("!3>6YO;GEM("`@("`@("!F;W(*("`@/ M("`@("`@("`@("`@("`@("`@("`@("`@("`@($%#5$E/3E]&24Y$7TE.4%54M M+B`@"B`@("`@("`@("";,VU!0U1)3TY?14Y$H)LP;:"@H*"@H*"@H*!);7!L1 M96UE;G1S("!#;&]S92@I+B!$;V5S(&$@0TU$7U501$%412P*("`@("`@("`@9 M("`@("`@("`@("`@("`@("`@("`@(&$@5$1?34]43U(L('1H96X@82!#;&]SV M941E=FEC92@I+B`@"B`@("`@("`@("";,VU!0U1)3TY?4D5!1*";,&V@H*"@* MH*"@H*!);7!L96UE;G1S(%)E860H*2X@1&]E<R!A;B!%5$1?4D5!1"X@(`H@# M("`@("`@("`@FS-M04-424].7U=2251%H)LP;:"@H*"@H*"@26UP;&5M96YT& M<R`@5W)I=&4H*2X@($1O97,@("AM87EB92`@(&%N"B`@("`@("`@("`@("`@W M("`@("`@("`@("`@("`@("!%5$1?4D5!1"!A;F0@=&AE;BD@86X@151$7U=2W M251%+B`@"B`@("`@("`@("";,VU!0U1)3TY?4T5%2Z";,&V@H*"@H*"@H*!); M;7!L96UE;G1S(%-E96LH*2X@(`H@("`@("`@("`@FS-M04-424].7TQ/0T%41 M15]/0DI%0U2@FS!M26UP;&5M96YT<R`@3&]C:R@I+B`@06QW87ES('-U8V-E] M961S(&EF"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!M96UO<GD@. M8V%N(&)E("!O8G1A:6YE9"`@9F]R("!A("!S=')U8W0*("`@("`@("`@("`@V M("`@("`@("`@("`@("`@("`@($9I;&5,;V-K+B`@"B`@("`@("`@("";,VU!= M0U1)3TY?0T]065]$25*@FS!MH*"@H*!);7!L96UE;G1S($1U<$QO8VLH*2X@< M(`H@("`@("`@("`@FS-M04-424].7T92145?3$]#2Z";,&V@H*"@26UP;&5MH M96YT<R!5;DQO8VLH*2X@(`H@("`@("`@("`@FS-M04-424].7T1%3$5415]/H M0DI%0U2@FS!M26UP;&5M96YT<R`@("`@1&5L971E1FEL92@I+B`@("`@06QW4 M87ES"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!S=6-C965D<RX@4 M($1O97,@;F]T:&EN9RX@(`H@("`@("`@("`@FS-M04-424].7T1)1:";,&V@< MH*"@H*"@H*"@56YL;V%D<R!T:&4@:&%N9&QE<B!F<F]M("!M96UO<GD@(&%F) M=&5R"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@("`M; M-"T@("`@("`@("`@("`@("`@("`@("`@(%)E;&5A<V4@,2XP"@H*("`@("!2! M1$8H-"D@("`@("`@("`@("`@("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A6 M;"`@("`@("`@("`@("`@("`@4D1&*#0I"@H*("`@("`@("`@("`@("`@("`@+ M("`@("`@("`@("`@(&%L;"!F:6QE<R!H879E(&)E96X@8VQO<V5D+B`@"B`@< M("`@("`@("";,VU!0U1)3TY?4D5.04U%7T1)4TN@FS!MH*!3>6YO;GEM("!F5 M;W(@($%#5$E/3E]$244N("!9;W4@(&-A;B!U<V4*("`@("`@("`@("`@("`@$ M("`@("`@("`@("`@("`@("=296QA8F5L("!21$8Z("!X>'@G("!T;R`@('5NI M;&]A9"`@('1H90H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@:&%NB M9&QE<B!F<F]M(&UE;6]R>2X@(`H*("`@("";,6U$24%'3D]35$E#4R`*("`@1 M("`@("`@()LP;5!L96YT>2`@=VAE;B`@8V]M<&EL960@('=I=&@@(&1E8G5G6 M9VEN9R`@96YA8FQE9"P@(&]T:&5R=VES90H@("`@("`@("`@;F]N92X@(`H*R M("`@("";,6U215154DX@0T]$15,@"B`@("`@("`@("";,&U/8G1A:6YE9"!VE M:6$@26]%<G(H*2X@(`H@("`@("`@("`@FS-M15)23U)?4D5!1%]04D]414-44 M142@FS!M;W*@FS-M15)23U)?5U))5$5?4%)/5$5#5$5$H)LP;7=H96X@82!RW M96%D(&]R"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(&$@=W)IH M=&4@97)R;W(@:7,@9&5T96-T960N("!.;R`@;W1H97(*("`@("`@("`@("`@8 M("`@("`@("`@("`@("`@("`@("`@97)R;W(@8V]D92!S965M<R!T;R!C;VUE) M(&-L;W-E+B`@"B`@("`@("`@("";,VU%4E)/4E]$25-+7T953$R@FS!MH*"@' MH*"@H'=H96X@(&%N("!A='1E;7!T("!I<R`@;6%D92`@=&\@=W)I=&4*("`@+ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@8F5Y;VYD('1H92!I;F1IF M8V%T960@<&AY<VEC86P@(&1E=FEC90H@("`@("`@("`@("`@("`@("`@("`@X M("`@("`@("`@("!L:6UI="X@(`H@("`@("`@("`@FS-M15)23U)?4T5%2U]%G M4E)/4J";,&V@H*"@H*!F;W(@:6YV86QI9"!3965K*"ES+B`@"B`@("`@("`@/ M("";,VU%4E)/4E].3U]&4D5%7U-43U)%H)LP;:"@H&%T('-T87)T=7`@:68@] M8G5F9F5R(&UE;6]R>2!C86YN;W0@8F4*("`@("`@("`@("`@("`@("`@("`@G M("`@("`@("`@("`@86QL;V-A=&5D+"!O<B!W:&5N('1H97)E(&ES(&YO(&UE+ M;6]R>0H@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!F;W(@82!&? M:6QE3&]C:RP@86X@24]%>'141"P@971C+B`@"B`@("`@("`@("";,VU%4E)/2 M4E]!0U1)3TY?3D]47TM.3U=.H)LP;69O<B!U;FMN;W=N('!A8VME=',N("`*] M"B`@("`@FS%M0E5'4R`*("`@("`@("`@()LP;41O:6YG("!M=6QT:7!L92`@3 M<W5C8V5S<VEV92`@5W)I=&4H*7,@;V8@82!F97<@8GET97,@:7,@=F5R>0H@W M("`@("`@("`@:6YE9F9I8VEE;G0N("!4:&4@<V%M92!I<R!T<G5E(&9O<B!2N M96%D*"DL('1H;W5G:"`@;&5S<R`@<V\N"B`@("`@("`@("!4:&ES("!I<R`@; M8F5C875S92`@86QL("!D979I8V4@($DO3R`@9V]E<R`@=&AR;W5G:"`@=&AEX M('-A;64*("`@("`@("`@(&)U9F9E<BX@(`H@("`@("`@("`@3F]T(')E86QLC M>2!A(&)U9R!O9B";,VU21$8Z()LP;6)U="!A;FYO>6EN9R`@86YY=V%Y.B`@W M57-I;F<@("A!<G`I"B`@("`@("`@("!465!%("!21$8Z("!/4%0@($@L("!47 M>7!E("!,;V-K*"ES("!T:&4@(&9I;&4L('1H96X@=V%N=',@=&\*("`@("`@1 M("`@($5X86UI;F4H*2!I="P@<')E<W5M86)L>2!T;R!S964@:68@:70@:7,@- M(&YO="`@82`@9&ER96-T;W)Y+`H@("`@("`@("`@8G5T('1H870@(&ES("!N# M;W0@(&$@<W5P<&]R=&5D(&9U;F-T:6]N+B`@5&AE;B!I="!F;W)G971S('1OG M"B`@("`@("`@("!5;DQO8VLH*2!T:&4@(&QO8VL@(&%G86EN+"`@=VAI8V@@0 M('=A<W1E<R`@<V]M92`@;65M;W)Y("!A;F0*("`@("`@("`@('!R;VAI8FETB M<R`@=&AE("!H86YD;&5R("!F<F]M("!B96EN9R`@=6YL;V%D960@(&9R;VT@K M;65M;W)Y+@H@("`@("`@("`@0F5W87)E(&]F(&]T:&5R('!R;V=R86US('1HE M870@86-T('5N<&]L:71E('=H96X@9F%C960@=VET:"!A"B`@("`@("`@("!&/ M:6QE3&]C:R!T:&%T('1H97D@8V%N;F]T($5X86UI;F4H*2X@(`H@("`@("`@A M("`@5&AE(&UO=&]R(&]F('1H92!D<FEV92!S:&]U;&0@<&5R:6]D:6-A;&QYR M(&)E('1U<FYE9"!O9F8N("`*("`@("`@("`@($UO<F4@('1I;64@('=A<R`@Y M('-P96YT("`@<')O;V9R96%D:6YG("`@=&AE("`@;6%N=6%L("`@=&AA;@H@> M("`@("`@("`@<')O;V9R96%D:6YG('1H92!P<F]G<F%M+B`@"@H@("`@()LQ' M;5-%12!!3%-/(`H@("`@("`@("`@FS!M6F]O*#$I+"`@0F]O>B@Q*2P@($%R< M8R@Q*2P@('1A<B@Q*2P@(&%R*#$I+"!T<F%C:V1I<VLN9&5V:6-E"B`@("`@O M("`@("`H4F]M("!+97)N86P@(%)E9F5R96YC92`@36%N=6%L.B`@3&EB<F%R6 M:65S("`@86YD("`@1&5V:6-E<RP*("`@("`@("`@($%U=&]D;V-S*2P@("!!E M;6EG841/4R`@(&UA;G5A;"P@("!-871T97<@("!$:6QL;VXG<R`@(%!)4$4Z$ M+`H@("`@("`@("`@8V]M<"YS;W5R8V5S+FUA='0M9&EL;&]N(&EN(&=E;F5R2 M86PN("`*"@H*"@H*"@H*"@H*"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@@ M("`@("`@("`@("`@("`M-2T@("`@("`@("`@("`@("`@("`@("`@(%)E;&5A8 (<V4@,2XP"@H@[ `` end size 15983 SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.