home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / source / util2src / ffind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-15  |  8.1 KB  |  210 lines

  1. /*============================================================================*
  2.  * module: FFIND.C - File Find functions.
  3.  *
  4.  * (C)Copyright IBM Corporation, 1987, 1988, 1991.         Brian E. Yoder
  5.  *
  6.  * Functions contained in this module:
  7.  *   findfirst() - Find first matching file.
  8.  *   findnext()  - Find next matching file.
  9.  *
  10.  * NOTES ON OPERATION:
  11.  *
  12.  * The findfirst() and findnext() functions use the DOS function calls by the
  13.  * same name to find files whose names match a given file specification.
  14.  *
  15.  * The file information structure type FINFO contains the file information
  16.  * returned by findfirst() and findnext().  The findfirst() function finds
  17.  * the first matching file and copies the file information to the FINFO
  18.  * structure type that the caller provides.  The findnext() function finds
  19.  * the next matching file, based on the FINFO structure type that the caller
  20.  * provides.
  21.  *
  22.  * DO NOT MODIFY the FINFO structure type set up by findfirst() and findnext():
  23.  * It is set up and used by DOS to perform the actual directory searches!!!
  24.  *
  25.  * When this function was first written, it used the DOS function GET_DTA to
  26.  * get the current DTA address.  However, when the DOS function FIND_FIRST was
  27.  * called and there was a match, DOS did NOT return from the INT 21 (inside the
  28.  * intdosx() function)!!  That is why a new DTA is set using the DOS function
  29.  * SET_DTA.
  30.  *
  31.  * Before the findnext() function invokes DOS to find the next matching file,
  32.  * it invokes the DOS SET_DTA command again to reset the DTA.  This is necessary
  33.  * since some C library functions (notably stat()!) change the DTA address!
  34.  *
  35.  * 11/03/87 - Initial version.
  36.  * 11/10/87 - Return DOS return code if error, 0 if no error.
  37.  * 04/26/88 - Updated for large model.
  38.  * 04/04/91 - Ported to C/2, and added pathcat().
  39.  * 04/05/91 - Added isdir() and decompose subroutines.
  40.  * 04/16/91 - Split out non-find functions into the futil.c module.
  41.  *============================================================================*/
  42. #define LINT_ARGS
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <dos.h>
  48. #include <sys\types.h>
  49. #include <sys\stat.h>
  50.  
  51. #include "util.h"
  52.  
  53. /*============================================================================*
  54.  * Static data
  55.  *============================================================================*/
  56.  
  57. static char  attribute;          /* Attribute byte to use when matching */
  58. static char  newdta[1024];       /* New DTA */
  59.  
  60. /*----------------------------------------------------------------------------*
  61.  * DOS Functions for INT 21
  62.  *----------------------------------------------------------------------------*/
  63.  
  64. #define SET_DTA      0x1A
  65. #define GET_DTA      0x2F
  66. #define FIND_FIRST   0x4E
  67. #define FIND_NEXT    0x4F
  68.  
  69.  
  70. /*============================================================================*
  71.  * findfirst() - Find first matching file.
  72.  *
  73.  * REMARKS:
  74.  *   This function finds the first file whose name matches 'fspec' and whose
  75.  *   attribute byte matches 'attrib'.  The following, taken from the DOS
  76.  *   manual, describes how the attribute is used during the search:
  77.  *
  78.  *      If the attribute is zero, only normal file entries are found.
  79.  *      Volume labels, subdirectories, hidden files, and system files
  80.  *      are ignored.
  81.  *
  82.  *      If the attribute is set for system files, hidden files, or directories,
  83.  *      the search includes these files as well.
  84.  *
  85.  *      If the attribute is set for the volume label, the search is exclusive,
  86.  *      and only the volume label is found.
  87.  *
  88.  *   The file information is copied to the FINFO structure type specified by
  89.  *   the caller.
  90.  *
  91.  * RETURNS:
  92.  *   Pointer to the FINFO structure type specified by the caller, if a match was
  93.  *   found.  The structure is filled in with the file's information.  Do not
  94.  *   modify the data in this structure: you will need it for findnext()!
  95.  *
  96.  *   NULL, if no matching file was found.
  97.  *============================================================================*/
  98. int findfirst(fspec, attrib, finfo)
  99.  
  100. char  *fspec;          /* Pointer to file specification to match */
  101. char   attrib;         /* Attribute to use when searching */
  102. FINFO *finfo;          /* Pointer to caller's file info. structure */
  103.  
  104. {
  105.   int rc;                 /* Storage for return codes */
  106.   union REGS regs;        /* Registers for intdos(), intdosx() */
  107.   struct SREGS segregs;   /* Segment registers for intdosx() */
  108.   char *dta;              /* Pointer to a DTA */
  109.  
  110.   dta = newdta;           /* Store pointer to newdat, for FP_ macros */
  111.  
  112.   attribute = attrib;   /* Save file attribute */
  113.  
  114.   segread(&segregs);    /* Store current values of segment registers */
  115.  
  116.   /* Set up a new DTA address */
  117.  
  118.   regs.h.ah = SET_DTA;              /* Set DOS function */
  119.   regs.x.dx = FP_OFF(dta);
  120.   segregs.ds = FP_SEG(dta);
  121.   intdosx(®s, ®s, &segregs);
  122.  
  123.   /* Find first filename that matches 'fspec' */
  124.  
  125.   regs.h.ah = FIND_FIRST;           /* Find first matching file */
  126.   regs.x.dx = FP_OFF(fspec);
  127.   segregs.ds = FP_SEG(fspec);
  128.   regs.h.cl = attribute;
  129.   regs.h.ch = 0;
  130.   intdosx(®s, ®s, &segregs);
  131.  
  132.   rc = (int)regs.x.cflag;           /* If carry flag set: Error: */
  133.   if (rc != 0) {
  134.     rc = regs.x.ax;                 /*   Set rc = DOS error code, */
  135.     switch (rc) {
  136.         case EF_NOFILE:
  137.         case EF_NOPATH:
  138.         case EF_NOMORE:
  139.             break;
  140.         default:                    /*   ignore add'l error codes from */
  141.             rc = EF_NOMORE;         /*   future DOS versions (if any!) */
  142.             break; }
  143.     return(rc); }                   /*   Return DOS Error code */
  144.  
  145.   memcpy((char *)finfo,             /* Copy the file information from the DTA */
  146.           newdta,                   /* to the caller's file info. structure */
  147.           sizeof(FINFO));
  148.  
  149.   return(0);                        /* Return 0: successful */
  150. }
  151.  
  152. /*============================================================================*
  153.  * findnext() - Find next matching file.
  154.  *
  155.  * REMARKS:
  156.  *   This function finds the next file whose name matches the criteria is a
  157.  *   valid FINFO file information structure.
  158.  *
  159.  *   The findfirst() function should be used to set up a valid FINFO file
  160.  *   information structure.  Repeated calls to findnext() can be made using
  161.  *   any one of the valid file information structures you may have.
  162.  *
  163.  * RETURNS:
  164.  *   0, if a match was found.  The file information is copied to the structure
  165.  *   specified on the call.  Do not modify it: you will need it for your next
  166.  *   call to findnext()!
  167.  *
  168.  *   EF_NOMORE, if no more matching files found.
  169.  *============================================================================*/
  170. int findnext(finfo)
  171.  
  172. FINFO *finfo;          /* Pointer to caller's file info. structure */
  173.  
  174. {
  175.   int rc;                 /* Storage for return codes */
  176.   union REGS regs;        /* Registers for intdos(), intdosx() */
  177.   struct SREGS segregs;   /* Segment registers for intdosx() */
  178.   char *dta;              /* Pointer to a DTA */
  179.  
  180.   dta = newdta;           /* Store pointer to newdat, for FP_ macros */
  181.  
  182.   /* Reset the DTA address */
  183.  
  184.   regs.h.ah = SET_DTA;              /* Set DOS function */
  185.   regs.x.dx = FP_OFF(dta);
  186.   segregs.ds = FP_SEG(dta);
  187.   intdosx(®s, ®s, &segregs);
  188.  
  189.   /* Copy previous file info [from findfirst() or findnext()] to the DTA */
  190.  
  191.   memcpy(newdta,                    /* Copy the file information to the DTA */
  192.           (char *)finfo,            /* from the caller's file info. structure */
  193.           sizeof(FINFO));
  194.  
  195.   /* Find next filename that matches 'fspec' */
  196.  
  197.   regs.h.ah = FIND_NEXT;            /* Find next matching file */
  198.   intdosx(®s, ®s, &segregs);
  199.  
  200.   rc = (int)regs.x.cflag;           /* If carry flag set: Error: */
  201.   if (rc != 0)
  202.     return(EF_NOMORE);              /*   Return null pointer  */
  203.  
  204.   memcpy((char *)finfo,             /* Copy the file information from the DTA */
  205.           newdta,                   /* to the caller's file info. structure */
  206.           sizeof(FINFO));
  207.  
  208.   return(0);                        /* Return 0: successful */
  209. }
  210.