Code

* first try at debianization
[fusedav.git] / src / filecache.c
index 429385d63e25118b7aa1035bd98bd46ea65b251f..ac88b66227e84029c636210dcc7b153a468dff53 100644 (file)
@@ -1,4 +1,26 @@
-#define _XOPEN_SOURCE 500
+/* $Id$ */
+
+/***
+  This file is part of fusedav.
+
+  fusedav is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+  
+  fusedav is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+  
+  You should have received a copy of the GNU General Public License
+  along with fusedav; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <errno.h>
 #include <string.h>
@@ -19,9 +41,9 @@
 #include <ne_basic.h>
 
 #include "filecache.h"
+#include "statcache.h"
 #include "fusedav.h"
 #include "session.h"
-#include "statcache.h"
 
 struct file_info {
     char *filename;
@@ -44,7 +66,7 @@ struct file_info {
 static struct file_info *files = NULL;
 static pthread_mutex_t files_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-int file_cache_sync_unlocked(struct file_info *fi);
+static int file_cache_sync_unlocked(struct file_info *fi);
 
 void* file_cache_get(const char *path) {
     struct file_info *f, *r = NULL;
@@ -136,21 +158,21 @@ int file_cache_close(void *f) {
 void* file_cache_open(const char *path, int flags) {
     struct file_info *fi;
     char tempfile[PATH_MAX];
-    char *length = NULL;
-    ne_request *req;
+    const char *length = NULL;
+    ne_request *req = NULL;
     ne_session *session;
 
+    if (!(session = session_get(1))) {
+        errno = EIO;
+        goto fail;
+    }
+
     if ((fi = file_cache_get(path))) {
         if (flags & O_RDONLY || flags & O_RDWR) fi->readable = 1;
         if (flags & O_WRONLY || flags & O_RDWR) fi->writable = 1;
         return fi;
     }
 
-    if (!(session = session_get())) {
-        errno = -EIO;
-        return NULL;
-    }
-
     fi = malloc(sizeof(struct file_info));
     memset(fi, 0, sizeof(struct file_info));
     fi->fd = -1;
@@ -165,24 +187,19 @@ void* file_cache_open(const char *path, int flags) {
     req = ne_request_create(session, "HEAD", path);
     assert(req);
 
-    ne_add_response_header_handler(req, "Content-Length", ne_duplicate_header, &length);
-    
     if (ne_request_dispatch(req) != NE_OK) {
         fprintf(stderr, "HEAD failed: %s\n", ne_get_error(session));
         errno = ENOENT;
         goto fail;
     }
 
-    if (!length) {
-        fprintf(stderr, "HEAD did not return content length.\n");
-        errno = EPROTO;
-        goto fail;
-    }
-
-    fi->server_length = fi->length = atoi(length);
+    if (!(length = ne_get_response_header(req, "Content-Length")))
+        /* dirty hack, since Apache doesn't send the file size if the file is empty */
+        fi->server_length = fi->length = 0; 
+    else
+        fi->server_length = fi->length = atoi(length);
 
     ne_request_destroy(req);
-    free(length);
     
     if (flags & O_RDONLY || flags & O_RDWR) fi->readable = 1;
     if (flags & O_WRONLY || flags & O_RDWR) fi->writable = 1;
@@ -203,9 +220,6 @@ fail:
     if (req)
         ne_request_destroy(req);
 
-    if (length)
-        free(length);
-
     if (fi) {
         if (fi->fd >= 0)
             close(fi->fd);
@@ -218,10 +232,11 @@ fail:
 
 static int load_up_to_unlocked(struct file_info *fi, off_t l) {
     ne_content_range range;
-    assert(fi);
     ne_session *session;
 
-    if (!(session = session_get())) {
+    assert(fi);
+
+    if (!(session = session_get(1))) {
         errno = EIO;
         return -1;
     }
@@ -237,8 +252,9 @@ static int load_up_to_unlocked(struct file_info *fi, off_t l) {
 
     range.start = fi->present;
     range.end = l-1;
+    range.total = 0;
     
-    if (ne_get_range(session, fi->filename, &range, fi->fd)) {
+    if (ne_get_range(session, fi->filename, &range, fi->fd) != NE_OK) {
         fprintf(stderr, "GET failed: %s\n", ne_get_error(session));
         errno = ENOENT;
         return -1;
@@ -296,8 +312,6 @@ int file_cache_write(void *f, const char *buf, size_t size, off_t offset) {
 
     fi->modified = 1;
 
-    r = 0;
-
 finish:
     pthread_mutex_unlock(&fi->mutex);
     
@@ -306,9 +320,10 @@ finish:
 
 int file_cache_truncate(void *f, off_t s) {
     struct file_info *fi = f;
-    assert(fi);
     int r;
 
+    assert(fi);
+
     pthread_mutex_lock(&fi->mutex);
 
     fi->length = s;
@@ -322,13 +337,9 @@ int file_cache_truncate(void *f, off_t s) {
 int file_cache_sync_unlocked(struct file_info *fi) {
     int r = -1;
     ne_session *session;
-    assert(fi);
-
-    if (!(session = session_get())) {
-        errno = EIO;
-        goto finish;
-    }
 
+    assert(fi);
+    
     if (!fi->writable) {
         errno = EBADF;
         goto finish;
@@ -345,6 +356,10 @@ int file_cache_sync_unlocked(struct file_info *fi) {
     if (lseek(fi->fd, 0, SEEK_SET) == (off_t)-1)
         goto finish;
 
+    if (!(session = session_get(1))) {
+        errno = EIO;
+        goto finish;
+    }
     
     if (ne_put(session, fi->filename, fi->fd)) {
         fprintf(stderr, "PUT failed: %s\n", ne_get_error(session));
@@ -396,3 +411,11 @@ int file_cache_close_all(void) {
 
     return r;
 }
+
+off_t file_cache_get_size(void *f) {
+    struct file_info *fi = f;
+
+    assert(fi);
+
+    return fi->length;
+}