Files

455 lines
11 KiB
C
Raw Permalink Normal View History

2019-02-16 00:16:52 +01:00
/*
* @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
*/