home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
dmake40.zip
/
emx
/
dcache.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-02
|
3KB
|
138 lines
#include "extern.h"
#include <dirent.h>
#include "sysintf.h"
typedef struct ent {
char *name;
time_t mtime;
int isdir;
struct ent *next;
} Entry, *EntryPtr;
typedef struct mydir {
char *path;
uint32 hkey;
EntryPtr entries;
struct mydir *next;
} DirEntry, *DirEntryPtr;
static DirEntryPtr dtab[HASH_TABLE_SIZE];
/* Stat a path using the directory cache.
*
* We build a cannonical representation of the path using either an absolute
* path name if that is what 'path' is or the relative path name constructed
* from 'path' and the present value of Pwd.
*
* The present value of Pwd then gives a directory path that we search for
* in our cache using a hash lookup. If the directory component is located
* then we search the basename component of the path and return the result of
* the search: 0L if the component is not in the cache and it's time stamp
* otherwise.
*
* If the directory is not in our cache we insert it into the cache by
* openning the directory and reading all of the files within. Once read
* then we return the result of the above search.
*
* Optionally, if force is TRUE, and we did NOT read the directory to provide
* the result then stat the file anyway and update the internal cache.
*/
PUBLIC time_t
CacheStat(path, force)
char *path;
int force;
{
struct stat stbuf;
DirEntryPtr dp;
EntryPtr ep;
uint32 hkey;
uint16 hv;
char *fpath;
char *comp;
char *dir;
int loaded=FALSE;
if (If_root_path(path))
fpath = path;
else
fpath = Build_path(Pwd,path);
dir = Filedir(DmStrDup(fpath));
comp = DmStrDup(Basename(fpath));
hv = Hash(dir,&hkey);
for(dp=dtab[hv]; dp; dp=dp->next)
if (hkey == dp->hkey && stricmp(dp->path,dir) == 0)
break;
if (!dp) {
DIR *dirp;
struct dirent *direntp;
if( Verbose & V_DIR_CACHE )
printf( "%s: Caching directory [%s]\n", Pname, dir );
/* Load the directory, we have the right hash position already */
loaded = TRUE;
TALLOC(dp,1,DirEntry);
dp->next = dtab[hv];
dtab[hv] = dp;
dp->path = DmStrDup(dir);
dp->hkey = hkey;
if (Set_dir(dir) == 0) {
if((dirp=opendir(dir)) != NIL(DIR)) {
while((direntp=readdir(dirp)) != NULL) {
TALLOC(ep,1,Entry);
ep->name = DmStrDup(direntp->d_name);
ep->next = dp->entries;
dp->entries = ep;
STAT(direntp->d_name,&stbuf);
ep->isdir = (stbuf.st_mode & S_IFDIR);
ep->mtime = stbuf.st_mtime;
}
closedir(dirp);
}
Set_dir(Pwd);
}
}
if (dp) {
for(ep=dp->entries; ep; ep=ep->next)
if(stricmp(ep->name,comp) == 0)
break;
}
else
ep = NULL;
if( force && !loaded) {
if( Verbose & V_DIR_CACHE )
printf("%s: Updating dir cache entry for [%s]\n", Pname, fpath);
if (strlen(comp) > NameMax || STAT(fpath,&stbuf) != 0) {
if(ep)
ep->mtime = 0L;
}
else {
if (!ep) {
TALLOC(ep,1,Entry);
ep->name = DmStrDup(comp);
ep->next = dp->entries;
ep->isdir = (stbuf.st_mode & S_IFDIR);
dp->entries = ep;
}
ep->mtime = stbuf.st_mtime;
}
}
FREE(dir);
FREE(comp);
return((!ep || (Augmake && ep->isdir)) ? 0L : ep->mtime);
}