Date : Wed, 16 Sep 1987 09:21:00 EDT
From : Stride 440 User <HELLER%cs.umass.edu@RELAY.CS.NET>
Subject: Re: Search first/search next
Your main problem is still trying to do File I/O while in the midst of
the search. You need to *complete* searching for *all* files, *then* do
your File I/O. The following C code should clarify things (I don't use
assembly, and am not really up on 8080/Z80 assembler (my system is a
68000 and I run CP/M-68K, which works much like CP/M 2.2):
/* FCB structure */
typedef struct {
char drive; /* drive code */
char fname[8]; /* file name */
char ftype[3]; /* file type */
char unused[21]; /* filler (32-byte FCB) */
} FCB;
/* result FCBs will end up in the DMA buffer, which is treated like
an array of 4 FCBs */
static FCB seabuf[4];
/* input FCB */
static FCB infcb;
/* the function __BDOS calls bdos. takes two args: a function code
and a parameter. (CP/M-68K passes the function code in D0 and a long
word (32-bits) in D1 as the parameter.)
*/
extern int __BDOS();
/* linked list of FCBs - list of names found */
typedef struct flist {
FCB file;
struct flist *next;
} FLIST;
/* memory allocator */
char *malloc();
/* search function */
FLIST *find_all_files()
{
register FLIST *result,*new; /* name list pointers */
register int status; /* status code
register int i,j; /* some lose ints */
register char *p,*q; /* char (byte) pointers */
infcb.drive = 0; /* current drive */
for (p=infcb.fname,i=0; i < 8; i++, p++) *p = '?'; fill in filename
for (p=infcb.ftype,i=0; i < 3; i++, p++) *p = '?'; fill in filetype
for (p=infcb.unused,i=0; i < 21; i++, p++) *p = '\0'; fill in rest of FCB
__BDOS(SETDMA,&seabuf); /* set DMA address to result buffer */
result = 0L; /* null pointer */
status = __BDOS(SEARCHFIRST,&infcb); /* start off search */
while (status != 0x00FF) { /* found a file? */
new = (FLIST *) malloc(sizeof(FLIST)); /* allocate some memory */
if (new == 0L) { /* memory allocate error */
perror("find_all_files (malloc)");
abort(0);
}
/* copy found FCB over */
for (p = &seabuf[0], q = new->file, i=0; i < sizeof(FCB); p++,q++,i++)
*q = *p;
/* add to front of list */
new->next = result;
result = new;
status = __BDOS(SEARCHNEXT,0L); /* search again */
} /* end of while loop */
return(result); /* return pointer to list of file names. */
/* note that the list is in reverse order. One of
features of using a linked list structure with
prepending in an interative loop. I am assuming
that the order does not really matter. If it does,
then the result accumulating code should be
*/
}
The above function will generate a list of all files on the current drive.
I used symbolic names for the function codes (don't have my CP/M manuals
here at work) and assume long word pointers (CP/M-68K). The important thing
is this: you need to find ALL of the filenames BEFORE doing ANY file I/O.
All bets are off if you use OPEN, CLOSE, DELETE, MAKE, RENAME, READ, WRITE,
READRANDOM, WRITERANDOM, etc. while in the midst of a search first/search
next cycle. The DIR command has an easy job: it just does console I/O
between searches. STAT and PIP, must acclumulate some sort of name list
and then loop down this list. Note, if you don't want to mess with
allocating memory and linked lists, you can simply set assign a name
only buffer and copy the filenames from the search buffer, using some
sort of separater character (i.e. a null character), using a name counter
and a working pointer.
Robert Heller
ARPANet: Heller@CS.UMass.EDU
BITNET: Heller@UMass.BITNET
BIX: Heller
GEnie: RHeller
FidoNet: 321/148 (Locks Hill BBS, Wendell, MA)
CompuServe 71450,3432
Local PV VAXen: COINS::HELLER
UCC Cyber/DG: Heller@CS