<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
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
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>