home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dmake40.zip / emx / dcache.c < prev    next >
C/C++ Source or Header  |  1994-11-02  |  3KB  |  138 lines

  1. #include "extern.h"
  2. #include <dirent.h>
  3. #include "sysintf.h"
  4.  
  5. typedef struct ent {
  6.    char    *name;
  7.    time_t  mtime;
  8.    int     isdir;
  9.    struct ent *next;
  10. } Entry, *EntryPtr;
  11.  
  12.  
  13. typedef struct mydir {
  14.    char         *path;
  15.    uint32        hkey;
  16.    EntryPtr      entries;
  17.    struct mydir *next;
  18. } DirEntry, *DirEntryPtr;
  19.  
  20. static DirEntryPtr dtab[HASH_TABLE_SIZE];
  21.  
  22.  
  23. /* Stat a path using the directory cache.
  24.  *
  25.  * We build a cannonical representation of the path using either an absolute
  26.  * path name if that is what 'path' is or the relative path name constructed
  27.  * from 'path' and the present value of Pwd.
  28.  *
  29.  * The present value of Pwd then gives a directory path that we search for
  30.  * in our cache using a hash lookup.  If the directory component is located
  31.  * then we search the basename component of the path and return the result of
  32.  * the search:  0L if the component is not in the cache and it's time stamp
  33.  * otherwise.
  34.  *
  35.  * If the directory is not in our cache we insert it into the cache by
  36.  * openning the directory and reading all of the files within.  Once read
  37.  * then we return the result of the above search.
  38.  *
  39.  * Optionally, if force is TRUE, and we did NOT read the directory to provide
  40.  * the result then stat the file anyway and update the internal cache.
  41.  */
  42.  
  43. PUBLIC time_t
  44. CacheStat(path, force)
  45. char        *path;
  46. int          force;
  47. {
  48.    struct stat stbuf;
  49.    DirEntryPtr dp;
  50.    EntryPtr    ep;
  51.    uint32 hkey;
  52.    uint16 hv;
  53.    char *fpath;
  54.    char *comp;
  55.    char *dir;
  56.    int  loaded=FALSE;
  57.  
  58.    if (If_root_path(path))
  59.       fpath = path;
  60.    else
  61.       fpath = Build_path(Pwd,path);
  62.  
  63.    dir  = Filedir(DmStrDup(fpath));
  64.    comp = DmStrDup(Basename(fpath));
  65.  
  66.    hv = Hash(dir,&hkey);
  67.  
  68.    for(dp=dtab[hv]; dp; dp=dp->next)
  69.       if (hkey == dp->hkey && stricmp(dp->path,dir) == 0)
  70.      break;
  71.  
  72.    if (!dp) {
  73.       DIR *dirp;
  74.       struct dirent *direntp;
  75.  
  76.       if( Verbose & V_DIR_CACHE )
  77.      printf( "%s:  Caching directory [%s]\n", Pname, dir  );
  78.  
  79.       /* Load the directory, we have the right hash position already */
  80.       loaded = TRUE;
  81.  
  82.       TALLOC(dp,1,DirEntry);
  83.       dp->next = dtab[hv];
  84.       dtab[hv] = dp;
  85.       dp->path = DmStrDup(dir);
  86.       dp->hkey = hkey;
  87.  
  88.       if (Set_dir(dir) == 0) {
  89.      if((dirp=opendir(dir)) != NIL(DIR)) {
  90.         while((direntp=readdir(dirp)) != NULL) {
  91.            TALLOC(ep,1,Entry);
  92.            ep->name = DmStrDup(direntp->d_name);
  93.            ep->next = dp->entries;
  94.            dp->entries = ep;
  95.            STAT(direntp->d_name,&stbuf);
  96.            ep->isdir = (stbuf.st_mode & S_IFDIR);
  97.            ep->mtime = stbuf.st_mtime;
  98.         }
  99.         closedir(dirp);
  100.      }
  101.      Set_dir(Pwd);
  102.       }
  103.    }
  104.  
  105.    if (dp) {
  106.       for(ep=dp->entries; ep; ep=ep->next)
  107.      if(stricmp(ep->name,comp) == 0)
  108.         break;
  109.    }
  110.    else
  111.       ep = NULL;
  112.  
  113.    if( force && !loaded) {
  114.       if( Verbose & V_DIR_CACHE )
  115.      printf("%s:  Updating dir cache entry for [%s]\n", Pname, fpath);
  116.  
  117.       if (strlen(comp) > NameMax || STAT(fpath,&stbuf) != 0) {
  118.      if(ep)
  119.         ep->mtime = 0L;
  120.       }
  121.       else {
  122.      if (!ep) {
  123.         TALLOC(ep,1,Entry);
  124.         ep->name = DmStrDup(comp);
  125.         ep->next = dp->entries;
  126.         ep->isdir = (stbuf.st_mode & S_IFDIR);
  127.         dp->entries = ep;
  128.      }
  129.  
  130.      ep->mtime = stbuf.st_mtime;
  131.       }
  132.    }
  133.  
  134.    FREE(dir);
  135.    FREE(comp);
  136.    return((!ep || (Augmake && ep->isdir)) ? 0L : ep->mtime);
  137. }
  138.