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

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