Tue, 19 Mar 2013 17:38:32 +0100
webdav uses the vfs api
--- 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); } }