/* * @file ejsFileSystem.c * @brief FileSystem class for the EJ System Object Model */ /********************************** Copyright *********************************/ /* * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. */ /********************************** Includes **********************************/ #include "ejs.h" /******************************************************************************/ /* * Default Constructor */ /******************************************************************************/ /************************************ 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) { WIN32_FIND_DATA findData; HANDLE h; 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); h = FindFirstFile(path, &findData); if (h == INVALID_HANDLE_VALUE) { ejsError(ejs, EJS_ARG_ERROR, "Can't enumerate dirList(path)"); return -1; } do { if (findData.cFileName[0] == '.') { continue; } if (!enumDirs || (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { mprSprintf(path, sizeof(path), "%s/%s", argv[0]->string, findData.cFileName); vp = ejsCreateStringVar(ejs, path); ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY); ejsFreeVar(ejs, vp); } } while (FindNextFile(h, &findData) != 0); FindClose(h); 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, 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; int bytes, 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 */