webdav uses the vfs api

Tue, 19 Mar 2013 17:38:32 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 19 Mar 2013 17:38:32 +0100
changeset 58
66c22e54aa90
parent 57
b3a89736b23e
child 59
ab25c0a231d0

webdav uses the vfs api

src/server/daemon/vfs.c file | annotate | diff | comparison | revisions
src/server/daemon/vfs.h file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c 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/util/util.h file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/daemon/vfs.c	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/daemon/vfs.c	Tue Mar 19 17:38:32 2013 +0100
@@ -96,7 +96,8 @@
     }
     
     // open file
-    int fd = open(path, oflags);
+    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+    int fd = open(path, oflags, mode);
     if(fd == -1) {
         if(ctx) {
             ctx->vfs_errno = errno;
@@ -410,14 +411,20 @@
 int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat) {
     struct dirent *e = readdir(dir->data);
     if(e) {
-        entry->name = e->d_name;
-        if(getstat) {
-            // TODO: check ACLs again for new path
-            if(fstatat(dir->fd, e->d_name, &entry->stat, 0)) {
-                entry->stat_errno = errno;
+        char *name = e->d_name;
+        if(!strcmp(name, ".") || !strcmp(name, "..")) {
+            return sys_dir_read(dir, entry, getstat);
+        } else {
+            entry->name = name;
+            if(getstat) {
+                // TODO: check ACLs again for new path
+                if(fstatat(dir->fd, e->d_name, &entry->stat, 0)) {
+                    entry->stat_errno = errno;
+                }
+                entry->stat_extra = NULL;
             }
+            return 1;
         }
-        return 1;
     } else {
         return 0;
     }
@@ -435,3 +442,18 @@
 int sys_unlink(VFSContext *ctx, char *path) {
     return unlink(path);
 }
+
+/* public file api */
+
+NSAPI_PUBLIC int system_fread(SYS_FILE fd, void *buf, int nbyte) {
+    return fd->io->read(fd, buf, nbyte);
+}
+
+NSAPI_PUBLIC int system_fwrite(SYS_FILE fd, const void *buf, int nbyte) {
+    return fd->io->write(fd, buf, nbyte);
+}
+
+NSAPI_PUBLIC int system_fclose(SYS_FILE fd) {
+    vfs_close(fd);
+    return 0;
+}
--- a/src/server/daemon/vfs.h	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/daemon/vfs.h	Tue Mar 19 17:38:32 2013 +0100
@@ -82,6 +82,7 @@
 struct VFSEntry {
     char *name;
     struct stat stat;
+    void *stat_extra;
     int stat_errno;
 };
 
--- a/src/server/daemon/webserver.c	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/daemon/webserver.c	Tue Mar 19 17:38:32 2013 +0100
@@ -35,6 +35,8 @@
 #include <stdlib.h>
 #include <dlfcn.h> 
 #include <grp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include "../public/nsapi.h"
 #include "../util/systhr.h"
@@ -135,8 +137,8 @@
                     LOG_LEVEL_INFO,
                     "server must be started as root to change uid");
     }
-
     
+   
     return 0;
 }
 
--- a/src/server/public/nsapi.h	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/public/nsapi.h	Tue Mar 19 17:38:32 2013 +0100
@@ -1315,6 +1315,11 @@
 #define netbuf_getbytes    netbuf_getbytes
 #define netbuf_grab        netbuf_grab
 
+/* file */
+NSAPI_PUBLIC int system_fread(SYS_FILE fd, void *buf, int nbyte);
+NSAPI_PUBLIC int system_fwrite(SYS_FILE fd, const void *buf, int nbyte);
+NSAPI_PUBLIC int system_fclose(SYS_FILE fd);
+
 NSAPI_PUBLIC int util_errno2status(int errno_value);
 #define util_errno2status util_errno2status
 
--- a/src/server/safs/service.c	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/safs/service.c	Tue Mar 19 17:38:32 2013 +0100
@@ -140,10 +140,6 @@
     //struct dirent *f;
     VFS_ENTRY f;
     while(vfs_readdir(dir, &f)) {
-        if(strcmp(f.name, ".") == 0 || strcmp(f.name, "..") == 0) {
-            continue;
-        }
-        
         sstr_t filename = sstr(f.name);
 
         sbuf_puts(out, "<a href=\"");
--- a/src/server/util/util.c	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/util/util.c	Tue Mar 19 17:38:32 2013 +0100
@@ -191,3 +191,34 @@
     }
     return 500;
 }
