diff --git a/src/filecache.c b/src/filecache.c
index d4d3a264ba36482db548e787d075dbf6f83feab4..e3f9b6b1e79a052a3be47cd24b197e862e45251b 100644 (file)
--- a/src/filecache.c
+++ b/src/filecache.c
+/* $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
+
#define _XOPEN_SOURCE 500
#include <errno.h>
#include <ne_basic.h>
#include "filecache.h"
+#include "statcache.h"
#include "fusedav.h"
#include "session.h"
-#include "statcache.h"
struct file_info {
char *filename;
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;
void* file_cache_open(const char *path, int flags) {
struct file_info *fi;
char tempfile[PATH_MAX];
- char *length = NULL;
+ 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;
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;
if (req)
ne_request_destroy(req);
- if (length)
- free(length);
-
if (fi) {
if (fi->fd >= 0)
close(fi->fd);
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;
}
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;
fi->modified = 1;
- r = 0;
-
finish:
pthread_mutex_unlock(&fi->mutex);
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;
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;
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));
return r;
}
+
+off_t file_cache_get_size(void *f) {
+ struct file_info *fi = f;
+
+ assert(fi);
+
+ return fi->length;
+}