/******************************************************************************
*
* NSSDC/CDF Directory utilities.
*
* Version 1.5b, 29-Oct-97, Hughes STX.
*
* Modification history:
*
* V1.0 20-Apr-92, J Love Original version.
* V1.1 21-Aug-92, J Love CDF V2.3 (shareable/NeXT).
* V1.2 26-Jan-94, J Love CDF V2.4.
* V1.3 24-Oct-94, J Love CDF V2.5.
* V1.3a 23-Jan-95, J Love IRIX 6.0 (64-bit).
* V1.3b 24-Feb-95, J Love Solaris 2.3 IDL i/f.
* V1.4 21-Mar-95, J Love POSIX.
* V1.4a 18-Apr-95, J Love More POSIX.
* V1.5 26-Jul-96, J Love CDF V2.6.
* V1.5a 3-Mar-97, J Love Windows NT for MS Visual C/C++ on an IBM PC.
* V1.5b 29-Oct-97, J Love More Windows NT.
* V1.6 11-Jul-05, M Liu Added MingW port for PC.
*
*****************************************************************************/
#include "cdflib.h"
#include "cdflib64.h"
/*****************************************************************************
* Macro constants.
*****************************************************************************/
#if (defined(unix) && !defined(__MINGW32__)) || defined(posixSHELL)
#define DU_MAX_USERNAME_LEN 100
#define DU_MAX_ENVVAR_LEN 80
#endif
/******************************************************************************
* Local function prototypes.
******************************************************************************/
#if (defined(unix) && !defined(__MINGW32__)) || defined(posixSHELL)
static void DerefEnvVar PROTOARGs((char *shortP,
char longP[DU_MAX_PATH_LEN+1]));
static char *NextNonENVchar PROTOARGs((char *ptr));
#endif
/******************************************************************************
* ExpandPath.
******************************************************************************/
VISIBLE_PREFIX void ExpandPath (shortP, longP)
char *shortP;
char longP[DU_MAX_PATH_LEN+1];
{
#if (defined(unix) && !defined(__MINGW32__)) || defined(posixSHELL)
int len; char *tail; struct passwd *pw;
char username[DU_MAX_USERNAME_LEN+1], tempP[DU_MAX_PATH_LEN+1];
#endif
#if (defined(unix) && !defined(__MINGW32__)) || defined(posixSHELL)
DerefEnvVar (shortP, tempP);
if (tempP[0] != '~')
strcpyX (longP, tempP, DU_MAX_PATH_LEN);
else {
tail = strchr (tempP, '/');
if (tail != NULL) {
len = tail - (tempP + 1);
if (len > 0) {
strcpyX (username, tempP + 1, MINIMUM(len,DU_MAX_USERNAME_LEN));
pw = getpwnam (username);
}
else
pw = getpwuid (getuid());
if (pw != NULL)
strcpyX (longP, pw->pw_dir, DU_MAX_PATH_LEN);
else
strcpyX (longP, "?", DU_MAX_PATH_LEN);
strcatX (longP, tail, DU_MAX_PATH_LEN);
}
else {
if (tempP[1] != NUL)
pw = getpwnam (tempP + 1);
else
pw = getpwuid (getuid());
if (pw != NULL)
strcpyX (longP, pw->pw_dir, DU_MAX_PATH_LEN);
else
strcpyX (longP, "?", DU_MAX_PATH_LEN);
}
}
#endif
#if defined(dos) || defined(vms) || defined(mac) || defined(win32) || \
defined(__CYGWIN__) || defined(__MINGW32__)
/* If a Macintosh...check for alias? */
strcpyX (longP, shortP, DU_MAX_PATH_LEN);
#endif
return;
}
/******************************************************************************
* IsReg.
* `stat' on VMS and DOS(/Windows?) systems will indicate a regular file if ANY
* file can be found matching a wildcard specification. On UNIX systems, that
* doesn't happen.
******************************************************************************/
VISIBLE_PREFIX Logical IsReg (path)
char *path;
{
char pathX[DU_MAX_PATH_LEN+1];
#if defined(mac)
struct FInfo fndrInfo;
#else
struct STAT st;
#endif
ExpandPath (path, pathX);
#if defined(mac)
if (GetFInfo(CtoPstr(pathX),0,&fndrInfo) == noErr)
return TRUE;
else
return FALSE;
#else
#if defined(vms)
if (strchr(pathX,'*') != NULL) return FALSE;
if (strchr(pathX,'%') != NULL) return FALSE;
#endif
#if defined(dos) || defined(win32) || defined(__CYGWIN__) || \
defined(__MINGW32__)
if (strchr(pathX,'*') != NULL) return FALSE;
if (strchr(pathX,'?') != NULL) return FALSE;
#endif
if (stat(pathX, &st) == 0) {
#if defined(SALFORDC) /* Salford's `stat' is broken. */
return (st.st_size > 0);
#else
#if defined(S_ISREG)
return S_ISREG(st.st_mode);
#else
return (st.st_mode & S_IFREG);
#endif
#endif
}
else {
#if defined(vms)
/**************************************************************************
* If this is a VMS system and the file is on DECnet (`::' is in the
* pathname following the DECnet nodename), `stat' may produce an error.
* In that case, try to open the file before giving up.
**************************************************************************/
if (strstr(pathX,"::") != NULL) {
FILE *fp = fopen (pathX, READ_ONLY_a_mode);
if (fp != NULL) {
fclose (fp);
return TRUE;
}
}
#endif
return FALSE;
}
#endif
}
/******************************************************************************
* DerefEnvVar.
* (Only used on UNIX/POSIXshell systems).
******************************************************************************/
#if (defined(unix) && !defined(__MINGW32__)) || defined(posixSHELL)
static void DerefEnvVar (shortP, longP)
char *shortP; /* Short path (with environment variables). */
char longP[DU_MAX_PATH_LEN+1]; /* Long path (with environment variables
dereferenced). */
{
char *Sptr = shortP; /* Current position in "short" path. */
char *Lptr = longP; /* End position in "long" path. */
char *DOLLARptr; /* Pointer to '$' in "short" path. */
char *ENVptr; /* Pointer to environment variable in "short" path.*/
char *DEREFptr; /* Pointer to dereferenced environment variable
"value". */
size_t len;
char *ptr;
char ENVvar[DU_MAX_ENVVAR_LEN + 1]; /* Environment variable. */
for (*Lptr = NUL;;) {
DOLLARptr = strchr (Sptr, '$');
if (DOLLARptr != NULL) {
len = DOLLARptr - Sptr;
if (len > 0) {
strcpyX (Lptr, Sptr, MINIMUM(len,DU_MAX_PATH_LEN));
Lptr += len;
}
if (*(DOLLARptr + 1) == '{') {
ENVptr = DOLLARptr + 2;
ptr = strchr (ENVptr, '}');
if (ptr != NULL) {
len = ptr - ENVptr;
Sptr = ptr + 1;
}
else {
len = strlen (ENVptr);
Sptr = ENVptr + len;
}
}
else {
ENVptr = DOLLARptr + 1;
ptr = NextNonENVchar (ENVptr + 1);
if (ptr != NULL) {
len = ptr - ENVptr;
Sptr = ptr;
}
else {
len = strlen (ENVptr);
Sptr = ENVptr + len;
}
}
strcpyX (ENVvar, ENVptr, MINIMUM(len,DU_MAX_ENVVAR_LEN));
DEREFptr = getenv (ENVvar);
if (DEREFptr != NULL) {
len = strlen (DEREFptr);
strcpyX (Lptr, DEREFptr, MINIMUM(len,DU_MAX_PATH_LEN));
Lptr += len;
}
}
else {
strcatX (Lptr, Sptr, DU_MAX_PATH_LEN);
return;
}
}
}
#endif
/******************************************************************************
* NextNonENVchar.
* (Only used on UNIX/POSIXshell systems).
******************************************************************************/
#if (defined(unix) && !defined(__MINGW32__)) || defined(posixSHELL)
static char *NextNonENVchar (ptr)
char *ptr;
{
uChar *p;
for (p = (uChar *) ptr; *p != NUL; p++) {
if (*p <= '/') return ((char *) p);
if (':' <= *p && *p <= '@') return ((char *) p);
if ('[' <= *p && *p <= '^') return ((char *) p);
if (*p == '`') return ((char *) p);
if ('{' <= *p) return ((char *) p);
}
return NULL;
}
#endif
/******************************************************************************
* MacDirSpecified. (Only used on Macintosh systems).
* WARNING - Using `PBHGetVol' caused some really weird things to happen. Use
* `HGetVol' instead.
******************************************************************************/
#if defined(mac)
STATICforIDL Logical MacDirSpecified (path, vRefNum, dirID)
char *path; /* In: Pathname to be checked. */
short *vRefNum; /* Out: Volume reference number. */
long *dirID; /* Out: Directory identifier. */
{
char pathX[DU_MAX_PATH_LEN+1];
OSErr rCode;
short tVRefNum;
long tDirID;
ExpandPath (path, pathX);
/****************************************************************************
* Check for no directory specified (which implies the current working
* directory) or just `:' (which also implies the current working directory).
****************************************************************************/
if (NULstring(pathX) || !strcmp(pathX,":")) {
rCode = HGetVol (NULL, &tVRefNum, &tDirID);
if (rCode != noErr) return FALSE;
}
else {
/**************************************************************************
* Some sort of pathname has been specified (full or partial).
**************************************************************************/
HParamBlockRec hParms;
CInfoPBRec cParms;
long topDirID; /* Top directory ID of partial pathname. */
Str255 tempS;
if (pathX[0] == ':') {
/*****************************************************************
* Partial pathname.
*****************************************************************/
rCode = HGetVol (NULL, &tVRefNum, &topDirID);
if (rCode != noErr) return FALSE;
}
else {
/*****************************************************************
* Full pathname.
*****************************************************************/
hParms.volumeParam.ioNamePtr = tempS;
strcpyX ((char *) hParms.volumeParam.ioNamePtr, pathX, 255);
CtoPstr ((char *) hParms.volumeParam.ioNamePtr);
hParms.volumeParam.ioVRefNum = 0;
hParms.volumeParam.ioVolIndex = -1;
rCode = PBHGetVInfo (&hParms, FALSE);
if (rCode == noErr)
tVRefNum = hParms.volumeParam.ioVRefNum;
else
return FALSE;
topDirID = 0;
}
cParms.hFileInfo.ioNamePtr = tempS;
strcpyX ((char *) cParms.hFileInfo.ioNamePtr, pathX, 255);
CtoPstr ((char *) cParms.hFileInfo.ioNamePtr);
cParms.hFileInfo.ioVRefNum = tVRefNum;
cParms.hFileInfo.ioFDirIndex = 0;
cParms.hFileInfo.ioDirID = topDirID;
rCode = PBGetCatInfo (&cParms, FALSE);
if (rCode == noErr)
tDirID = cParms.hFileInfo.ioDirID;
else
return FALSE;
if (BITCLR(cParms.hFileInfo.ioFlAttrib,4)) return FALSE; /* `Dir' bit */
}
/****************************************************************************
* Pass back volume reference number and directory identifier.
****************************************************************************/
ASSIGNnotNULL (vRefNum, tVRefNum)
ASSIGNnotNULL (dirID, tDirID)
return TRUE;
}
#endif
/******************************************************************************
* AppendToDir.
* If necessary, appends a '/' (UNIX), a '\' (MS-DOS), or a `:' (Mac) to make
* a directory specification to which the file name can then be appended.
******************************************************************************/
VISIBLE_PREFIX void AppendToDir (dir, name)
char *dir;
char *name;
{
#if defined(vms)
strcatX (dir, name, 0);
#endif
#if (defined(unix) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || \
defined(posixSHELL)
if (!NULstring(dir)) {
int lastChar = strlen(dir) - 1;
if (dir[lastChar] != '/') strcatX (dir, "/", 0);
}
strcatX (dir, name, 0);
#endif
#if defined(dos) || defined(win32) || defined(__CYGWIN__) || \
defined(__MINGW32__)
if (!NULstring(dir)) {
int lastChar = strlen(dir) - 1;
if (dir[lastChar] != '\\' && dir[lastChar] != ':') strcatX (dir, "\\", 0);
}
strcatX (dir, name, 0);
#endif
#if defined(mac)
if (!NULstring(dir)) {
int lastChar = strlen(dir) - 1;
if (dir[lastChar] != ':') strcatX (dir, ":", 0);
}
strcatX (dir, name, 0);
#endif
return;
}
syntax highlighted by Code2HTML, v. 0.9.1