Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
651
cde/lib/DtHelp/FileUtils.c
Normal file
651
cde/lib/DtHelp/FileUtils.c
Normal file
@@ -0,0 +1,651 @@
|
||||
/* $TOG: FileUtils.c /main/8 1998/07/28 15:37:38 mgreess $ */
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: FileUtils.c
|
||||
**
|
||||
** Project: File locating
|
||||
**
|
||||
** Description: Locates files (volumes) accessible via the
|
||||
** known paths
|
||||
**
|
||||
** NOTE: this file must remain free of Xt & Xm calls.
|
||||
**
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
|
||||
/*
|
||||
* system includes
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h> /* MAXPATHLEN */
|
||||
|
||||
#include <Dt/Help.h>
|
||||
|
||||
/*
|
||||
* private includes
|
||||
*/
|
||||
#include "bufioI.h" /* for AccessI.h */
|
||||
#include "Access.h" /* CompressPathname */
|
||||
#include "AccessI.h" /* ExpandPathname */
|
||||
#include "HelpP.h" /* for DtDEFAULT_xxx */
|
||||
#include "HelposI.h" /* for search path access */
|
||||
#include "StringFuncsI.h"
|
||||
#include "FileUtilsI.h"
|
||||
#include "Lock.h"
|
||||
|
||||
/******** constants *********/
|
||||
#define LANG_C_STR "C"
|
||||
#define DIR_SLASH '/'
|
||||
#define EOS '\0'
|
||||
|
||||
/******** types *********/
|
||||
|
||||
/******** public global variables *********/
|
||||
const char * _DtHelpFileSuffixList[3] = {
|
||||
DtHelpSDL_VOL_SUFFIX,
|
||||
DtHelpCCDF_VOL_SUFFIX,
|
||||
NULL };
|
||||
|
||||
/******** variables *********/
|
||||
static const char * EmptyStr = "";
|
||||
#ifdef not_used
|
||||
static const char * PeriodStr = ".";
|
||||
#endif
|
||||
static const char * DirSlashStr = "/";
|
||||
static const char * PathSeparator = ":";
|
||||
static const _DtHelpCeDirStruct DefCacheDir = { NULL, ENOTDIR, 0, NULL };
|
||||
|
||||
static _DtHelpCeDirStruct *CachedDirs = NULL;
|
||||
|
||||
/******** functions *********/
|
||||
#define MyNewString(s) (NULL != s ? strdup((char *)s) : NULL)
|
||||
#define MyRealloc(p,s) (NULL != (p) ? realloc((char *)p,s) : malloc(s) )
|
||||
#define MyMalloc(s) malloc(s)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Function: MyFree()
|
||||
*
|
||||
* locate the '.' of the filename extension, if present
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void MyFree(char * ptr)
|
||||
{
|
||||
if(ptr) free(ptr);
|
||||
}
|
||||
|
||||
|
||||
#ifdef not_used
|
||||
/*****************************************************************************
|
||||
* Function: GetExtension()
|
||||
*
|
||||
* locate the '.' of the filename extension, if present
|
||||
*
|
||||
*****************************************************************************/
|
||||
static char * GetExtension(
|
||||
char * filename)
|
||||
{
|
||||
char * ext;
|
||||
if (_DtHelpCeStrrchr(filename,PeriodStr,MB_CUR_MAX,&ext) == 0 ) return ext;
|
||||
else return ""; /* do NOT return a NULL*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Function: SpecialStrcmp()
|
||||
*
|
||||
* Tests the args for NULL pointers. If both are NULL or if
|
||||
* both aren't NULL and are the same string, then returns 0.
|
||||
* If one arg is NULL and other isn't, or if strings are
|
||||
* different, returns -1 or +1.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static int SpecialStrcmp(
|
||||
const char * str1,
|
||||
const char * str2)
|
||||
{
|
||||
if(NULL == str1)
|
||||
{
|
||||
if(NULL == str2) return 0; /* str1 == str2 */
|
||||
return -1; /* str1 < str2 */
|
||||
}
|
||||
if(NULL == str2) return 1; /* str1 > str2 */
|
||||
return(strcmp(str1,str2)); /* str1 ? str2 */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Function: _DtHelpFileTraceLinks (pathName)
|
||||
*
|
||||
* Purpose: Traces pathname through all symbolic links
|
||||
* until a real file is found or the link is
|
||||
* found to be invalid.
|
||||
*
|
||||
* Returns: True if file found at end of link, False if not
|
||||
*
|
||||
* Memory: pathName must point to a malloc'd string. The string
|
||||
* may be freed by the function and pathName assigned a pointer
|
||||
* to a different string specifying a different path to the same file.
|
||||
* If a file is found, foundPath is set to the same pointer
|
||||
* as pathName, otherwise it is set to NULL.
|
||||
***********************************************************************/
|
||||
Boolean
|
||||
_DtHelpFileTraceLinks (
|
||||
char * * pPathName)
|
||||
{
|
||||
int result = 0;
|
||||
char curBuf;
|
||||
char * linkPath;
|
||||
char * filePath;
|
||||
char buf [2][MAXPATHLEN+2]; /* 2K+ bytes on stack */
|
||||
|
||||
if ( NULL == *pPathName ) return False; /* RETURN */
|
||||
|
||||
/* init */
|
||||
strcpy(buf[0],*pPathName);
|
||||
linkPath = buf[0]; /* will be assigned to filePath below */
|
||||
curBuf = 1; /* next valid buf */
|
||||
|
||||
/* find out if this path is a symbolic link */
|
||||
while ( result >= 0 )
|
||||
{
|
||||
/* exchange buffer ptrs and toggle index */
|
||||
filePath = linkPath;
|
||||
linkPath = buf[curBuf % 2];
|
||||
curBuf++;
|
||||
|
||||
/* get the link info */
|
||||
result = readlink (filePath, linkPath, MAXPATHLEN);
|
||||
|
||||
/* check for the result of the readlink call */
|
||||
if (result == -1)
|
||||
{
|
||||
/* if newPath is not a symbolic link, errno != EINVAL */
|
||||
if (errno != EINVAL)
|
||||
return False; /* RETURN */
|
||||
|
||||
/* filePath is not a sym link ==> a real file or directory */
|
||||
/* so return filePath in caller-owned memory */
|
||||
if ( curBuf != 1 ) /* curBuf == 1 when pPathName is a file */
|
||||
{
|
||||
/*
|
||||
* pPathName had memory allocated before this function was called.
|
||||
* only increase the memory if needed.
|
||||
*/
|
||||
if ( strlen (*pPathName) < strlen(filePath) )
|
||||
*pPathName = (char *)realloc((void *)*pPathName, (sizeof(char)
|
||||
* (strlen(filePath) +1)));
|
||||
|
||||
strcpy(*pPathName, filePath);
|
||||
}
|
||||
/* printf("actual is: %s\n", filePath); ** DBG */
|
||||
return True; /* RETURN */
|
||||
} /* if an error */
|
||||
else
|
||||
{ /* no error--handle the link */
|
||||
|
||||
/* if the path is absolute, just take it as such */
|
||||
linkPath [result] = EOS; /* for safety */
|
||||
|
||||
/* is path relative to current directory? */
|
||||
if ( linkPath[0] != DIR_SLASH )
|
||||
{
|
||||
char * slash = NULL;
|
||||
|
||||
/* get last slash in the current file path */
|
||||
if(_DtHelpCeStrrchr(filePath,DirSlashStr,MB_CUR_MAX,&slash) == 0)
|
||||
{ /* there is a path comonent in filePath; use it with linkPath */
|
||||
strcpy(++slash,linkPath);
|
||||
strcpy(linkPath,filePath); /* leave result in linkPath */
|
||||
}
|
||||
} /* if path is relative */
|
||||
/* printf("traced to: %s\n", linkPath); ** DBG */
|
||||
} /* if no error */
|
||||
} /* while result >= 0 */
|
||||
return False; /* RETURN */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Function: _DtHelpFileTraceToFile (pathName, accessMode, foundPath)
|
||||
*
|
||||
* Memory: pPathName must point to a malloc'd string. The string
|
||||
* may be freed by the function and pathName assigned a pointer
|
||||
* to a different string specifying a different path to the same file.
|
||||
* If a file is found, foundPath is set to the same pointer
|
||||
* as pathName, otherwise it is set to NULL.
|
||||
* Returns:
|
||||
* True: file found
|
||||
* False: file not found or error
|
||||
***********************************************************************/
|
||||
Boolean
|
||||
_DtHelpFileTraceToFile (
|
||||
char * * pPathName,
|
||||
int accessMode,
|
||||
char * * pFoundPath)
|
||||
{
|
||||
struct stat status;
|
||||
char * pathName = *pPathName; /* avoid indirection */
|
||||
|
||||
*pFoundPath = NULL;
|
||||
if ( pathName == NULL || pathName[0] == EOS )
|
||||
return False;
|
||||
|
||||
/* if it's a file, trace its links */
|
||||
if ( access (pathName, accessMode) == 0
|
||||
&& stat (pathName, &status) == 0
|
||||
&& S_ISREG(status.st_mode) ) /* a file */
|
||||
{
|
||||
/* trace any links */
|
||||
if ( _DtHelpFileTraceLinks(pPathName) == False )
|
||||
{
|
||||
/* don't free pPathName here */
|
||||
return False; /* RETURN: no file */
|
||||
}
|
||||
pathName = *pPathName;
|
||||
|
||||
/* find out if its an accessible file */
|
||||
if ( pathName != NULL
|
||||
&& pathName[0] != EOS
|
||||
&& access (pathName, accessMode) == 0
|
||||
&& stat (pathName, &status) == 0
|
||||
&& S_ISREG(status.st_mode)) /* a file */
|
||||
{
|
||||
/* point foundPath at the path */
|
||||
*pFoundPath = pathName;
|
||||
return True; /* RETURN: its a file */
|
||||
} /* if a valid path */
|
||||
} /* if a path */
|
||||
|
||||
#if 0
|
||||
printf("Unknown file: %s\n", pathName);
|
||||
printf("Access: %d, stat: %d, IS_REG: %d, mode: %x\n",
|
||||
access (pathName, accessMode),
|
||||
stat (pathName, &status),
|
||||
S_ISREG(status.st_mode),
|
||||
status.st_mode);
|
||||
#endif
|
||||
|
||||
/* its not a file */
|
||||
*pFoundPath = NULL;
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: int _DtHelpFileGetSearchPaths ()
|
||||
*
|
||||
* Parameters:
|
||||
* paths: caller array size _DtHELP_FILE_NUM_PATHS in which
|
||||
* to store ptrs to the private path strings
|
||||
* searchHomeDir: boolean flag
|
||||
*
|
||||
* Memory:
|
||||
* the memory pointed to by the array is NOT owned by the
|
||||
* caller and should not be freed or modified
|
||||
*
|
||||
* Purpose: make the search paths available
|
||||
*
|
||||
*****************************************************************************/
|
||||
void _DtHelpFileGetSearchPaths(
|
||||
char * paths[],
|
||||
Boolean searchHomeDir)
|
||||
{
|
||||
static char * pathsSet[_DtHELP_FILE_NUM_PATHS];
|
||||
char tmpPath[MAXPATHLEN + 2];
|
||||
|
||||
/* get user's home directory; is used in _DtHELP_FILE_USER_PATH as well */
|
||||
if (NULL == pathsSet[_DtHELP_FILE_HOME_PATH])
|
||||
{
|
||||
_DtHelpOSGetHomeDirName(tmpPath, sizeof(tmpPath));
|
||||
pathsSet[_DtHELP_FILE_HOME_PATH] = strdup(tmpPath);
|
||||
}
|
||||
if (searchHomeDir)
|
||||
paths[_DtHELP_FILE_HOME_PATH] = pathsSet[_DtHELP_FILE_HOME_PATH];
|
||||
else
|
||||
paths[_DtHELP_FILE_HOME_PATH] = NULL;
|
||||
|
||||
/* generate the user path */
|
||||
if (NULL == pathsSet[_DtHELP_FILE_USER_PATH])
|
||||
pathsSet[_DtHELP_FILE_USER_PATH] = _DtHelpGetUserSearchPath();
|
||||
paths[_DtHELP_FILE_USER_PATH] = pathsSet[_DtHELP_FILE_USER_PATH];
|
||||
|
||||
/* get the system search path */
|
||||
if (NULL == pathsSet[_DtHELP_FILE_SYS_PATH])
|
||||
pathsSet[_DtHELP_FILE_SYS_PATH] = _DtHelpGetSystemSearchPath();
|
||||
paths[_DtHELP_FILE_SYS_PATH] = pathsSet[_DtHELP_FILE_SYS_PATH];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: char * _DtHelpFileLocate ()
|
||||
*
|
||||
* Parameters:
|
||||
* type: subdirectories to search (%T)
|
||||
* base: basename of the file
|
||||
* suffix: extension of the file to find (%S)
|
||||
* searchCurDir: boolean flag
|
||||
* accessMode: constant value from access(2)
|
||||
*
|
||||
* Returns: malloc'd path of the located file or NULL if none located
|
||||
*
|
||||
* errno Values:
|
||||
* EINVAL
|
||||
*
|
||||
* Purpose: Scans all paths of given type looking for a matching file
|
||||
* If file contains a valid absolute path, that is also
|
||||
* acceptible.
|
||||
*
|
||||
* FIX: merge _DtHelpFileLocate() and _DtHelpFileListScanPaths()
|
||||
*****************************************************************************/
|
||||
char * _DtHelpFileLocate (
|
||||
char * type,
|
||||
char * filespec,
|
||||
const char * suffixList[],
|
||||
Boolean searchCurDir,
|
||||
int accessMode)
|
||||
{
|
||||
char * loc;
|
||||
char * ptr;
|
||||
char * pathName;
|
||||
char * curPath;
|
||||
char * base;
|
||||
int curPathIndex;
|
||||
char * foundPath;
|
||||
const char empty = 0;
|
||||
const char * sufList[2];
|
||||
#define NUM_BUGS 1
|
||||
_DtSubstitutionRec bugFixSubs [NUM_BUGS];
|
||||
char * paths[_DtHELP_FILE_NUM_PATHS];
|
||||
char tmpPath[MAXPATHLEN + 2];
|
||||
const char * * pSuffix;
|
||||
char * eos = NULL;
|
||||
char * slash = NULL;
|
||||
|
||||
/* test args */
|
||||
if (NULL == filespec) return NULL;
|
||||
|
||||
/* init suffix list to empty if not specified */
|
||||
if (suffixList == NULL)
|
||||
{
|
||||
sufList[0] = ∅
|
||||
sufList[1] = NULL;
|
||||
suffixList = sufList; /* override initial argument setting */
|
||||
}
|
||||
|
||||
/*** first look for file as specified ***/
|
||||
/* if filespec begins with . or .. then stop after the cwd path */
|
||||
if ( ( MB_CUR_MAX == 1
|
||||
|| mblen(filespec, MB_CUR_MAX) == 1) /* 1st char is 1 byte */
|
||||
&& *filespec == '/') /* and its a / */
|
||||
{
|
||||
/* _DtHelpFileTraceToFile() needs a malloc'd string */
|
||||
/* 10: leaves room for add'l suffixes */
|
||||
pathName = MyMalloc(sizeof(char) * (strlen(filespec)+10));
|
||||
pathName = strcpy(pathName,filespec);
|
||||
_DtHelpCeCompressPathname(pathName); /* compress out relative paths */
|
||||
if ( _DtHelpFileTraceToFile(&pathName,accessMode,&foundPath) )
|
||||
return foundPath; /* RETURN */
|
||||
|
||||
/* test all suffixes */
|
||||
eos = pathName + strlen(pathName);
|
||||
for ( pSuffix = suffixList; NULL != *pSuffix; pSuffix++ )
|
||||
{
|
||||
strcpy(eos,(char *) *pSuffix);
|
||||
/*recall: _DtHelpFileTraceToFile() requires pathName to be malloc'd*/
|
||||
if ( _DtHelpFileTraceToFile(&pathName,accessMode,&foundPath) )
|
||||
return foundPath; /* RETURN: found */
|
||||
} /* for all suffixes */
|
||||
|
||||
MyFree(pathName);
|
||||
}
|
||||
|
||||
/*** second, check if its relative to the current directory ***/
|
||||
/* if filespec begins with . or .. then stop after the cwd path */
|
||||
if ( searchCurDir
|
||||
|| ( MB_CUR_MAX == 1
|
||||
|| mblen(filespec, MB_CUR_MAX) == 1) /* 1st char is 1 byte */
|
||||
&& *filespec == '.') /* and its a . */
|
||||
{ /* we're looking at a cwd-relative path; ignore others */
|
||||
/*** this is monstrously inefficient--but it shouldn't get called often ***/
|
||||
|
||||
/* get user's current working directory */
|
||||
if (getcwd(tmpPath, MAXPATHLEN) == NULL) return NULL; /* RETURN: error */
|
||||
|
||||
/* make path end in a slash */
|
||||
eos = tmpPath + strlen(tmpPath);
|
||||
_DtHelpCeStrrchr(tmpPath,DirSlashStr,MB_CUR_MAX,&slash);
|
||||
if ( slash != (eos - 1) ) { *eos++ = DIR_SLASH; *eos = EOS; }
|
||||
|
||||
/* make a malloc'd copy of the path with room to grow */
|
||||
slash = filespec + strlen(filespec);
|
||||
pathName = malloc(sizeof(char) *
|
||||
((eos-tmpPath) + (slash-filespec) + 50) ); /* 50: arbitrary */
|
||||
if (NULL == pathName) return NULL; /* RETURN: error */
|
||||
strcpy(pathName,tmpPath);
|
||||
|
||||
/* cat on the relative path */
|
||||
strcat(pathName,filespec);
|
||||
|
||||
/* compress out any relative paths */
|
||||
_DtHelpCeCompressPathname(pathName);
|
||||
|
||||
/* see if we find the file now */
|
||||
/* recall: _DtHelpFileTraceToFile() requires pathName to be malloc'd */
|
||||
if ( _DtHelpFileTraceToFile(&pathName,accessMode,&foundPath) )
|
||||
return foundPath; /* RETURN: found */
|
||||
|
||||
/* test all suffixes */
|
||||
eos = pathName + strlen(pathName);
|
||||
for ( pSuffix = suffixList; NULL != *pSuffix; pSuffix++ )
|
||||
{
|
||||
strcpy(eos,(char *) *pSuffix);
|
||||
/* recall: _DtHelpFileTraceToFile() requires pathName to be malloc'd */
|
||||
if ( _DtHelpFileTraceToFile(&pathName,accessMode,&foundPath) )
|
||||
return foundPath; /* RETURN: found */
|
||||
} /* for all suffixes */
|
||||
MyFree(pathName);
|
||||
return NULL; /* RETURN: error */
|
||||
} /* filespec is a relative path or search cur dir */
|
||||
|
||||
/*** third look in search path directories ***/
|
||||
|
||||
/* get the search paths */
|
||||
_DtHelpFileGetSearchPaths( paths, False );
|
||||
|
||||
/*** prep variables to pass through the path search loop ***/
|
||||
/* we're not looking at a cwd-relative path and
|
||||
we know that 'filespec' isn't a valid path to a volume
|
||||
(from _DtHelpFileTraceToFile), so just pick off the
|
||||
basename of the spec */
|
||||
base = filespec;
|
||||
if ( _DtHelpCeStrrchr(filespec,DirSlashStr,MB_CUR_MAX,&ptr) == 0 )
|
||||
base = ++ptr; /* begin past the slash */
|
||||
|
||||
/* Have to support %H explicitly */
|
||||
bugFixSubs[0].match = 'H';
|
||||
bugFixSubs[0].substitution = base;
|
||||
|
||||
/* get the LANG value */
|
||||
loc = _DtHelpGetLocale();
|
||||
if (NULL == loc || EOS == loc[0]) loc = strdup(LANG_C_STR);
|
||||
|
||||
/* outer loop is once for each path */
|
||||
foundPath = NULL;
|
||||
for ( curPathIndex = 0;
|
||||
curPathIndex < _DtHELP_FILE_NUM_PATHS && NULL == foundPath;
|
||||
curPathIndex++ )
|
||||
{
|
||||
curPath = paths[curPathIndex];
|
||||
if (NULL == curPath) continue; /* continue */
|
||||
|
||||
/* look for the file in that path */
|
||||
if (NULL != curPath) do
|
||||
{
|
||||
/* look for next subpath separator and insert and EOS if found */
|
||||
if (_DtHelpCeStrchr(curPath,PathSeparator,MB_CUR_MAX,&ptr)==0)
|
||||
*ptr = EOS;
|
||||
|
||||
/* compress that path */
|
||||
strcpy(tmpPath,curPath);
|
||||
_DtHelpCeCompressPathname(tmpPath);
|
||||
|
||||
/* test all suffixes */
|
||||
for ( pSuffix = suffixList, foundPath = NULL;
|
||||
NULL == foundPath && NULL != *pSuffix;
|
||||
pSuffix++ )
|
||||
{
|
||||
/* generate the (directory) path using all the variables and fix
|
||||
it up to remove the unwanted stuff involving the filename */
|
||||
pathName = _DtHelpCeExpandPathname (curPath, base, type,
|
||||
(char *) *pSuffix, loc, bugFixSubs, NUM_BUGS);
|
||||
|
||||
if ( _DtHelpFileTraceToFile(&pathName,accessMode,&foundPath)==False
|
||||
&& NULL != pathName)
|
||||
free(pathName);
|
||||
|
||||
} /* for all suffixes */
|
||||
|
||||
/* restore the subpath separator and advance past it */
|
||||
if (ptr) *ptr++ = *PathSeparator;
|
||||
|
||||
curPath = ptr;
|
||||
} while (curPath && *curPath && NULL == foundPath);
|
||||
/* do while more subpaths */
|
||||
|
||||
} /* for all paths */
|
||||
|
||||
MyFree(loc);
|
||||
return foundPath;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: int _DtHelpCeCheckAndCacheDir (char *dir)
|
||||
*
|
||||
* Parameters:
|
||||
* dir Specifies the directory to test.
|
||||
*
|
||||
* Returns: 0 if the directory exists.
|
||||
* ENOTDIR if the directory is invalid.
|
||||
*
|
||||
* Purpose: To check a directory only once and remember the result.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int
|
||||
_DtHelpCeCheckAndCacheDir (char *dir)
|
||||
{
|
||||
int result = ENOTDIR;
|
||||
_DtHelpCeDirStruct *curDir = CachedDirs;
|
||||
_DtHelpCeDirStruct *prevDir = NULL;
|
||||
struct stat buf;
|
||||
|
||||
_DtHelpProcessLock();
|
||||
|
||||
if (dir == NULL || *dir == '\0')
|
||||
return ENOTDIR;
|
||||
|
||||
/*
|
||||
* search the cached directories
|
||||
*/
|
||||
while (curDir != NULL && strcmp(curDir->dir_name, dir))
|
||||
{
|
||||
prevDir = curDir;
|
||||
curDir = curDir->next_dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* was the directory found in the cache? If so, return the type.
|
||||
*/
|
||||
if (curDir != NULL)
|
||||
result = curDir->type;
|
||||
else
|
||||
{
|
||||
/*
|
||||
* new directory - malloc room for this entry.
|
||||
*/
|
||||
result = ENOMEM;
|
||||
curDir = (_DtHelpCeDirStruct *) malloc(sizeof(_DtHelpCeDirStruct));
|
||||
if (curDir != NULL)
|
||||
{
|
||||
/*
|
||||
* initialize the new entry. I.E. type starts out ENOTDIR.
|
||||
*/
|
||||
*curDir = DefCacheDir;
|
||||
curDir->dir_name = strdup(dir);
|
||||
if (curDir->dir_name != NULL)
|
||||
{
|
||||
/*
|
||||
* put this entry in the list
|
||||
*/
|
||||
if (prevDir != NULL)
|
||||
prevDir->next_dir = curDir;
|
||||
else
|
||||
CachedDirs = curDir;
|
||||
|
||||
/*
|
||||
* is this a directory?
|
||||
*/
|
||||
if (access(dir, R_OK) == 0 &&
|
||||
stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode))
|
||||
curDir->type = 0;
|
||||
|
||||
/*
|
||||
* return the result of the tests.
|
||||
*/
|
||||
result = curDir->type;
|
||||
}
|
||||
else
|
||||
free(curDir);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This should never happen, but just in case the directory
|
||||
* can't be cached, go ahead and check it anyway.
|
||||
*/
|
||||
if (result == ENOMEM && access(dir, R_OK) == 0 &&
|
||||
stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode))
|
||||
result = 0;
|
||||
|
||||
_DtHelpProcessUnlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef not_done
|
||||
/******************************************************************************
|
||||
* Function: _DtHelpCeDirStruct *_DtHelpCeGetCachedDirs (void)
|
||||
*
|
||||
* Parameters: none.
|
||||
*
|
||||
* Returns: A pointer to the cached directories.
|
||||
*
|
||||
* Purpose: To allow access to the cached directories.
|
||||
*
|
||||
*****************************************************************************/
|
||||
_DtHelpCeDirStruct *
|
||||
_DtHelpCeGetCachedDirs (void)
|
||||
{
|
||||
return CachedDirs;
|
||||
}
|
||||
#endif /* not_done */
|
||||
Reference in New Issue
Block a user