455 lines
11 KiB
C
Executable File
455 lines
11 KiB
C
Executable File
/*
|
|
* @file ejsFileSystem.c
|
|
* @brief FileSystem class for the EJ System Object Model
|
|
* MOB -- this is almost the same as for Windows. Should common up.
|
|
*/
|
|
/********************************** Copyright *********************************/
|
|
/*
|
|
* Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
|
|
*/
|
|
/********************************** Includes **********************************/
|
|
|
|
#include "ejs.h"
|
|
#include <dirent.h>
|
|
|
|
/******************************************************************************/
|
|
/************************************ Methods *********************************/
|
|
/******************************************************************************/
|
|
/*
|
|
* function void access(string path);
|
|
* MOB - API insufficient. Access for read or write?
|
|
*/
|
|
|
|
static int accessProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
int rc;
|
|
|
|
if (argc != 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: access(path)");
|
|
return -1;
|
|
}
|
|
|
|
rc = access(argv[0]->string, 04);
|
|
|
|
ejsSetReturnValueToBoolean(ejs, (rc == 0) ? 1 : 0);
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void mkdir(string path);
|
|
*/
|
|
|
|
static int mkdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
if (argc != 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)");
|
|
return -1;
|
|
}
|
|
|
|
if (mprMakeDirPath(ejs, argv[0]->string) < 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant create directory");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void rmdir(string path);
|
|
*/
|
|
|
|
static int rmdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
int rc;
|
|
|
|
if (argc != 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)");
|
|
return -1;
|
|
}
|
|
|
|
rc = mprDeleteDir(ejs, argv[0]->string);
|
|
|
|
if (rc < 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant remove directory");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void dirList(string path, [bool enumDirs]);
|
|
* MOB -- need pattern to match (what about "." and ".." and ".*"
|
|
*/
|
|
|
|
static int dirListProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
DIR *dir;
|
|
struct dirent *dirent;
|
|
char path[MPR_MAX_FNAME];
|
|
EjsVar *array, *vp;
|
|
uchar enumDirs;
|
|
|
|
if (argc < 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: dirList(path)");
|
|
return -1;
|
|
}
|
|
if (argc == 2) {
|
|
enumDirs = ejsVarToBoolean(argv[1]);
|
|
} else {
|
|
enumDirs = 0;
|
|
}
|
|
array = ejsCreateArray(ejs, 0);
|
|
ejsMakeObjPermanent(array, 1);
|
|
|
|
/*
|
|
* First collect the files
|
|
*/
|
|
mprSprintf(path, sizeof(path), "%s/*.*", argv[0]->string);
|
|
|
|
dir = opendir(path);
|
|
if (dir == 0) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Can't enumerate dirList(path)");
|
|
return -1;
|
|
}
|
|
|
|
while ((dirent = readdir(dir)) != 0) {
|
|
if (dirent->d_name[0] == '.') {
|
|
continue;
|
|
}
|
|
if (!enumDirs || (dirent->d_type & DT_DIR)) {
|
|
mprSprintf(path, sizeof(path), "%s/%s", argv[0]->string,
|
|
dirent->d_name);
|
|
vp = ejsCreateStringVar(ejs, path);
|
|
ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY);
|
|
ejsFreeVar(ejs, vp);
|
|
}
|
|
}
|
|
|
|
closedir(dir);
|
|
|
|
ejsSetReturnValue(ejs, array);
|
|
ejsMakeObjPermanent(array, 0);
|
|
|
|
/*
|
|
* Can free now as the return value holds the reference
|
|
*/
|
|
ejsFreeVar(ejs, array);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void getFreeSpace();
|
|
*/
|
|
|
|
static int getFreeSpaceProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
#if UNUSED
|
|
MprApp *app;
|
|
uint space;
|
|
|
|
app = mprGetApp(ejs);
|
|
space = IFILEMGR_GetFreeSpace(app->fileMgr, 0);
|
|
ejsSetReturnValueToInteger(ejs, space);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void writeFile(string path, var data);
|
|
*/
|
|
|
|
static int writeFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
MprFile *file;
|
|
char *data, *buf;
|
|
int bytes, length, rc;
|
|
|
|
if (argc != 2 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: writeFile(path, var)");
|
|
return -1;
|
|
}
|
|
|
|
if (ejsVarIsString(argv[1])) {
|
|
data = argv[1]->string;
|
|
length = argv[1]->length;
|
|
buf = 0;
|
|
} else {
|
|
buf = data = ejsVarToString(ejs, argv[1]);
|
|
length = strlen(data);
|
|
}
|
|
|
|
/*
|
|
* Create fails if already present
|
|
*/
|
|
rc = mprDelete(ejs, argv[0]->string);
|
|
file = mprOpen(ejs, argv[0]->string, O_CREAT | O_WRONLY | O_BINARY, 0664);
|
|
if (file == 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[0]->string);
|
|
mprFree(buf);
|
|
return -1;
|
|
}
|
|
|
|
rc = 0;
|
|
bytes = mprWrite(file, data, length);
|
|
if (bytes != length) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
|
|
rc = -1;
|
|
}
|
|
|
|
mprClose(file);
|
|
|
|
mprFree(buf);
|
|
return rc;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function string readFile(string path);
|
|
*/
|
|
|
|
static int readFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
MprApp *app;
|
|
MprFile *file;
|
|
MprBuf *buf;
|
|
char *data;
|
|
int bytes, rc;
|
|
|
|
if (argc != 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: readFile(path)");
|
|
return -1;
|
|
}
|
|
buf = mprCreateBuf(ejs, MPR_BUF_INCR, MPR_MAX_BUF);
|
|
if (buf == 0) {
|
|
ejsMemoryError(ejs);
|
|
return -1;
|
|
}
|
|
|
|
data = mprAlloc(ejs, MPR_BUFSIZE);
|
|
if (buf == 0) {
|
|
mprFree(buf);
|
|
ejsMemoryError(ejs);
|
|
return -1;
|
|
}
|
|
|
|
app = mprGetApp(ejs);
|
|
file = mprOpen(ejs, argv[0]->string, O_RDONLY, 0664);
|
|
if (file == 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string);
|
|
mprFree(buf);
|
|
return -1;
|
|
}
|
|
|
|
rc = 0;
|
|
while ((bytes = mprRead(file, data, MPR_BUFSIZE)) > 0) {
|
|
if (mprPutBlockToBuf(buf, data, bytes) != bytes) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
|
|
rc = -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ejsSetReturnValueToBinaryString(ejs, (uchar*) mprGetBufStart(buf),
|
|
mprGetBufLength(buf));
|
|
|
|
mprClose(file);
|
|
mprFree(data);
|
|
mprFree(buf);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void remove(string path);
|
|
*/
|
|
|
|
static int removeProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
int rc;
|
|
|
|
if (argc != 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: remove(path)");
|
|
return -1;
|
|
}
|
|
|
|
rc = unlink(argv[0]->string);
|
|
if (rc < 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant remove file");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void rename(string from, string to);
|
|
*/
|
|
|
|
static int renameProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
int rc;
|
|
|
|
if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: rename(old, new)");
|
|
return -1;
|
|
}
|
|
|
|
unlink(argv[1]->string);
|
|
rc = rename(argv[0]->string, argv[1]->string);
|
|
if (rc < 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant rename file");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function void copy(string old, string new);
|
|
*/
|
|
|
|
static int copyProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
MprFile *from, *to;
|
|
char *buf;
|
|
uint bytes;
|
|
int rc;
|
|
|
|
if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: copy(old, new)");
|
|
return -1;
|
|
}
|
|
|
|
buf = mprAlloc(ejs, MPR_BUFSIZE);
|
|
if (buf == 0) {
|
|
ejsMemoryError(ejs);
|
|
return -1;
|
|
}
|
|
|
|
from = mprOpen(ejs, argv[0]->string, O_RDONLY | O_BINARY, 0664);
|
|
if (from == 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string);
|
|
mprFree(buf);
|
|
return -1;
|
|
}
|
|
|
|
to = mprOpen(ejs, argv[1]->string, O_CREAT | O_BINARY, 0664);
|
|
if (to == 0) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[1]->string);
|
|
mprClose(from);
|
|
mprFree(buf);
|
|
return -1;
|
|
}
|
|
|
|
rc = 0;
|
|
while ((bytes = mprRead(from, buf, MPR_BUFSIZE)) > 0) {
|
|
if (mprWrite(to, buf, bytes) != bytes) {
|
|
ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
|
|
rc = -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
mprClose(from);
|
|
mprClose(to);
|
|
mprFree(buf);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
* function FileInfo getFileInfo(string path);
|
|
*
|
|
* MOB -- should create a real class FileInfo
|
|
*/
|
|
|
|
static int getFileInfoProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
|
|
{
|
|
MprFileInfo info;
|
|
EjsVar *fileInfo;
|
|
int rc;
|
|
|
|
if (argc != 1 || !ejsVarIsString(argv[0])) {
|
|
ejsError(ejs, EJS_ARG_ERROR, "Bad usage: getFileInfo(path)");
|
|
return -1;
|
|
}
|
|
|
|
fileInfo = ejsCreateObjVar(ejs);
|
|
if (fileInfo == 0) {
|
|
ejsMemoryError(ejs);
|
|
return -1;
|
|
}
|
|
ejsMakeObjPermanent(fileInfo, 1);
|
|
|
|
rc = mprGetFileInfo(ejs, argv[0]->string, &info);
|
|
if (rc < 0) {
|
|
ejsMakeObjPermanent(fileInfo, 0);
|
|
ejsFreeVar(ejs, fileInfo);
|
|
ejsError(ejs, EJS_IO_ERROR, "Cant get file info for %s",
|
|
argv[0]->string);
|
|
return -1;
|
|
}
|
|
|
|
ejsSetPropertyToInteger(ejs, fileInfo, "created", info.ctime);
|
|
ejsSetPropertyToInteger(ejs, fileInfo, "length", info.size);
|
|
ejsSetPropertyToBoolean(ejs, fileInfo, "isDir", info.isDir);
|
|
|
|
ejsSetReturnValue(ejs, fileInfo);
|
|
ejsMakeObjPermanent(fileInfo, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/******************************** Initialization ******************************/
|
|
/******************************************************************************/
|
|
|
|
int ejsDefineFileSystemClass(Ejs *ejs)
|
|
{
|
|
EjsVar *fileSystemClass;
|
|
|
|
fileSystemClass = ejsDefineClass(ejs, "FileSystem", "Object", 0);
|
|
if (fileSystemClass == 0) {
|
|
return MPR_ERR_CANT_INITIALIZE;
|
|
}
|
|
|
|
/*
|
|
* Define the methods
|
|
*/
|
|
ejsDefineCMethod(ejs, fileSystemClass, "access", accessProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "mkdir", mkdirProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "rmdir", rmdirProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "dirList", dirListProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "writeFile", writeFileProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "readFile", readFileProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "remove", removeProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "rename", renameProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "copy", copyProc, 0);
|
|
ejsDefineCMethod(ejs, fileSystemClass, "getFileInfo", getFileInfoProc, 0);
|
|
|
|
// MOB -- should be a property with accessor
|
|
ejsDefineCMethod(ejs, fileSystemClass, "getFreeSpace", getFreeSpaceProc, 0);
|
|
|
|
return ejsObjHasErrors(fileSystemClass) ? MPR_ERR_CANT_INITIALIZE: 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
/*
|
|
* Local variables:
|
|
* tab-width: 4
|
|
* c-basic-offset: 4
|
|
* End:
|
|
* vim:tw=78
|
|
* vim600: sw=4 ts=4 fdm=marker
|
|
* vim<600: sw=4 ts=4
|
|
*/
|