added vfs_mkdir and vfs_unlink

Sun, 17 Mar 2013 17:54:20 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 17 Mar 2013 17:54:20 +0100
changeset 56
c6cf20b09043
parent 55
b7908bf38f9f
child 57
b3a89736b23e

added vfs_mkdir and vfs_unlink

src/server/config/acl.c file | annotate | diff | comparison | revisions
src/server/daemon/vfs.c file | annotate | diff | comparison | revisions
src/server/daemon/vfs.h file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
src/server/safs/service.c file | annotate | diff | comparison | revisions
src/server/util/util.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/config/acl.c	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/config/acl.c	Sun Mar 17 17:54:20 2013 +0100
@@ -230,6 +230,8 @@
         val = ACLCFG_WRITE_DATA;
     } else if(!sstrcmp(access, sstr("append"))) {
         val = ACLCFG_APPEND;
+    } else if(!sstrcmp(access, sstr("add"))) {
+        val = ACLCFG_ADD_FILE;
     } else if(!sstrcmp(access, sstr("add_file"))) {
         val = ACLCFG_ADD_FILE;
     } else if(!sstrcmp(access, sstr("add_subdirectory"))) {
--- a/src/server/daemon/vfs.c	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/daemon/vfs.c	Sun Mar 17 17:54:20 2013 +0100
@@ -123,11 +123,11 @@
 }
 
 SYS_FILE vfs_openWO(VFSContext *ctx, char *path) {
-    return vfs_open(ctx, path, O_WRONLY);
+    return vfs_open(ctx, path, O_WRONLY | O_CREAT);
 }
 
 SYS_FILE vfs_openRW(VFSContext *ctx, char *path) {
-    return vfs_open(ctx, path, O_RDONLY);
+    return vfs_open(ctx, path, O_RDONLY | O_WRONLY | O_CREAT);
 }
 
 int vfs_stat(VFSContext *ctx, char *path, struct stat *buf) {
@@ -292,8 +292,69 @@
     }
 }
 
+int vfs_mkdir(VFSContext *ctx, char *path) {
+    if(ctx && ctx->vfs) {
+        return vfs_path_op(ctx, path, ctx->vfs->mkdir, ACL_ADD_FILE);
+    } else {
+        return vfs_path_op(ctx, path, sys_mkdir, ACL_ADD_FILE);
+    }
+}
+
+int vfs_unlink(VFSContext *ctx, char *path) {
+    if(ctx && ctx->vfs) {
+        return vfs_path_op(ctx, path, ctx->vfs->unlink, ACL_DELETE);
+    } else {
+        return vfs_path_op(ctx, path, sys_unlink, ACL_DELETE);
+    }
+}
+
 
 // private
