Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 403 lines (334 sloc) 6.029 kb
#ifndef com_sleepless_io_directory_cpp
#define com_sleepless_io_directory_cpp
// Copyright 3000 Sleepless Software Inc. All Rights Reserved
#include "args.cpp"
#include "string.cpp"
#if defined( WIN32 )
# include <windows.h>
# include <stdio.h>
# ifndef __CYGWIN__
# include <direct.h>
# endif
# define DIR_NAME_MAX MAX_PATH
//# define _mkdir(d,b) mkdir(d)
#elif defined(linux) || (defined(__APPLE__) && defined(__GNUC__))
# include <dirent.h>
# include <string.h>
# include <stdlib.h>
#endif
// Windows replacements for dirent.h
#if defined( WIN32 )
struct dirent
{
char d_name[DIR_NAME_MAX + 1];
};
struct DIR
{
WIN32_FIND_DATA findData;
HANDLE handle;
dirent de;
char *path;
void close()
{
if(handle != INVALID_HANDLE_VALUE)
{
FindClose(handle);
handle = INVALID_HANDLE_VALUE;
}
}
void rewind()
{
close();
handle = FindFirstFile(path, &findData);
}
DIR(const char *p)
{
handle = INVALID_HANDLE_VALUE;
path = (char *)malloc(strlen(p) + 5);
if(path == NULL)
{
handle = INVALID_HANDLE_VALUE;
return;
}
sprintf(path, "%s/*.*", p);
rewind();
}
dirent *readdir()
{
if(FindNextFile(handle, &findData) != 0)
{
strncpy(de.d_name, findData.cFileName, DIR_NAME_MAX);
de.d_name[DIR_NAME_MAX] = 0;
return &de;
}
return NULL;
}
~DIR()
{
close();
free(path);
}
};
static DIR *opendir(const char *p)
{
DIR *dir = new DIR(p);
if(dir->handle == INVALID_HANDLE_VALUE)
{
delete dir;
dir = NULL;
}
return dir;
}
static dirent *readdir(DIR *dir)
{
return dir->readdir();
}
static void rewinddir(DIR *dir)
{
dir->rewind();
}
static int closedir(DIR *dir)
{
delete dir;
return 0;
}
#endif
#if 0
// Windows replacement for mkdir()
#if defined( WIN32 )
#ifndef __CYGWIN__
// create a dir - returns 0 on success, non-zero on fail
int mkdir(const char *file, int)
{
char *tfile = strdup(file); // clone string
char *s = tfile;
while(*s) { if(*s == '/') *s = '\\'; s++; } // Convert '/' to '\'
int r = _mkdir(tfile); // make the dir
free(tfile); // dispose of cloned str
return r;
}
#endif
#endif
#endif
#include <sys/stat.h>
#ifndef WIN32
#define stricmp strcasecmp
#else
#define stricmp _stricmp
#endif
class Directory
{
int numEntries;
char **entries;
static int compareName( const void *arg1, const void *arg2 )
{
return stricmp( * ( char** ) arg1, * ( char** ) arg2 );
}
void sortByName()
{
qsort(entries, numEntries, sizeof(char *), compareName);
}
public:
Directory(const char *path)
{
numEntries = 0;
entries = NULL;
DIR *dir = opendir(path);
if(dir == NULL)
{
// m(("Can't read dir '%s'", path));
return;
}
int n = 0;
while(true)
{
if(readdir(dir) != NULL)
{
n++;
}
else
{
break;
}
}
rewinddir(dir);
if(n > 0)
{
entries = (char **)malloc(n * sizeof(const char *));
struct dirent *d;
for(int i = 0; i < n; i++)
{
d = readdir(dir);
entries[i] = (char *)malloc(strlen(d->d_name) + 1);
strcpy(entries[i], d->d_name);
numEntries++;
}
}
closedir(dir);
sortByName();
}
~Directory()
{
if(entries != NULL)
{
for(int i = 0; i < numEntries; i++)
{
if(entries[i] != NULL)
{
free(entries[i]);
}
}
}
}
int getNumEntries()
{
return numEntries;
}
const char *getEntry(int n)
{
return entries[n];
}
static int getSize(const char *path)
{
struct stat buf;
int r = stat(path, &buf );
if(r == 0)
return buf.st_size;
return 0;
}
static unsigned long getTimeStamp(const char *path)
{
struct stat buf;
int r = stat(path, &buf );
if(r == 0)
return (unsigned long)buf.st_mtime;
return 0;
}
int getEntrySize(int n)
{
return getSize(entries[n]);
}
int getSize(int n)
{
return getSize(entries[n]);
}
unsigned long getTimeStamp(int n)
{
return getTimeStamp(entries[n]);
}
static bool isFile(const char *path)
{
struct stat buf;
int r = stat(path, &buf );
if(r == 0)
return (buf.st_mode & S_IFREG) ? 1 : 0;
return 0;
}
bool isFile(int n)
{
return isFile(entries[n]);
}
static bool isDir(const char *path)
{
struct stat buf;
int r = stat(path, &buf );
if(r == 0)
return (buf.st_mode & S_IFDIR) ? 1 : 0;
return 0;
}
bool isDir(int n)
{
return isDir(entries[n]);
}
bool isLink(int n)
{
#ifdef WIN32
// Windows doesn't have symbolic links.
return false;
#else
struct stat buf;
int r = lstat(entries[n], &buf );
if(r == 0)
return (buf.st_mode & S_IFLNK) ? 1 : 0;
return 0;
#endif
};
// static functions below here
// creates all intermediate dirs as necessary
// returns 0 on success.
static int createDir(const char *odir, char sep = '/')
{
/*
foo/bar
./foo/bar
/foo/bar
c:\foo/bar
\\host\foo\bar
*/
// create working copy of path
char *dir = strdup(odir);
if(!dir)
return 1;
#ifdef WIN32
// convert all backslashes to forward slashes
char *tmp = dir;
while(*tmp)
{
if(*tmp == '\\')
*tmp = '/';
tmp++;
}
// except in th case of "C:\foobar" and "\\host\foo\bar"
if(dir[0] == '/' && dir[1] == '/')
dir[0] = dir[1] = '\\';
if(dir[1] == ':' && dir[2] == '/')
dir[2] = '\\';
#endif
#ifdef WIN32
char *cwd = _getcwd(0, 1);
#else
char *cwd = getcwd(0, 1);
#endif
int r = 0;
Args pa(dir, '/');
for(int i = 0; i < pa.length(); i++)
{
const char *pth = pa.get(i);
#ifndef WIN32
// can't remember why i had to do do this on linux/mac, but it win32 pukes on it
S pth2(pth,"/");
pth = pth2.chars;
#endif
if(!isDir(pth))
{
#ifdef WIN32
r = _mkdir(pth);
#else
r = mkdir(pth, 0700);
#endif
if(r)
{
break;
}
}
#ifdef WIN32
r = _chdir(pth);
#else
r = chdir(pth);
#endif
if(r)
{
break;
}
}
#ifdef WIN32
_chdir(cwd);
#else
chdir(cwd);
#endif
free(cwd);
free(dir);
return r;
}
};
#endif // com_sleepless_io_directory_cpp
Jump to Line
Something went wrong with that request. Please try again.