home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cidsam.zip / FINDFILE.C < prev    next >
C/C++ Source or Header  |  1993-06-28  |  10KB  |  178 lines

  1.                   /*********************************/
  2.                   /*              NOTE             */
  3.                   /*                               */
  4.                   /* This sample code has been     */
  5.                   /* provided by IBM.  It is not   */
  6.                   /* warranted for any particular  */
  7.                   /* use or purpose.               */
  8.                   /*                               */
  9.                   /* IBM releases this code into   */
  10.                   /* the public domain.  You may   */
  11.                   /* use it, modify it, or         */
  12.                   /* incorporate it into other     */
  13.                   /* products without restriction. */
  14.                   /*********************************/
  15.  
  16.  /*********************************************************************/
  17.  /*                                                                   */
  18.  /* MODULE  NAME:    findfile.c                                       */
  19.  /*                                                                   */
  20.  /* DESCRIPTIVE NAME: Contains routine CID_findfile()                 */
  21.  /*                                                                   */
  22.  /* LINKAGE:   This is a linkable subroutine. It requires no other    */
  23.  /*            linkages.                                              */
  24.  /*                                                                   */
  25.  /*********************************************************************/
  26. #pragma page (1)
  27. /**************************************************************************
  28. * Given a file spec, find the first file that satisfies it.               *
  29. *                                                                         *
  30. *    The algorithem is:  look on the current directory.                   *
  31. *    If it's not there, and the filespec was fully qualified, return      *
  32. *    file-not-found.                                                      *
  33. *    If it's not there but the filespec was relative, look up the DPATH   *
  34. *    concatenate the file with each directory listed there, and search    *
  35. *    for the resultant fully qualified name.                              *
  36. *    If it's still not found, look up the PATH and search on each         *
  37. *    directory listed there.                                              *
  38. *                                                                         *
  39. *    The file spec can be ambiguous.  Only the first file that satisfies  *
  40. *    the spec will be returned.                                           *
  41. *                                                                         *
  42. *    Returns a pointer to the fully-qualified file name if successful,    *
  43. *    or NULL if the file was not found.  The reason the file was not      *
  44. *    found is not returned.  It could be because the file does not exist  *
  45. *    or because an I/O error prevented access.  It could also be that     *
  46. *    there is not enough memory left to store the file name.              *
  47. *                                                                         *
  48. *    THIS CODE IS FINE FOR PORTABILITY, BUT SHOULD BE REPLACED BY CALLS   *
  49. *    TO DosSearchPath() IN THE OS/2 ENVIRONMENT.  IT WILL BE, PRETTY      *
  50. *    QUICK.                                                               *
  51. **************************************************************************/
  52.  
  53. /*************************************************************************/
  54. /* Modification history:                                                 */
  55. /*                                                                       */
  56. /* Marker  PTR    Who  When     Why                                      */
  57. /*   U1           grb 09/27/91 mallocing 1 byte too few in ff_make_fqname*/
  58. /*   R1           grb 09/30/91 Incorporated comments from code review    */
  59. /*   U2           grb 10/30/91 Algorithem failed for roots of drives     */
  60. /*   A2           grb 05/06/93 Port to 32-bit IBM C++ compiler           */
  61. /*************************************************************************/
  62. #pragma page (1)
  63.  
  64. #define INCL_BASE
  65. #include <os2.h>
  66. #include <stdlib.h>
  67. #include <string.h>
  68. #include "findfile.h"
  69.  
  70. char *CID_findfile(char *filespec)
  71. {
  72.     char *fqname, *sname, *p, *q, *ep;
  73.     int  fslen, rc, epi;                                        /*@R1c*/
  74.     #define ENVPATHS 2
  75.     char *envlist[ENVPATHS] = { "DPATH", "PATH"};
  76.     HDIR handle;
  77. #ifdef I16                                                      /*@A2a*/
  78.     FILEFINDBUF ffb;
  79.     USHORT count;                                               /*@R1a*/
  80. #else                                                           /*@A2a*/                                                                                                  /*@A2a*/
  81.     FILEFINDBUF3 ffb;                                           /*@A2a*/
  82.     ULONG  count;                                               /*@R1a*/
  83. #endif                                                          /*@A2a*/ 
  84.  
  85.     fqname = (char *)NULL;
  86.     fslen = strlen(filespec);
  87. /* STEP 1:  look on current working directory */
  88.     count = 1;
  89.     handle = 1;
  90. #ifdef I16                                                      /*@A2a*/ 
  91.     if ( (rc = DosFindFirst((PSZ)filespec, &handle,             /*@R1c*/
  92.              FILE_SYSTEM | FILE_HIDDEN,
  93.              &ffb, sizeof(FILEFINDBUF), &count, 0l)) == NO_ERROR)
  94. #else
  95.     if ( (rc = DosFindFirst((PSZ)filespec, &handle,             /*@R1c*/
  96.              FILE_SYSTEM | FILE_HIDDEN,
  97.              &ffb, sizeof(FILEFINDBUF3), &count, 1l)) == NO_ERROR)
  98. #endif
  99.                     /* FIle was found on the current directory */
  100.       fqname = ff_make_fqname(filespec, ffb.achName);
  101.     else            /* file is not on current DIRECTORY */
  102.        {                /* if it's fully qualified, we're out of here */
  103.          if (*filespec != PATH_SEPC && *(filespec + CHARSIZE) != DRIVE_SEPC)
  104.  
  105. /* STEP 2:  look on DPATH and PATH */
  106.                                            /* for each path variable */
  107.             for (epi = 0; epi < ENVPATHS && !fqname; epi++)
  108.               {
  109.                  ep = getenv(envlist[epi]);   /* get envir variable */
  110.                  if (ep)
  111.                    while (*ep)                  /* for each path element */
  112.                      {                            /* find end of path element */                     for (p = ep; *p && *p != ';'; p++);
  113.                         if (!(p = strchr(ep, ENVPATH_SEPC)) )
  114.                           p = ep + strlen(ep);
  115.                                                /* make space for it */
  116.                         sname = (char *)malloc(p - ep + fslen + CHARLENT2);
  117.                         if (sname)
  118.                           {                                    /* copy it */
  119.                             for (q = sname; ep != p; *q++ = *ep++);
  120.                             if (*ep)          /* point to start of next path */
  121.                               ep += CHARSIZE;
  122.                             if (*(q-1) != PATH_SEPC)              /*@U2a*/
  123.                               {                                   /*@U2a*/
  124.                                 strcpy(q,PATH_SEPS); /* put in the path seperator */
  125.                                 q += strlen(PATH_SEPS);
  126.                               }                                   /*@U2a*/
  127.                             strcpy(q, filespec);   /* put in the file spec */
  128.                                               /* Is the file on this path? */
  129.                             count = 1;
  130.                             handle = 1;
  131.                             if ( (rc = DosFindFirst((PSZ)sname, &handle,/*@R1c*/
  132.                               FILE_SYSTEM | FILE_HIDDEN,
  133.                               &ffb, sizeof(FILEFINDBUF), &count, 0l))
  134.                                                                   == NO_ERROR)
  135.                               {    /* seperate the path from the file name */
  136.                                 fqname = ff_make_fqname(sname, ffb.achName);
  137.                                 break;   /* get out of the WHILE loop */
  138.                               }
  139.                             else              /* No, it's not */
  140.                               {
  141.                                 fqname = (char *)NULL;
  142.                               }
  143.                             free(sname);
  144.                           }   /* end IF memory was available */
  145.                      }   /* end WHILE more paths in this variable */
  146.               }   /* end FOR all variables */
  147.        }   /* end IF file was not local */
  148.    return(fqname);
  149. }
  150.  
  151. #pragma page (1)
  152.  
  153. /**************************************************************************
  154. *   Strip  the file name (possibly ambiguous) off a file specification,   *
  155. *   and append in its place a resolved file name                          *
  156. **************************************************************************/
  157. char *ff_make_fqname(char *ambig_name, char *resolv_name)
  158. {
  159.    char *p, *q1, *q2, *fqname;
  160.  
  161.    if (!(p = strrchr(ambig_name, PATH_SEPC)) )
  162.            if (!(p = strrchr(ambig_name, DRIVE_SEPC)) )
  163.               p = ambig_name;     /* seperate the path from the file name */
  164.  
  165.    fqname = (char *)malloc(p - ambig_name + strlen(resolv_name) + 2);/*U1c*/
  166.    if (fqname)
  167.      {
  168.        for (q1 = ambig_name, q2 = fqname; q1 != p; *q2++ = *q1++);
  169.        if (*p == DRIVE_SEPC)                                       /* @A1a2 */
  170.          *q2++ = *p;
  171.        *q2 = '\0';      /* null terminate the path portion of the fq name */
  172.        if (*p == '\\')
  173.            strcat(fqname, PATH_SEPS);
  174.        strcat(fqname, resolv_name);
  175.      }
  176.    return(fqname);
  177. }
  178.