*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Fri, 15 Sep 2006 21:04:48 +0000 (21:04 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Fri, 15 Sep 2006 21:04:48 +0000 (21:04 +0000)
mmsoftware/js/classes/js_fd.c
mmsoftware/js/classes/js_fs.c [new file with mode: 0644]
mmsoftware/js/classes/js_fs.h [new file with mode: 0644]
mmsoftware/js/js-sh/src/GNUmakefile

index fd6a237..fef8fb7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: js_fd.c,v 1.9 2006/09/15 07:06:58 mmondor Exp $ */
+/* $Id: js_fd.c,v 1.10 2006/09/15 21:04:48 mmondor Exp $ */
 
 /*
  * Copyright (c) 2005, Matthew Mondor
@@ -49,6 +49,7 @@
  *   for this (maybe a VFS static class?)  Maybe even something calling
  *   execve(2) and fork(2), those primitives... popen(3) also.
  * - Also opendir(3) and friends wrapper...
+ * - fchdir(2) XXX
  */
 
 
@@ -149,7 +150,7 @@ static JSBool       fd_setProperty(JSContext *, JSObject *, jsval, jsval *);
 static JSBool  fd_m_open(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_set(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_close(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_truncate(JSContext *, JSObject *, uintN, jsval *,
+static JSBool  fd_m_ftruncate(JSContext *, JSObject *, uintN, jsval *,
                    jsval *);
 static JSBool  fd_m_put(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_get(JSContext *, JSObject *, uintN, jsval *, jsval *);
@@ -174,8 +175,6 @@ static JSBool       fd_m_fchown(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_fchmod(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_flock(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_fstat(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_ftruncate(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
 
 static JSBool  fd_sm_poll(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_sm_poll_mkset(JSContext *, jsval *, jsval *, void *);
@@ -254,7 +253,7 @@ static JSFunctionSpec fd_methods[] = {
        { "open", fd_m_open, 0, 0, 0 }, /* Variable 2-3 parameters */
        { "set", fd_m_set, 1, 0, 0 },
        { "close", fd_m_close, 0, 0, 0 },
-       { "truncate", fd_m_truncate, 1, 0, 0 },
+       { "ftruncate", fd_m_ftruncate, 1, 0, 0 },
        { "put", fd_m_put, 1, 0, 0 },
        { "get", fd_m_get, 0, 0, 0 },
        { "socket", fd_m_socket, 3, 0, 0 },
@@ -274,7 +273,6 @@ static JSFunctionSpec fd_methods[] = {
        { "fchmod", fd_m_fchmod, 1, 0, 0 },
        { "flock", fd_m_flock, 1, 0, 0 },
        { "fstat", fd_m_fstat, 0, 0, 0 },
-       { "ftruncate", fd_m_ftruncate, 1, 0, 0 },
        { NULL, NULL, 0, 0, 0 }
 };
 
@@ -878,7 +876,7 @@ fd_m_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 }
 
 static JSBool
-fd_m_truncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+fd_m_ftruncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
     jsval *rval)
 {
        jsfd_t          *jsfd;
@@ -1722,89 +1720,6 @@ err:
        return JS_FALSE;
 }
 
-static JSBool
-fd_m_ftruncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       /* XXX */
-       jsfd_t          *jsfd;
-       struct stat     st;
-       JSObject        *array = NULL;
-       jsval           val;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "ftruncate", FDMA_FTRUNCATE,
-           argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       if (fstat(jsfd->fd, &st) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       /*
-        * Note: We immediately link newly created objects to avoid GC
-        * problems.  For the simplicity of this task we don't need an
-        * additional root to be created using JS_AddRoot(), since *rval
-        * is already rooted.  Moreover, the double objects we create are
-        * immediately added as propery as well.
-        */
-
-       if ((array = JS_NewObject(cx, NULL, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-       *rval = OBJECT_TO_JSVAL(array);
-
-#define DEFINE_INT_PROP(n, i)  do {                                    \
-       val = INT_TO_JSVAL((int)(i));                                   \
-       if (!JS_DefineProperty(cx, array, (n), val, NULL, NULL,         \
-           JSPROP_ENUMERATE)) {                                        \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-#define DEFINE_DOUBLE_PROP(n, d) do {                                  \
-       if (!JS_NewDoubleValue(cx, (jsdouble)(d), &val))                \
-               goto err;                                               \
-       if (!JS_DefineProperty(cx, array, (n), val, NULL, NULL,         \
-           JSPROP_ENUMERATE)) {                                        \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-       DEFINE_INT_PROP("st_dev", st.st_dev);
-       DEFINE_INT_PROP("st_ino", st.st_ino);
-       DEFINE_INT_PROP("st_mode", st.st_mode);
-       DEFINE_INT_PROP("st_nlink", st.st_nlink);
-       DEFINE_INT_PROP("st_uid", st.st_uid);
-       DEFINE_INT_PROP("st_gid", st.st_gid);
-       DEFINE_INT_PROP("st_rdev", st.st_rdev);
-       DEFINE_DOUBLE_PROP("st_atime", st.st_atime);
-       DEFINE_DOUBLE_PROP("st_mtime", st.st_mtime);
-       DEFINE_DOUBLE_PROP("st_ctime", st.st_ctime);
-       DEFINE_DOUBLE_PROP("st_size", st.st_size);
-       DEFINE_DOUBLE_PROP("st_blocks", st.st_blocks);
-       DEFINE_INT_PROP("st_blksize", st.st_blksize);
-       DEFINE_INT_PROP("st_flags", st.st_flags);
-       DEFINE_INT_PROP("st_gen", st.st_gen);
-
-#undef DEFINE_INT_PROP
-#undef DEFINE_DOUBLE_PROP
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-
 
 /*
  * Static methods
diff --git a/mmsoftware/js/classes/js_fs.c b/mmsoftware/js/classes/js_fs.c
new file mode 100644 (file)
index 0000000..c4ffb7d
--- /dev/null
@@ -0,0 +1,867 @@
+/* $Id: js_fs.c,v 1.1 2006/09/15 21:04:48 mmondor Exp $ */
+
+/*
+ * Copyright (c) 2006, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <stdint.h>
+
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <jsapi.h>
+
+#include <js_fs.h>
+
+
+
+#define QUEUE_EXCEPTION(s)     do {                                    \
+       JS_SetPendingException(cx,                                      \
+           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
+} while (/* CONSTCOND */0)
+
+
+
+/*
+ * Static prototypes
+ */
+static JSBool  fs_constructor(JSContext *, JSObject *, uintN, jsval *,
+                   jsval *);
+static void    fs_finalize(JSContext *, JSObject *);
+
+static JSBool  fs_sm_chdir(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_getcwd(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_mkdir(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_rmdir(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_stat(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_lstat(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_chown(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_lchown(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_chmod(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_rename(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_unlink(JSContext *, JSObject *, uintN, jsval *,
+                   jsval *);
+static JSBool  fs_sm_truncate(JSContext *, JSObject *, uintN, jsval *,
+                   jsval *);
+static JSBool  fs_sm_creat(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_mknod(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_mkfifo(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fs_sm_symlink(JSContext *, JSObject *, uintN, jsval *,
+                   jsval *);
+
+static JSBool  fs_sm_stat_i(JSContext *, JSObject *, uintN, jsval *, jsval *,
+                   int (*)(const char *, struct stat *));
+
+static int     chown_resolve(JSContext *, jsval, jsval, uid_t *, gid_t *);
+
+static mode_t  fs_mode_allow(mode_t);
+static int     fs_path_allow(const char *);
+
+
+
+/*
+ * Static globals
+ */
+
+/* FS class */
+static JSClass fs_class = {
+       "FS", 0, JS_PropertyStub, JS_PropertyStub,
+       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub,
+       JS_ConvertStub, fs_finalize
+};
+
+/* Provided static methods */
+static JSFunctionSpec fs_smethods[] = {
+       { "chdir", fs_sm_chdir, 1, 0, 0 },
+       { "getcwd", fs_sm_getcwd, 0, 0, 0 },
+       { "mkdir", fs_sm_mkdir, 2, 0, 0 },
+       { "rmdir", fs_sm_rmdir, 1, 0, 0 },
+       { "stat", fs_sm_stat, 1, 0, 0 },
+       { "lstat", fs_sm_lstat, 1, 0, 0 },
+       { "chown", fs_sm_chown, 3, 0, 0 },
+       { "lchown", fs_sm_lchown, 3, 0, 0 },
+       { "chmod", fs_sm_chmod, 2, 0, 0 },
+       { "rename", fs_sm_rename, 2, 0, 0 },
+       { "unlink", fs_sm_unlink, 1, 0, 0 },
+       { "truncate", fs_sm_truncate, 2, 0, 0 },
+       { "creat", fs_sm_creat, 2, 0, 0 },
+       { "mknod", fs_sm_mknod, 3, 0, 0 },
+       { "mkfifo", fs_sm_mkfifo, 2, 0, 0 },
+       { "symlink", fs_sm_symlink, 2, 0, 0 }
+};
+
+
+
+/*
+ * FS object control
+ */
+
+JSObject *
+js_InitFSClass(JSContext *cx, JSObject *obj)
+{
+       JSObject                *proto;
+
+       if ((proto = JS_InitClass(cx, obj, NULL, &fs_class, fs_constructor,
+           0, NULL, NULL, NULL, fs_smethods)) == NULL)
+               (void) fprintf(stderr, "Error initializing FS class\n");
+
+       return proto;
+}
+
+static JSBool
+fs_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+
+       QUEUE_EXCEPTION("FS class non-instanciable");
+
+       return JS_FALSE;
+}
+
+static void
+fs_finalize(JSContext *cx, JSObject *obj)
+{
+
+       /* NOOP */
+}
+
+
+
+/* Static methods */
+static JSBool
+fs_sm_chdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 1) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+
+       if (fs_path_allow(path) == -1) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       if (chdir(path) != 0) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_getcwd(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       static char     cwd[MAXPATHLEN];
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 0) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+
+       if (getcwd(cwd, MAXPATHLEN - 1) == NULL) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cwd));
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+       mode_t  mode;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(argv[0])) {
+               QUEUE_EXCEPTION("Argument 2 not an Integer");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       mode = fs_mode_allow((mode_t)JSVAL_TO_INT(argv[1]));
+
+       if (mkdir(path, mode) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_rmdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 1) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       if (rmdir(path) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_stat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+
+       return fs_sm_stat_i(cx, obj, argc, argv, rval, stat);
+}
+
+static JSBool
+fs_sm_lstat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+
+       return fs_sm_stat_i(cx, obj, argc, argv, rval, lstat);
+}
+
+static JSBool
+fs_sm_chown(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+       uid_t   uid;
+       gid_t   gid;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 3) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       if (chown_resolve(cx, argv[1], argv[2], &uid, &gid) == -1)
+               return JS_FALSE;
+
+       if (chown(path, uid, gid) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_lchown(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       char    *path;
+       uid_t   uid;
+       gid_t   gid;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 3) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       if (chown_resolve(cx, argv[1], argv[2], &uid, &gid) == -1)
+               return JS_FALSE;
+
+       if (lchown(path, uid, gid) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_chmod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+       mode_t  mode;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not an Integer");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       mode = fs_mode_allow((mode_t)JSVAL_TO_INT(argv[1]));
+
+       if (chmod(path, mode) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_rename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       char    *path1, *path2;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path1 = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path1) != 0) {
+               QUEUE_EXCEPTION("Path 1 not allowed");
+               return JS_FALSE;
+       }
+
+       if ((path2 = JS_GetStringBytes(JSVAL_TO_STRING(argv[1]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path2) != 0) {
+               QUEUE_EXCEPTION("Path 2 not allowed");
+               return JS_FALSE;
+       }
+
+       if (rename(path1, path2) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_unlink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       char    *path;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 1) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       if (unlink(path) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_truncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       char            *path;
+       off_t           size;
+       jsdouble        dsize;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_NUMBER(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not a number");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       if (!JS_ValueToNumber(cx, argv[1], &dsize)) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       size = (off_t)dsize;
+
+       if (truncate(path, size) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_creat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+       mode_t  mode;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not an Integer");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       mode = fs_mode_allow((mode_t)JSVAL_TO_INT(argv[1]));
+
+       if (creat(path, mode) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_mknod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+       char    *path;
+       mode_t  mode;
+       dev_t   dev;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 3) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not an Integer");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(argv[2])) {
+               QUEUE_EXCEPTION("Argument 3 not an Integer");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       mode = fs_mode_allow((mode_t)JSVAL_TO_INT(argv[1]));
+
+       dev = (dev_t)JSVAL_TO_INT(argv[2]);
+
+       if (mknod(path, mode, dev) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_mkfifo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       char    *path;
+       mode_t  mode;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not an Integer");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path) != 0) {
+               QUEUE_EXCEPTION("Path not allowed");
+               return JS_FALSE;
+       }
+
+       mode = fs_mode_allow((mode_t)JSVAL_TO_INT(argv[1]));
+
+       if (mkfifo(path, mode) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
+fs_sm_symlink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       char    *path1, *path2;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 2) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[1])) {
+               QUEUE_EXCEPTION("Argument 2 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path1 = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path1) != 0) {
+               QUEUE_EXCEPTION("Path 1 not allowed");
+               return JS_FALSE;
+       }
+
+       if ((path2 = JS_GetStringBytes(JSVAL_TO_STRING(argv[1]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+       if (fs_path_allow(path2) != 0) {
+               QUEUE_EXCEPTION("Path 2 not allowed");
+               return JS_FALSE;
+       }
+
+       if (symlink(path1, path2) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+
+static JSBool
+fs_sm_stat_i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval, int (*stat_i)(const char *, struct stat *))
+{
+       char            *path;
+       struct stat     st;
+       JSObject        *o = NULL;
+       jsval           val;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 1) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_STRING(argv[0])) {
+               QUEUE_EXCEPTION("Argument 1 not a String");
+               return JS_FALSE;
+       }
+
+       if ((path = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
+               QUEUE_EXCEPTION("Internal error!");
+               return JS_FALSE;
+       }
+
+       if (fs_path_allow(path) == -1) {
+               QUEUE_EXCEPTION("Path now allowed");
+               return JS_FALSE;
+       }
+
+       if (stat_i(path, &st) == -1) {
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       /*
+        * Note: We immediately link newly created objects to avoid GC
+        * problems.  For the simplicity of this task we don't need an
+        * additional root to be created using JS_AddRoot(), since *rval
+        * is already rooted.  Moreover, the double objects we create are
+        * immediately added as propery as well.
+        */
+
+       if ((o = JS_NewObject(cx, NULL, NULL, NULL)) == NULL) {
+               QUEUE_EXCEPTION("Out of memory");
+               goto err;
+       }
+       *rval = OBJECT_TO_JSVAL(o);
+
+#define DEFINE_INT_PROP(n, i)  do {                                    \
+       val = INT_TO_JSVAL((int)(i));                                   \
+       if (!JS_DefineProperty(cx, o, (n), val, NULL, NULL,             \
+           JSPROP_ENUMERATE)) {                                        \
+               QUEUE_EXCEPTION("Internal error!");                     \
+               goto err;                                               \
+       }                                                               \
+} while (/* CONSTCOND */0)
+
+#define DEFINE_DOUBLE_PROP(n, d) do {                                  \
+       if (!JS_NewDoubleValue(cx, (jsdouble)(d), &val))                \
+               goto err;                                               \
+       if (!JS_DefineProperty(cx, o, (n), val, NULL, NULL,             \
+           JSPROP_ENUMERATE)) {                                        \
+               QUEUE_EXCEPTION("Internal error!");                     \
+               goto err;                                               \
+       }                                                               \
+} while (/* CONSTCOND */0)
+
+       DEFINE_INT_PROP("st_dev", st.st_dev);
+       DEFINE_INT_PROP("st_ino", st.st_ino);
+       DEFINE_INT_PROP("st_mode", st.st_mode);
+       DEFINE_INT_PROP("st_nlink", st.st_nlink);
+       DEFINE_INT_PROP("st_uid", st.st_uid);
+       DEFINE_INT_PROP("st_gid", st.st_gid);
+       DEFINE_INT_PROP("st_rdev", st.st_rdev);
+       DEFINE_DOUBLE_PROP("st_atime", st.st_atime);
+       DEFINE_DOUBLE_PROP("st_mtime", st.st_mtime);
+       DEFINE_DOUBLE_PROP("st_ctime", st.st_ctime);
+       DEFINE_DOUBLE_PROP("st_size", st.st_size);
+       DEFINE_DOUBLE_PROP("st_blocks", st.st_blocks);
+       DEFINE_INT_PROP("st_blksize", st.st_blksize);
+       DEFINE_INT_PROP("st_flags", st.st_flags);
+       DEFINE_INT_PROP("st_gen", st.st_gen);
+
+#undef DEFINE_INT_PROP
+#undef DEFINE_DOUBLE_PROP
+
+       return JS_TRUE;
+
+err:
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       return JS_FALSE;
+}
+
+
+static int
+chown_resolve(JSContext *cx, jsval vuid, jsval vgid, uid_t *uid, gid_t *gid)
+{
+       char            *str, e[1024];
+       struct passwd   *pwd;
+       struct group    *grp;
+
+       if (JSVAL_IS_STRING(vuid)) {
+               if ((str = JS_GetStringBytes(JSVAL_TO_STRING(vuid))) == NULL) {
+                       QUEUE_EXCEPTION("Internal error!");
+                       return -1;
+               }
+               if ((pwd = getpwnam(str)) == NULL) {
+                       (void) snprintf(e, 1023, "Unknown user '%s'", str);
+                       QUEUE_EXCEPTION(e);
+                       return -1;
+               }
+               *uid = pwd->pw_uid;
+       } else if (JSVAL_IS_INT(vuid))
+               *uid = JSVAL_TO_INT(vuid);
+       else {
+               QUEUE_EXCEPTION("uid argument not String or Integer");
+               return -1;
+       }
+
+       if (JSVAL_IS_STRING(vgid)) {
+               if ((str = JS_GetStringBytes(JSVAL_TO_STRING(vgid))) == NULL) {
+                       QUEUE_EXCEPTION("Internal error!");
+                       return -1;
+               }
+               if ((grp = getgrnam(str)) == NULL) {
+                       (void) snprintf(e, 1023, "Unknown group '%s'", str);
+                       QUEUE_EXCEPTION(e);
+                       return -1;
+               }
+               *gid = grp->gr_gid;
+       } else if (JSVAL_IS_INT(vgid))
+               *gid = JSVAL_TO_INT(vgid);
+       else {
+               QUEUE_EXCEPTION("gid argument not String or Integer");
+               return -1;
+       }
+
+       return 0;
+}
+
+static mode_t
+fs_mode_allow(mode_t mode)
+{
+       /* XXX */
+
+       return mode;
+}
+
+/* ARGSUSED */
+static int
+fs_path_allow(const char *path)
+{
+       /* XXX */
+
+       return 0;
+}
diff --git a/mmsoftware/js/classes/js_fs.h b/mmsoftware/js/classes/js_fs.h
new file mode 100644 (file)
index 0000000..3785dc2
--- /dev/null
@@ -0,0 +1,13 @@
+/* $Id: js_fs.h,v 1.1 2006/09/15 21:04:48 mmondor Exp $ */
+
+/*
+ * Copyright (c) 2006, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+#ifndef JSFS_H
+#define JSFS_H
+
+extern JSObject        *js_InitFSClass(JSContext *, JSObject *);
+
+#endif
index ccf4735..e076c17 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: GNUmakefile,v 1.2 2006/09/08 12:50:47 mmondor Exp $
+# $Id: GNUmakefile,v 1.3 2006/09/15 21:03:49 mmondor Exp $
 
 #CFLAGS += -g
 CFLAGS += -Wall
@@ -11,7 +11,7 @@ PG_LDFLAGS := $(shell pg_config --ldflags)
 PG_LDFLAGS += -lpq
 
 OBJS := $(addprefix ../../classes/,js_fd.o js_errno.o js_signal.o js_pgsql.o \
-       js_dir.o)
+       js_dir.o js_fs.o)
 OBJS += js-sh.o
 
 CFLAGS += $(JS_CFLAGS) $(PG_CFLAGS) -I../../classes -Wall