Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!sri-spam!mordor!lll-tis!ptsfa!ihnp4!ihlpa!qix From: qix@ihlpa.ATT.COM (Puckett) Newsgroups: comp.sys.amiga Subject: Re: MCC pipes Message-ID: <4402@ihlpa.ATT.COM> Date: Thu, 25-Jun-87 10:26:33 EDT Article-I.D.: ihlpa.4402 Posted: Thu Jun 25 10:26:33 1987 Date-Received: Sat, 27-Jun-87 02:08:01 EDT References: <8706240726.AA06112@cory.Berkeley.EDU> Organization: AT&T Bell Laboratories - Naperville, Illinois Lines: 188 In article <8706240726.AA06112@cory.Berkeley.EDU>, dillon@CORY.BERKELEY.EDU (Matt Dillon) writes: > >Does your new PIPE: support the packets Examine and ExNext use? If so, then you > >could just "dir pipe:" to get a list of active pipes, right? > > I've been trying... and trying... and trying... I can't figure > out why it is crashing.... Can somebody post a *working* device driver > which uses Examine/ExNext???? P: supports these. Here is a fragment of the code. The complete sources have been posted to comp.sources.amiga and sent to Fred Fish. Hope this helps. -Ed Puckett. /*--------------------------------------------------------------------------- ** PipeExamine() responds to Examine requests. For locks on the handler, the ** address first item of the pipelist is stored in the DiskKey field for ** PipeExNext()'s reference. */ void PipeExamine (pkt) struct DosPacket *pkt; { struct FileInfoBlock *fib; struct FileLock *lock; PIPEDATA *pipe; void FillFIB(); pkt->dp_Res1= 1; /* no error, for now */ pkt->dp_Res2= 0; fib= (struct FileInfoBlock *) BPTRtoCptr (pkt->dp_Arg2); if ((lock= (struct FileLock *) BPTRtoCptr (pkt->dp_Arg1)) == NULL) { pkt->dp_Res1= 0; pkt->dp_Res2= ERROR_OBJECT_NOT_FOUND; } else { if ((pipe= (PIPEDATA *) lock->fl_Key) == NULL) /* then this is a lock on the handler */ { FillFIB ( fib, FirstItem (&pipelist), HandlerName, (FIBF_EXECUTE | FIBF_DELETE), 1, 0, 0, &PipeDate ); } else { FillFIB ( fib, NULL, pipe->name, (FIBF_EXECUTE | FIBF_DELETE), -1, pipe->buf->len, 1, &pipe->accessdate ); } } ReplyPkt (pkt); } /*--------------------------------------------------------------------------- ** PipeExNext() responds to ExNext requests. The DiskKey field of the ** FileInfoBlock is assumed to be a pointer to the next pipe in the pipelist ** which is to be listed in the directory. We then scan pipelist for this ** pointer, and upon finding it, store its information in the FileInfoBlock ** and store the address of the next pipe in pipelist in the DiskKey field. ** If the pipe is not found in the list, or if DiskKey is NULL, then ** ERROR_NO_MORE_ENTRIES is returned. ** By rescanning the list each time, deletion of a pipe cannot hurt us ** by causing a dangling pointer in DiskKey -- we just end the directory ** listing there. This can cause incomplete directory information for the ** cleint, however, if the last listed pipe is deleted before the client's ** next ExNext() call. */ void PipeExNext (pkt) struct DosPacket *pkt; { struct FileLock *lock; struct FileInfoBlock *fib; PIPEDATA *listitem, *pipe; void FillFIB(); pkt->dp_Res1= 0; /* error, for now */ if ((lock= (struct FileLock *) BPTRtoCptr (pkt->dp_Arg1)) == NULL) { pkt->dp_Res2= ERROR_INVALID_LOCK; goto EXNEXTREPLY; } if (lock->fl_Key != NULL) /* then an individual pipe */ { pkt->dp_Res2= ERROR_OBJECT_WRONG_TYPE; goto EXNEXTREPLY; } pkt->dp_Res2= ERROR_NO_MORE_ENTRIES; /* until found otherwise */ fib= (struct FileInfoBlock *) BPTRtoCptr (pkt->dp_Arg2); if ((listitem= (PIPEDATA *) fib->fib_DiskKey) == NULL) goto EXNEXTREPLY; for (pipe= (PIPEDATA *) FirstItem (&pipelist); pipe != NULL; pipe= (PIPEDATA *) NextItem (pipe)) if (listitem == pipe) break; if (listitem == pipe) /* then found next entry */ { FillFIB ( fib, NextItem (listitem), listitem->name, (FIBF_EXECUTE | FIBF_DELETE), -1, listitem->buf->len, 1, &listitem->accessdate ); pkt->dp_Res1= 1; pkt->dp_Res2= 0; } EXNEXTREPLY: ReplyPkt (pkt); } /*--------------------------------------------------------------------------- ** PipeParentDir() responds to ParentDir requests. */ void PipeParentDir (pkt) struct DosPacket *pkt; { struct FileLock *lock; void InitPipedirLock(); InitPipedirLock (); pkt->dp_Res2= 0; if ((lock= (struct FileLock *) BPTRtoCptr (pkt->dp_Arg1)) == NULL) { pkt->dp_Res1= 0; pkt->dp_Res2= ERROR_INVALID_LOCK; } else { if (lock->fl_Key == NULL) /* then lock is on handler */ pkt->dp_Res1= 0; /* root of current filing system */ else pkt->dp_Res1= CptrtoBPTR (PipedirLock); } ReplyPkt (pkt); } * * * * * /*--------------------------------------------------------------------------- ** FillFIB() fills a FileInfoBlock with the specified information. Note ** that handlers must store BSTR's in the FileInfoBlock. */ static void FillFIB (fib, DiskKey, FileName, Protection, Type, Size, NumBlocks, Datep) struct FileInfoBlock *fib; LONG DiskKey; char *FileName; /* null-terminated */ LONG Protection; LONG Type; LONG Size; LONG NumBlocks; struct DateStamp *Datep; { fib->fib_DiskKey= DiskKey; fib->fib_DirEntryType= Type; CstrtoBSTR (FileName, fib->fib_FileName, sizeof (fib->fib_FileName)); fib->fib_Protection= Protection; fib->fib_EntryType= Type; /* ??? */ fib->fib_Size= Size; fib->fib_NumBlocks= NumBlocks; CopyMem (Datep, &fib->fib_Date, sizeof (struct DateStamp)); fib->fib_Comment[0]= '\0'; /* empty BSTR */ }