+
+
+NSAPI_PUBLIC
+sstr_t util_path_append(pool_handle_t *pool, char *path, char *ch) {
+    sstr_t parent = sstr(path);
+    sstr_t child = sstr(ch);
+    sstr_t newstr;
+    sstr_t s;
+    
+    s.length = 0;
+    s.ptr = NULL;
+    newstr.length = parent.length + child.length;
+    if(parent.ptr[parent.length - 1] != '/') {
+        s = sstrn("/", 1);
+        newstr.length++;
+    }
+    
+    newstr.ptr = pool_malloc(pool, newstr.length + 1);
+    if(!newstr.ptr) {
+        // TODO: error
+        return newstr;
+    }
+    if(s.length == 1) {
+        newstr = sstrncat(3, newstr, parent, s, child);
+    } else {
+        newstr = sstrncat(2, newstr, parent, child);
+    }
+    newstr.ptr[newstr.length] = '\0';
+    
+    return newstr;
+}
--- a/src/server/util/util.h	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/util/util.h	Tue Mar 19 17:38:32 2013 +0100
@@ -35,6 +35,8 @@
 #define BASE_UTIL_H
 
 #include "../daemon/netsite.h"
+#include "../ucx/string.h"
+#include "pool.h"
 #include <pwd.h>
 
 #ifndef NOINTNSAPI
@@ -221,6 +223,10 @@
 
 NSAPI_PUBLIC int util_qtoi(const char *q, const char **p);
 
+/* path utils */
+NSAPI_PUBLIC
+sstr_t util_path_append(pool_handle_t *pool, char *path, char *child);
+
 /* --- End common function prototypes --- */
 
 /* --- Begin Unix-only function prototypes --- */
--- a/src/server/webdav/webdav.c	Sun Mar 17 19:19:57 2013 +0100
+++ b/src/server/webdav/webdav.c	Tue Mar 19 17:38:32 2013 +0100
@@ -35,6 +35,7 @@
 #include "../util/pool.h"
 #include "../util/pblock.h"
 #include "../util/date.h"
+#include "../util/util.h"
 
 #include "../daemon/vfs.h"
 #include "../daemon/protocol.h"
@@ -77,24 +78,20 @@
     
     printf("PUT length: %d\n", length);
     
-    int status = 201;
-    FILE *out = fopen(ppath, "w");
+    //int status = 201;
+    //FILE *out = fopen(ppath, "w");
+    
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    SYS_FILE out = vfs_openWO(vfs, ppath);
     if(out == NULL) {
-        fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath);
-        protocol_status(sn, rq, 500, NULL);
+        fprintf(stderr, "vfs_openWO(%s, \"w\") failed\n", ppath);
+        //protocol_status(sn, rq, 500, NULL);
         return REQ_ABORTED;
     }
     
     if(length > 0) {
-        FILE *out = fopen(ppath, "w");
-        if(out == NULL) {
-            fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath);
-            return REQ_ABORTED;
-        }
-        setvbuf(out, NULL, _IONBF, 0);
-        
         size_t len = (length > 4096) ? (4096) : (length);
-        char *buffer = malloc(len);
+        char *buffer = pool_malloc(sn->pool, len);
         
         int r;
         int r2 = 0;
@@ -103,18 +100,18 @@
             if(r == NETBUF_EOF) {
                 break;
             }