+int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access) {
+    Session *sn;
+    Request *rq;
+    uint32_t access_mask;
+    
+    if(ctx) {
+        access_mask = ctx->aclreqaccess;
+        access_mask |= access;
+        if(!ctx->pool) {
+            // TODO: log warning
+            // broken VFSContext
+        }
+        if(ctx->vfs) {
+            // ctx->aclreqaccess should be the complete access mask
+            uint32_t m = ctx->aclreqaccess; // save original access mask
+            ctx->aclreqaccess = access_mask; // set mask for vfs->fstat call
+            int ret = op(ctx, path);
+            ctx->aclreqaccess = m; // restore original access mask
+            return ret;
+        }
+    } else {
+        sn = NULL;
+        rq = NULL;
+        access_mask = access;
+    }
+    
+    // check ACLs
+    uid_t uid; // uid and gid will be initialized by sys_acl_check
+    gid_t gid;
+    if(sys_acl_check(ctx, access_mask, &uid, &gid)) {
+        return NULL;
+    }
+    
+    // do path operation
+    if(op(ctx, path)) {
+        // error
+        if(ctx) {
+            ctx->vfs_errno = errno;
+            sys_set_error_status(ctx);
+        }
+        return -1;
+    }
+    
+    return 0;
+}
 
 int sys_acl_check(VFSContext *ctx, uint32_t acm, uid_t *uid, gid_t *gid) {
     /*
@@ -329,17 +390,7 @@
 
 void sys_set_error_status(VFSContext *ctx) {
     if(ctx->sn && ctx->rq) {
-        int status = 500;
-        switch(ctx->vfs_errno) {
-            case EACCES: {
-                status = 403;
-                break;
-            }
-            case ENOENT: {
-                status = 404;
-                break;
-            }
-        }
+        int status = util_errno2status(ctx->vfs_errno);
         protocol_status(ctx->sn, ctx->rq, status, NULL);
     }
 }
@@ -375,3 +426,12 @@
 void sys_dir_close(VFS_DIR dir) {
     closedir(dir->data);
 }
+
+int sys_mkdir(VFSContext *ctx, char *path) {
+    mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+    return mkdir(path, mode);
+}
+
+int sys_unlink(VFSContext *ctx, char *path) {
+    return unlink(path);
+}
--- a/src/server/daemon/vfs.h	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/daemon/vfs.h	Sun Mar 17 17:54:20 2013 +0100
@@ -50,6 +50,8 @@
     int (*stat)(VFSContext *ctx, char *path, struct stat *buf);
     int (*fstat)(VFSContext *ctx, SYS_FILE fd, struct stat *buf);
     VFS_DIR (*opendir)(VFSContext *ctx, char *path);
+    int (*mkdir)(VFSContext *ctx, char *path);
+    int (*unlink)(VFSContext *ctx, char *path);
 };
 
 struct VFSContext {
@@ -111,8 +113,13 @@
 int vfs_readdir(VFS_DIR dir, VFS_ENTRY *entry);
 int vfs_readdir_stat(VFS_DIR dir, VFS_ENTRY *entry);
 void vfs_closedir(VFS_DIR dir);
+int vfs_mkdir(VFSContext *ctx, char *path);
+int vfs_unlink(VFSContext *ctx, char *path);
 
 // private
+typedef int(*vfs_op_f)(VFSContext *, char *);
+int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access);
+
 int sys_acl_check(VFSContext *ctx, uint32_t acm, uid_t *uid, gid_t *gid);
 void sys_set_error_status(VFSContext *ctx);
 ssize_t sys_file_read(SYS_FILE fd, void *buf, size_t nbyte);
@@ -120,6 +127,8 @@
 void sys_file_close(SYS_FILE fd);
 int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat);
 void sys_dir_close(VFS_DIR dir);
+int sys_mkdir(VFSContext *ctx, char *path);
+int sys_unlink(VFSContext *ctx, char *path);
 
 #ifdef	__cplusplus
 }
--- a/src/server/public/nsapi.h	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/public/nsapi.h	Sun Mar 17 17:54:20 2013 +0100
@@ -1315,6 +1315,8 @@
 #define netbuf_getbytes    netbuf_getbytes
 #define netbuf_grab        netbuf_grab
 
+NSAPI_PUBLIC int util_errno2status(int errno_value);
+#define util_errno2status util_errno2status
 
 
 /* end new macro and function definitions */
--- a/src/server/safs/service.c	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/safs/service.c	Sun Mar 17 17:54:20 2013 +0100
@@ -41,14 +41,6 @@
 
 #include <errno.h>
 
-// TODO: system sendfile Abstraktionen in neue Datei auslagern
-/*
-ssize_t sys_sendfile(int out_fd, int in_fd, off_t *off, size_t len) {
-    
-}
-*/
-#define sys_sendfile sendfile
-
 
 /*
  * prepares for servicing a file
--- a/src/server/util/util.c	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/util/util.c	Sun Mar 17 17:54:20 2013 +0100
@@ -49,6 +49,8 @@
 
 
 //include "nspr.h"
+#include <errno.h>
+
 #include "../daemon/netsite.h"
 #include "../public/nsapi.h"
 
@@ -172,3 +174,20 @@
     return rv;
 }
 #endif
+
+
+NSAPI_PUBLIC int util_errno2status(int errno_value) {
+    switch(errno_value) {
+        case 0: {
+            return 200;
+        }
+        case EACCES: {
+            return 403;
+        }
+        case ENOENT: {
+            return 404;
+            break;
+        }
+    }
+    return 500;
+}
--- a/src/server/webdav/webdav.c	Sun Mar 17 12:47:59 2013 +0100
+++ b/src/server/webdav/webdav.c	Sun Mar 17 17:54:20 2013 +0100
@@ -36,6 +36,7 @@
 #include "../util/pblock.h"
 #include "../util/date.h"
 
+#include "../daemon/vfs.h"
 #include "../daemon/protocol.h"
 
 #include "davparser.h"
@@ -158,12 +159,12 @@
 int webdav_mkcol(pblock *pb, Session *sn, Request *rq) {
     char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
     
-    int status = 201;
-    if(mkdir(ppath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
-        status = 403;
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    if(vfs_mkdir(vfs, ppath)) {
+        return REQ_ABORTED;
     }
     
-    protocol_status(sn, rq, status, NULL);
+    protocol_status(sn, rq, 201, NULL);
     pblock_removekey(pb_key_content_type, rq->srvhdrs);
     pblock_nninsert("content-length", 0, rq->srvhdrs);
     http_start_response(sn, rq);

mercurial