Milán Major

netscape-revival

1 branch
Code

nspr-/src/file.c

#include <stdlib.h>
#include "prfile.h"
#include "prmem.h"
#include "prtypes.h"

#ifdef XP_PC
#include <string.h>
#include <direct.h>
#include <sys/stat.h>

#include "prprf.h"      /* PR_snprintf(...) */

#define S_ISDIR( m )	(((m) & S_IFMT) == S_IFDIR)
#define S_ISREG( m )	(((m) & S_IFMT) == S_IFREG)

/* Symbolic constants for the access() function */

#define R_OK    4       /*  Test for read permission    */
#define W_OK    2       /*  Test for write permission   */
#define F_OK    0       /*  Test for existence of file  */

/* Data structures required for opendir/readdir/closedir */

#ifdef _WIN32
typedef struct dirent {
    HANDLE          d_hdl;
    char *          d_name;
    WIN32_FIND_DATA d_entry;
} DIR;

#define GetFileFromDIR(d)       (d)->d_entry.cFileName
#define IsInvalidHandle(h)      ((h)== INVALID_HANDLE_VALUE)

#else /* ! _WIN32 */

#include <dos.h>

#define MAX_PATH                _MAX_PATH

typedef struct dirent {
    unsigned        d_hdl;
    char *          d_name;
    struct _find_t  d_entry;
} DIR;

/* Map the WIN32 FindxxxFile API to equivilant DOS calls */

#define FindFirstFile(_a, _b)   _dos_findfirst((_a), _A_RDONLY|_A_SUBDIR, (_b))
#define FindNextFile( _a,_b)    ((_a) = _dos_findnext((_b)))
#define FindClose(_a)

#define GetFileFromDIR(d)       (d)->d_entry.name
#define IsInvalidHandle(h)      ((h) != 0)
#endif  /* ! _WIN32 */

struct PRDirStr {
    DIR *d;
    PRDirEntry cur;
};
#endif  /* XP_PC */

#ifdef XP_MAC
port me;
#endif

#ifdef XP_UNIX
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

struct PRDirStr {
    DIR *d;
    PRDirEntry cur;
};
#endif

#ifdef XP_PC

void FlipSlashes(char *cp, int len)
{
    while (--len >= 0) {
	if (cp[0] == '/') {
	    cp[0] = DIRECTORY_SEPARATOR;
	}
	cp++;
    }
}

/*
**
** Local implementations of standard Unix RTL functions which are not provided 
** by the VC RTL.
**
*/

void closedir( DIR * d )
{
    if ( d ) {
        FindClose( d->d_hdl );
        free( d );
    }
}


DIR *opendir( const char * name)
{
    char filename[ MAX_PATH ];
    DIR * d;

    PR_snprintf(filename, MAX_PATH, "%s%s%s", 
                name, DIRECTORY_SEPARATOR_STR, "*.*");
    FlipSlashes( filename, strlen(filename) );

    d = (DIR *)calloc( 1, sizeof( DIR ) );
    if ( !d ) {
        return 0;
    }

    d->d_hdl = FindFirstFile( filename, &(d->d_entry) );
    if ( IsInvalidHandle(d->d_hdl) ) {
        free( d );
        d = 0;
    } else {
        d->d_name = GetFileFromDIR(d);
	}
    return d;
}

struct dirent *readdir( DIR * d )
{
    if ( d ) {
        d->d_name = NULL;
        if ( FindNextFile( d->d_hdl, &(d->d_entry) ) ) {
            d->d_name = GetFileFromDIR(d);
            return d;
        }
    }
    return 0;
}
#endif  /* XP_PC */

#ifdef XP_UNIX
#undef FlipSlashes
void FlipSlashes(char *cp, int len)
{
}
#endif

PR_PUBLIC_API(int) PR_GetFileInfo(char *fn, PRFileInfo *info)
{
#if defined(XP_UNIX) || defined(XP_PC)
    struct stat sb;
    int64 s, c1;

    int rv = stat(fn, &sb);
    if (rv < 0) {
	return rv;
    }
    if (info) {
	if (S_ISREG(sb.st_mode))
	    info->type = PR_FI_FILE;
	else if (S_ISDIR(sb.st_mode))
	    info->type = PR_FI_DIRECTORY;
	else
	    info->type = PR_FI_OTHER;
	info->size = sb.st_size;
	LL_I2L(s, sb.st_mtime);
	LL_I2L(c1, 1000000000L);
	LL_MUL(s, s, c1);
	info->modifyTime = s;
    }
    return 0;
#endif
#ifdef XP_MAC
    write me;
#endif
}

long PR_GetOpenFileLength(int desc)
{
#if defined(XP_UNIX) || defined(XP_PC)
    struct stat sb;
    int rv = fstat(desc, &sb);
    if (rv > 0) {
	return sb.st_size;
    }
    return -1;
#endif
#ifdef XP_MAC
    write me;
#endif
}


PR_PUBLIC_API(int) PR_Mkdir(char *name, int mask)
{
    int rv;

#ifdef XP_PC
    rv = mkdir(name);
#endif
#ifdef XP_MAC
    write me;
#endif
#ifdef XP_UNIX
    rv = mkdir(name, mask);
#endif
    return rv;
}

/************************************************************************/

PR_PUBLIC_API(PRDir *) PR_OpenDirectory(char *name)
{
    PRDir *d;

    d = (PRDir*) calloc(1, sizeof(PRDir));
    if (!d) {
	return 0;
    }

#ifdef XP_MAC
    write me;
#endif
#if defined(XP_UNIX) || defined(XP_PC)
    d->d = opendir(name);
    if (!d->d) {
	free(d);
	return 0;
    }
#endif
    return d;
}

PR_PUBLIC_API(PRDirEntry *) PR_ReadDirectory(PRDir *d, int flags)
{
#ifdef XP_MAC
    write me;
#endif
#if defined(XP_UNIX) || defined(XP_PC)
    struct dirent *de;

    for (;;) {
	de = readdir(d->d);
	if (!de) return 0;
	if ((flags & PR_RD_SKIP_DOT) &&
	    (de->d_name[0] == '.') && (de->d_name[1] == 0))
	    continue;
	if ((flags & PR_RD_SKIP_DOT_DOT) &&
	    (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
	    (de->d_name[2] == 0))
	    continue;
	break;
    }
    d->cur.d_name = de->d_name;
    return &d->cur;
#endif
}

PR_PUBLIC_API(void) PR_CloseDirectory(PRDir *d)
{
    if (d) {
#ifdef XP_MAC
	write me;
#endif
#if defined(XP_UNIX) || defined(XP_PC)
	closedir(d->d);
#endif
	free(d);
    }
}

PR_PUBLIC_API(int) PR_AccessFile(char *name, int how)
{
#ifdef XP_MAC
    write me;
#endif
#if defined(XP_UNIX) || defined(XP_PC)
    switch (how) {
      case PR_AF_WRITE_OK:
	return access(name, W_OK);
      case PR_AF_READ_OK:
	return access(name, R_OK);
      case PR_AF_EXISTS:
      default:
	return access(name, F_OK);
    }
#endif
}

PR_PUBLIC_API(int) PR_RenameFile(char *from, char *to)
{
#ifdef XP_MAC
    write me;
#endif
#if defined(XP_UNIX) || defined(XP_PC)
    return rename(from, to);
#endif
}