-            fwrite(buffer, 1, r, out);
+            system_fwrite(out, buffer, r);
             
             r2 += r;
         }
         
-        free(buffer);
+        pool_free(sn->pool, buffer);
     } else {
         
     }
-    fclose(out);
+    vfs_close(out);
     
-    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);
@@ -126,12 +123,13 @@
     char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
     char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
     
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    
     int status = 204;
     
     struct stat st;
-    if(stat(ppath, &st) != 0) {
-        /* ERROR */
-        status = 403; /* TODO: check errno */
+    if(vfs_stat(vfs, ppath, &st)) {
+        return REQ_ABORTED;
     }
     
     if(!strcmp(uri, "/")) {
@@ -142,9 +140,9 @@
             status = 403;
         }
     } else {
-        if(unlink(ppath) != 0) {
+        if(vfs_unlink(vfs, ppath)) {
             /* ERROR */
-            status = 403; /* TODO: check errno */
+            return REQ_ABORTED;
         }
     }
     
@@ -233,17 +231,10 @@
     char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
     char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
     
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    
     struct stat st;
-    if(stat(ppath, &st) != 0) {
-        perror("webdav_propfind: stat");
-        fprintf(stderr, "   file: %s\n", ppath);
-        
-        /* TODO: check errno only set status */
-        protocol_status(sn, rq, 404, NULL);
-        pblock_removekey(pb_key_content_type, rq->srvhdrs);
-        pblock_nninsert("content-length", 0, rq->srvhdrs);
-        //http_start_response(sn, rq);
-        
+    if(vfs_stat(vfs, ppath, &st) != 0) {
         return REQ_ABORTED;
     } 
     
@@ -252,54 +243,16 @@
      * a response for every child
      */
     if(S_ISDIR(st.st_mode)) {
-        DIR *dir = opendir(ppath);
+        VFS_DIR dir = vfs_opendir(vfs, ppath);
         if(dir == NULL) {
-            protocol_status(sn, rq, 500, NULL);
-            printf("webdav_propfind: DIR is null\n");
             return REQ_ABORTED;
         }
         
-        struct dirent *f;
-        while((f = readdir(dir)) != NULL) {
-            if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
-                continue;
-            }
-            
-            sstr_t filename = sstr(f->d_name);
-            sstr_t _path = sstr(ppath); 
-            sstr_t _uri = sstr(uri);
-            sstr_t ps;
-            sstr_t us;
-            ps.length = 0;
-            ps.ptr = NULL;
-            us.length = 0;
-            us.ptr = NULL;
-            if(_path.ptr[_path.length - 1] != '/') {
-                ps = sstrn("/", 1);
-            }
-            if(_uri.ptr[_uri.length - 1] != '/') {
-                us = sstrn("/", 1);
-            }
-            
-            sstr_t newuri;
-            newuri.length = filename.length + _uri.length + us.length;
-            newuri.ptr = alloca(newuri.length + 1);
-            if(us.length == 1) {
-                newuri = sstrncat(3, newuri, _uri, us, filename);
-            } else {
-                newuri = sstrncat(2, newuri, _uri, filename);
-            }
-            
-            sstr_t newpath;
-            newpath.length = _path.length + filename.length + ps.length;
-            newpath.ptr = alloca(newpath.length + 1);
-            if(ps.length == 1) {
-                newpath = sstrncat(3, newpath, _path, ps, filename);
-            } else {
-                newpath = sstrncat(2, newpath, _path, filename);
-            }
-            
-            /* child response */
+        VFS_ENTRY entry;
+        while(vfs_readdir(dir, &entry)) {
+            sstr_t newpath = util_path_append(sn->pool, ppath, entry.name);
+            sstr_t newuri = util_path_append(sn->pool, uri, entry.name); 
+            // child response
             dav_resource_response(davrq, newpath, newuri);
         }
     }

mercurial