@@ -629,10 +629,11 @@ stbuf->st_mtime = pathinfo.time; stbuf->st_ctime = pathinfo.time; stbuf->st_atime = pathinfo.time; stbuf->st_ino = pathinfo.inode; stbuf->st_mode = 0; + stbuf->st_uid = appfs_get_fsuid(); switch (pathinfo.type) { case APPFS_PATHTYPE_DIRECTORY: stbuf->st_mode = S_IFDIR | 0555; stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount; @@ -843,28 +844,39 @@ return(0); } static int appfs_fuse_create(const char *path, mode_t mode, struct fuse_file_info *fi) { + char *real_path; int fd; - int chmod_ret; APPFS_DEBUG("Enter (path = %s, ...)", path); - fd = appfs_fuse_open(path, fi); + if ((mode & S_IFCHR) == S_IFCHR) { + return(-EPERM); + } + + if ((mode & S_IFBLK) == S_IFBLK) { + return(-EPERM); + } + + real_path = appfs_prepare_to_create(path); + if (real_path == NULL) { + return(-EIO); + } + + fd = creat(real_path, mode); + + free(real_path); + if (fd < 0) { - return(fd); + return(errno * -1); } - chmod_ret = fchmod(fd, mode); - if (chmod_ret != 0) { - close(fd); - - return(-EIO); - } - - return(fd); + fi->fh = fd; + + return(0); } static int appfs_fuse_truncate(const char *path, off_t size) { char *real_path; int truncate_ret; @@ -930,10 +942,40 @@ } } return(0); } + +static int appfs_fuse_chmod(const char *path, mode_t mode) { + Tcl_Interp *interp; + const char *real_path; + int tcl_ret, chmod_ret; + + APPFS_DEBUG("Enter (path = %s, ...)", path); + + interp = appfs_TclInterp(); + if (interp == NULL) { + return(-EIO); + } + + tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::openpath", path, "write"); + if (tcl_ret != TCL_OK) { + APPFS_DEBUG("::appfs::openpath(%s, %s) failed.", path, "write"); + APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + + return(-EIO); + } + + real_path = Tcl_GetStringResult(interp); + if (real_path == NULL) { + return(-EIO); + } + + chmod_ret = chmod(real_path, mode); + + return(chmod_ret); +} /* * SQLite3 mode: Execute raw SQL and return success or failure */ static int appfs_sqlite3(const char *sql) { @@ -1029,10 +1071,11 @@ .create = appfs_fuse_create, .truncate = appfs_fuse_truncate, .unlink = appfs_fuse_unlink_rmdir, .rmdir = appfs_fuse_unlink_rmdir, .mkdir = appfs_fuse_mkdir, + .chmod = appfs_fuse_chmod, }; /* * FUSE option parsing callback */