home *** CD-ROM | disk | FTP | other *** search
- /*============================================================================*
- * module: FFIND.C - File Find functions.
- *
- * (C)Copyright IBM Corporation, 1987, 1988, 1991. Brian E. Yoder
- *
- * Functions contained in this module:
- * findfirst() - Find first matching file.
- * findnext() - Find next matching file.
- *
- * NOTES ON OPERATION:
- *
- * The findfirst() and findnext() functions use the DOS function calls by the
- * same name to find files whose names match a given file specification.
- *
- * The file information structure type FINFO contains the file information
- * returned by findfirst() and findnext(). The findfirst() function finds
- * the first matching file and copies the file information to the FINFO
- * structure type that the caller provides. The findnext() function finds
- * the next matching file, based on the FINFO structure type that the caller
- * provides.
- *
- * DO NOT MODIFY the FINFO structure type set up by findfirst() and findnext():
- * It is set up and used by DOS to perform the actual directory searches!!!
- *
- * When this function was first written, it used the DOS function GET_DTA to
- * get the current DTA address. However, when the DOS function FIND_FIRST was
- * called and there was a match, DOS did NOT return from the INT 21 (inside the
- * intdosx() function)!! That is why a new DTA is set using the DOS function
- * SET_DTA.
- *
- * Before the findnext() function invokes DOS to find the next matching file,
- * it invokes the DOS SET_DTA command again to reset the DTA. This is necessary
- * since some C library functions (notably stat()!) change the DTA address!
- *
- * 11/03/87 - Initial version.
- * 11/10/87 - Return DOS return code if error, 0 if no error.
- * 04/26/88 - Updated for large model.
- * 04/04/91 - Ported to C/2, and added pathcat().
- * 04/05/91 - Added isdir() and decompose subroutines.
- * 04/16/91 - Split out non-find functions into the futil.c module.
- *============================================================================*/
- #define LINT_ARGS
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <sys\types.h>
- #include <sys\stat.h>
-
- #include "util.h"
-
- /*============================================================================*
- * Static data
- *============================================================================*/
-
- static char attribute; /* Attribute byte to use when matching */
- static char newdta[1024]; /* New DTA */
-
- /*----------------------------------------------------------------------------*
- * DOS Functions for INT 21
- *----------------------------------------------------------------------------*/
-
- #define SET_DTA 0x1A
- #define GET_DTA 0x2F
- #define FIND_FIRST 0x4E
- #define FIND_NEXT 0x4F
-
-
- /*============================================================================*
- * findfirst() - Find first matching file.
- *
- * REMARKS:
- * This function finds the first file whose name matches 'fspec' and whose
- * attribute byte matches 'attrib'. The following, taken from the DOS
- * manual, describes how the attribute is used during the search:
- *
- * If the attribute is zero, only normal file entries are found.
- * Volume labels, subdirectories, hidden files, and system files
- * are ignored.
- *
- * If the attribute is set for system files, hidden files, or directories,
- * the search includes these files as well.
- *
- * If the attribute is set for the volume label, the search is exclusive,
- * and only the volume label is found.
- *
- * The file information is copied to the FINFO structure type specified by
- * the caller.
- *
- * RETURNS:
- * Pointer to the FINFO structure type specified by the caller, if a match was
- * found. The structure is filled in with the file's information. Do not
- * modify the data in this structure: you will need it for findnext()!
- *
- * NULL, if no matching file was found.
- *============================================================================*/
- int findfirst(fspec, attrib, finfo)
-
- char *fspec; /* Pointer to file specification to match */
- char attrib; /* Attribute to use when searching */
- FINFO *finfo; /* Pointer to caller's file info. structure */
-
- {
- int rc; /* Storage for return codes */
- union REGS regs; /* Registers for intdos(), intdosx() */
- struct SREGS segregs; /* Segment registers for intdosx() */
- char *dta; /* Pointer to a DTA */
-
- dta = newdta; /* Store pointer to newdat, for FP_ macros */
-
- attribute = attrib; /* Save file attribute */
-
- segread(&segregs); /* Store current values of segment registers */
-
- /* Set up a new DTA address */
-
- regs.h.ah = SET_DTA; /* Set DOS function */
- regs.x.dx = FP_OFF(dta);
- segregs.ds = FP_SEG(dta);
- intdosx(®s, ®s, &segregs);
-
- /* Find first filename that matches 'fspec' */
-
- regs.h.ah = FIND_FIRST; /* Find first matching file */
- regs.x.dx = FP_OFF(fspec);
- segregs.ds = FP_SEG(fspec);
- regs.h.cl = attribute;
- regs.h.ch = 0;
- intdosx(®s, ®s, &segregs);
-
- rc = (int)regs.x.cflag; /* If carry flag set: Error: */
- if (rc != 0) {
- rc = regs.x.ax; /* Set rc = DOS error code, */
- switch (rc) {
- case EF_NOFILE:
- case EF_NOPATH:
- case EF_NOMORE:
- break;
- default: /* ignore add'l error codes from */
- rc = EF_NOMORE; /* future DOS versions (if any!) */
- break; }
- return(rc); } /* Return DOS Error code */
-
- memcpy((char *)finfo, /* Copy the file information from the DTA */
- newdta, /* to the caller's file info. structure */
- sizeof(FINFO));
-
- return(0); /* Return 0: successful */
- }
-
- /*============================================================================*
- * findnext() - Find next matching file.
- *
- * REMARKS:
- * This function finds the next file whose name matches the criteria is a
- * valid FINFO file information structure.
- *
- * The findfirst() function should be used to set up a valid FINFO file
- * information structure. Repeated calls to findnext() can be made using
- * any one of the valid file information structures you may have.
- *
- * RETURNS:
- * 0, if a match was found. The file information is copied to the structure
- * specified on the call. Do not modify it: you will need it for your next
- * call to findnext()!
- *
- * EF_NOMORE, if no more matching files found.
- *============================================================================*/
- int findnext(finfo)
-
- FINFO *finfo; /* Pointer to caller's file info. structure */
-
- {
- int rc; /* Storage for return codes */
- union REGS regs; /* Registers for intdos(), intdosx() */
- struct SREGS segregs; /* Segment registers for intdosx() */
- char *dta; /* Pointer to a DTA */
-
- dta = newdta; /* Store pointer to newdat, for FP_ macros */
-
- /* Reset the DTA address */
-
- regs.h.ah = SET_DTA; /* Set DOS function */
- regs.x.dx = FP_OFF(dta);
- segregs.ds = FP_SEG(dta);
- intdosx(®s, ®s, &segregs);
-
- /* Copy previous file info [from findfirst() or findnext()] to the DTA */
-
- memcpy(newdta, /* Copy the file information to the DTA */
- (char *)finfo, /* from the caller's file info. structure */
- sizeof(FINFO));
-
- /* Find next filename that matches 'fspec' */
-
- regs.h.ah = FIND_NEXT; /* Find next matching file */
- intdosx(®s, ®s, &segregs);
-
- rc = (int)regs.x.cflag; /* If carry flag set: Error: */
- if (rc != 0)
- return(EF_NOMORE); /* Return null pointer */
-
- memcpy((char *)finfo, /* Copy the file information from the DTA */
- newdta, /* to the caller's file info. structure */
- sizeof(FINFO));
-
- return(0); /* Return 0: successful */
- }
-