summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0c82f84)
raw | patch | inline | side by side (parent: 0c82f84)
author | Lennart Poettering <lennart@poettering.net> | |
Mon, 23 Jun 2014 13:05:26 +0000 (15:05 +0200) | ||
committer | Lennart Poettering <lennart@poettering.net> | |
Mon, 23 Jun 2014 13:05:57 +0000 (15:05 +0200) |
bootstrap.sh | patch | blob | history | |
configure.ac | patch | blob | history | |
doc/README.html.in | patch | blob | history | |
src/filecache.c | patch | blob | history | |
src/fusedav.c | patch | blob | history | |
src/session.c | patch | blob | history | |
src/statcache.c | patch | blob | history |
diff --git a/bootstrap.sh b/bootstrap.sh
index ea4ec9ad5d7b1748ab52112ecabb7d48f8da70b9..14a941b052c373349feb72c55a603feccec9e08e 100755 (executable)
--- a/bootstrap.sh
+++ b/bootstrap.sh
local V
V=$(echo "$2" | sed -e 's,\.,,g')
-
+
if [ -e "`which $1$V`" ] ; then
- P="$1$V"
+ P="$1$V"
else
- if [ -e "`which $1-$2`" ] ; then
- P="$1-$2"
- else
- P="$1"
- fi
+ if [ -e "`which $1-$2`" ] ; then
+ P="$1-$2"
+ else
+ P="$1"
+ fi
fi
shift 2
if [ "x$1" = "xam" ] ; then
run_versioned automake "$VERSION" -a -c --foreign
./config.status
-else
+else
rm -rf autom4te.cache
rm -f config.cache
diff --git a/configure.ac b/configure.ac
index ae19c480f3489aad8c94993892e1353a2e7ebf5c..b4ad76cc2d5e7b338f053ea1d9d2d35454e30747 100644 (file)
--- a/configure.ac
+++ b/configure.ac
for flag in $DESIRED_FLAGS ; do
AC_MSG_CHECKING([whether $CC accepts $flag])
- if test_gcc_flag $flag ; then
+ if test_gcc_flag $flag ; then
CFLAGS="$CFLAGS $flag"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
- done
+ done
fi
# 64 Bit LFS support
diff --git a/doc/README.html.in b/doc/README.html.in
index 2b3a3de418a750673235642d13dac9236f34398d..529f81f463a260a2c9ca0f138ce64d2252514430 100644 (file)
--- a/doc/README.html.in
+++ b/doc/README.html.in
<?xml version="1.0" encoding="iso-8859-15"?> <!-- -*-nxml-*- -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
-
+
<head>
<title>fusedav @PACKAGE_VERSION@</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<h2><a name="status">Current Status</a></h2>
<p>Version @PACKAGE_VERSION@ works fine.</p>
-
+
<h2><a name="documentation">Documentation</a></h2>
<p>After installation just run <tt>fusedav</tt> with two arguments: the WevDAV URL and the local mount point:</p>
diff --git a/src/filecache.c b/src/filecache.c
index 5bf7dfee31fea538a4486ffb555dd123a14a058a..dfbbae840185b354552e7d72e2763d49ff9cb369 100644 (file)
--- a/src/filecache.c
+++ b/src/filecache.c
char *filename;
int fd;
off_t server_length, length, present;
-
+
int readable;
int writable;
struct file_info *f, *r = NULL;
pthread_mutex_lock(&files_mutex);
-
+
for (f = files; f; f = f->next) {
-
+
pthread_mutex_lock(&f->mutex);
if (!f->dead && f->filename && !strcmp(path, f->filename)) {
f->ref++;
if (r)
break;
}
-
+
pthread_mutex_unlock(&files_mutex);
return f;
}
assert(fi);
pthread_mutex_lock(&files_mutex);
-
+
for (s = files, prev = NULL; s; s = s->next) {
if (s == fi) {
if (prev)
break;
}
-
+
prev = s;
}
-
+
pthread_mutex_unlock(&files_mutex);
}
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;
+ fi->server_length = fi->length = 0;
else
fi->server_length = fi->length = atoi(length);
ne_request_destroy(req);
-
+
if (flags & O_RDONLY || flags & O_RDWR) fi->readable = 1;
if (flags & O_WRONLY || flags & O_RDWR) fi->writable = 1;
pthread_mutex_init(&fi->mutex, NULL);
-
+
pthread_mutex_lock(&files_mutex);
fi->next = files;
files = fi;
pthread_mutex_unlock(&files_mutex);
fi->ref = 1;
-
+
return fi;
fail:
free(fi->filename);
free(fi);
}
-
+
return NULL;
}
if (l > fi->server_length)
l = fi->server_length;
-
+
if (l <= fi->present)
return 0;
if (lseek(fi->fd, fi->present, SEEK_SET) != fi->present)
return -1;
-
+
range.start = fi->present;
range.end = l-1;
range.total = 0;
-
+
if (ne_get_range64(session, fi->filename, &range, fi->fd) != NE_OK) {
fprintf(stderr, "GET failed: %s\n", ne_get_error(session));
errno = ENOENT;
int file_cache_read(void *f, char *buf, size_t size, off_t offset) {
struct file_info *fi = f;
ssize_t r = -1;
-
+
assert(fi && buf && size);
pthread_mutex_lock(&fi->mutex);
goto finish;
finish:
-
+
pthread_mutex_unlock(&fi->mutex);
return r;
if (load_up_to_unlocked(fi, offset) < 0)
goto finish;
-
+
if ((r = pwrite(fi->fd, buf, size, offset)) < 0)
goto finish;
finish:
pthread_mutex_unlock(&fi->mutex);
-
+
return r;
}
ne_session *session;
assert(fi);
-
+
if (!fi->writable) {
errno = EBADF;
goto finish;
r = 0;
goto finish;
}
-
+
if (load_up_to_unlocked(fi, (off_t) -1) < 0)
goto finish;
errno = EIO;
goto finish;
}
-
+
if (ne_put(session, fi->filename, fi->fd)) {
fprintf(stderr, "PUT failed: %s\n", ne_get_error(session));
errno = ENOENT;
r = 0;
finish:
-
+
return r;
}
pthread_mutex_lock(&fi->mutex);
r = file_cache_sync_unlocked(fi);
pthread_mutex_unlock(&fi->mutex);
-
+
return r;
}
while (files) {
struct file_info *fi = files;
-
+
pthread_mutex_lock(&fi->mutex);
fi->ref++;
pthread_mutex_unlock(&fi->mutex);
diff --git a/src/fusedav.c b/src/fusedav.c
index 619b091205d42f34ccd1e7a5b647156921e92ad6..8d3cdc72f3dda3abcdac12f7be15ab4fbb03aee4 100644 (file)
--- a/src/fusedav.c
+++ b/src/fusedav.c
int l;
pthread_once(&path_cvt_once, path_cvt_tsd_key_init);
-
+
if ((r = pthread_getspecific(path_cvt_tsd_key)))
free(r);
free(t);
pthread_setspecific(path_cvt_tsd_key, r);
-
+
return r;
}
void *userdata) {
int i, ret;
-
+
for (i = 0; i < MAX_REDIRECTS; i++) {
const ne_uri *u;
if (debug)
fprintf(stderr, "REDIRECT FROM '%s' to '%s'\n", path, u->path);
-
+
path = u->path;
}
ne_session *session,
const char *path,
const ne_proppatch_operation *ops) {
-
+
int i, ret;
-
+
for (i = 0; i < MAX_REDIRECTS; i++) {
const ne_uri *u;
if (debug)
fprintf(stderr, "REDIRECT FROM '%s' to '%s'\n", path, u->path);
-
+
path = u->path;
}
@@ -187,7 +187,7 @@ static void fill_stat(struct stat* st, const ne_prop_result_set *results, int is
const ne_propname getcontentlength = { "DAV:", "getcontentlength" };
const ne_propname getlastmodified = { "DAV:", "getlastmodified" };
const ne_propname creationdate = { "DAV:", "creationdate" };
-
+
assert(st && results);
rt = ne_propset_value(results, &resourcetype);
@@ -197,7 +197,7 @@ static void fill_stat(struct stat* st, const ne_prop_result_set *results, int is
cd = ne_propset_value(results, &creationdate);
memset(st, 0, sizeof(struct stat));
-
+
if (is_dir) {
st->st_mode = S_IFDIR | 0777;
st->st_nlink = 3; /* find will ignore this directory if nlin <= and st_size == 0 */
@@ -211,12 +211,12 @@ static void fill_stat(struct stat* st, const ne_prop_result_set *results, int is
st->st_atime = time(NULL);
st->st_mtime = glm ? ne_rfc1123_parse(glm) : 0;
st->st_ctime = cd ? ne_iso8601_parse(cd) : 0;
-
+
st->st_blocks = (st->st_size+511)/512;
/*fprintf(stderr, "a: %u; m: %u; c: %u\n", st->st_atime, st->st_mtime, st->st_ctime);*/
st->st_mode &= ~mask;
-
+
st->st_uid = getuid();
st->st_gid = getgid();
}
assert(fn);
assert(is_dir);
assert(l > 0);
-
+
if ((*is_dir = (fn[l-1] == '/')))
fn[l-1] = 0;
@@ -247,7 +247,7 @@ static void getdir_propfind_callback(void *userdata, const ne_uri *u, const ne_p
if (strcmp(fn, f->root) && fn[0]) {
char *h;
-
+
if ((t = strrchr(fn, '/')))
t++;
else
const char *root,
const char *fn,
void *user) {
-
+
struct fill_info *f = user;
char path[PATH_MAX];
char *h;
assert(f);
-
+
snprintf(path, sizeof(path), "%s/%s", !strcmp(root, "/") ? "" : root, fn);
-
+
f->filler(f->buf, h = ne_path_unescape(fn), NULL, 0);
free(h);
}
fuse_fill_dir_t filler,
__unused off_t offset,
__unused struct fuse_file_info *fi) {
-
+
struct fill_info f;
ne_session *session;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
-
+
if (dir_cache_enumerate(path, getdir_cache_callback, &f) < 0) {
if (debug)
fprintf(stderr, "DIR-CACHE-MISS\n");
-
- if (!(session = session_get(1)))
+
+ if (!(session = session_get(1)))
return -EIO;
dir_cache_begin(path);
-
+
if (simple_propfind_with_redirect(session, path, NE_DEPTH_ONE, query_properties, getdir_propfind_callback, &f) != NE_OK) {
dir_cache_finish(path, 2);
fprintf(stderr, "PROPFIND failed: %s\n", ne_get_error(session));
@@ -333,7 +333,7 @@ static void getattr_propfind_callback(void *userdata, const ne_uri *u, const ne_
strncpy(fn, u->path, sizeof(fn));
fn[sizeof(fn)-1] = 0;
strip_trailing_slash(fn, &is_dir);
-
+
fill_stat(st, results, is_dir);
stat_cache_set(fn, st);
}
@@ -341,7 +341,7 @@ static void getattr_propfind_callback(void *userdata, const ne_uri *u, const ne_
static int get_stat(const char *path, struct stat *stbuf) {
ne_session *session;
- if (!(session = session_get(1)))
+ if (!(session = session_get(1)))
return -EIO;
if (stat_cache_get(path, stbuf) == 0) {
if (debug)
fprintf(stderr, "unlink(%s)\n", path);
- if (!(session = session_get(1)))
+ if (!(session = session_get(1)))
return -EIO;
if ((r = get_stat(path, &st)) < 0)
if (!S_ISREG(st.st_mode))
return -EISDIR;
-
+
if (ne_delete(session, path)) {
fprintf(stderr, "DELETE failed: %s\n", ne_get_error(session));
return -ENOENT;
stat_cache_invalidate(path);
dir_cache_invalidate_parent(path);
-
+
return 0;
}
if (debug)
fprintf(stderr, "rmdir(%s)\n", path);
- if (!(session = session_get(1)))
+ if (!(session = session_get(1)))
return -EIO;
if ((r = get_stat(path, &st)) < 0)
return -ENOTDIR;
snprintf(fn, sizeof(fn), "%s/", path);
-
+
if (ne_delete(session, fn)) {
fprintf(stderr, "DELETE failed: %s\n", ne_get_error(session));
return -ENOENT;
if (debug)
fprintf(stderr, "mkdir(%s)\n", path);
- if (!(session = session_get(1)))
+ if (!(session = session_get(1)))
return -EIO;
snprintf(fn, sizeof(fn), "%s/", path);
-
+
if (ne_mkcol(session, fn)) {
fprintf(stderr, "MKCOL failed: %s\n", ne_get_error(session));
return -ENOENT;
stat_cache_invalidate(path);
dir_cache_invalidate_parent(path);
-
+
return 0;
}
snprintf(fn, sizeof(fn), "%s/", from);
from = fn;
}
-
+
if (ne_move(session, 1, from, to)) {
fprintf(stderr, "MOVE failed: %s\n", ne_get_error(session));
r = -ENOENT;
goto finish;
}
-
+
stat_cache_invalidate(from);
stat_cache_invalidate(to);
finish:
free(_from);
-
+
return r;
}
@@ -514,7 +514,7 @@ static int dav_release(const char *path, __unused struct fuse_file_info *info) {
r = -EIO;
goto finish;
}
-
+
if (!(f = file_cache_get(path))) {
fprintf(stderr, "release() called for closed file\n");
r = -EFAULT;
@@ -529,7 +529,7 @@ static int dav_release(const char *path, __unused struct fuse_file_info *info) {
finish:
if (f)
file_cache_unref(f);
-
+
return r;
}
}
finish:
-
+
if (f)
file_cache_unref(f);
if (debug)
fprintf(stderr, "mknod(%s)\n", path);
- if (!(session = session_get(1)))
+ if (!(session = session_get(1)))
return -EIO;
if (!S_ISREG(mode))
snprintf(tempfile, sizeof(tempfile), "%s/fusedav-empty-XXXXXX", "/tmp");
if ((fd = mkstemp(tempfile)) < 0)
return -errno;
-
+
unlink(tempfile);
-
+
if (ne_put(session, path, fd)) {
fprintf(stderr, "mknod:PUT failed: %s\n", ne_get_error(session));
close(fd);
static int dav_read(const char *path, char *buf, size_t size, off_t offset, __unused struct fuse_file_info *info) {
void *f = NULL;
ssize_t r;
-
+
path = path_cvt(path);
-
+
if (debug)
fprintf(stderr, "read(%s, %lu+%lu)\n", path, (unsigned long) offset, (unsigned long) size);
-
+
if (!(f = file_cache_get(path))) {
fprintf(stderr, "read() called for closed file\n");
r = -EFAULT;
@@ -640,7 +640,7 @@ static int dav_read(const char *path, char *buf, size_t size, off_t offset, __un
finish:
if (f)
file_cache_unref(f);
-
+
return r;
}
@@ -663,11 +663,11 @@ static int dav_write(const char *path, const char *buf, size_t size, off_t offse
r = -errno;
goto finish;
}
-
+
finish:
if (f)
file_cache_unref(f);
-
+
return r;
}
void *f = NULL;
int r = 0;
ne_session *session;
-
+
path = path_cvt(path);
-
+
if (debug)
fprintf(stderr, "truncate(%s, %lu)\n", path, (unsigned long) size);
if (!(session = session_get(1)))
r = -EIO;
goto finish;
-
+
if (!(f = file_cache_get(path))) {
fprintf(stderr, "truncate() called for closed file\n");
r = -EFAULT;
finish:
if (f)
file_cache_unref(f);
-
+
return r;
}
ne_proppatch_operation ops[2];
int r = 0;
char *date;
-
+
assert(path);
assert(buf);
path = path_cvt(path);
-
+
if (debug)
fprintf(stderr, "utime(%s, %lu, %lu)\n", path, (unsigned long) buf->actime, (unsigned long) buf->modtime);
-
+
ops[0].name = &getlastmodified;
ops[0].type = ne_propset;
ops[0].value = date = ne_rfc1123_date(buf->modtime);
r = -ENOTSUP;
goto finish;
}
-
+
stat_cache_invalidate(path);
finish:
free(date);
-
+
return r;
}
struct listxattr_info *l = userdata;
int n;
-
+
assert(l);
if (!value || !pname)
if (l->list) {
n = snprintf(l->list, l->space, "user.webdav(%s;%s)", pname->nspace, pname->name) + 1;
-
+
if (n >= (int) l->space) {
l->size += l->space;
l->space = 0;
return 1;
-
+
} else {
l->size += n;
l->space -= n;
-
+
if (l->list)
l->list += n;
-
+
return 0;
}
} else {
/* Calculate space */
-
+
l->size += strlen(pname->nspace) + strlen(pname->name) + 15;
return 0;
}
const char *path,
char *list,
size_t size) {
-
+
ne_session *session;
struct listxattr_info l;
-
+
assert(path);
l.space -= sizeof(MIME_XATTR);
l.size += sizeof(MIME_XATTR);
}
-
+
} else {
l.list = NULL;
l.space = 0;
l.size = sizeof(MIME_XATTR);
}
-
- if (!(session = session_get(1)))
+
+ if (!(session = session_get(1)))
return -EIO;
if (simple_propfind_with_redirect(session, path, NE_DEPTH_ZERO, NULL, listxattr_propfind_callback, &l) != NE_OK) {
__unused const ne_status *status) {
struct getxattr_info *g = userdata;
-
+
assert(g);
if (!value || !pname)
g->size = l;
} else {
/* Calculate space */
-
+
g->size = strlen(value);
return 0;
}
-
+
return 0;
}
@@ -902,13 +902,13 @@ static void getxattr_propfind_callback(void *userdata, __unused const ne_uri *u,
static int parse_xattr(const char *name, char *dnspace, size_t dnspace_length, char *dname, size_t dname_length) {
char *e;
size_t k;
-
+
assert(name);
assert(dnspace);
assert(dnspace_length);
assert(dname);
assert(dname_length);
-
+
if (strncmp(name, "user.webdav(", 12) ||
name[strlen(name)-1] != ')' ||
!(e = strchr(name+12, ';')))
@@ -921,7 +921,7 @@ static int parse_xattr(const char *name, char *dnspace, size_t dnspace_length, c
dnspace[k] = 0;
e++;
-
+
if ((k = strlen(e)) > dname_length-1)
return -1;
struct getxattr_info g;
ne_propname props[2];
char dnspace[128], dname[128];
-
+
assert(path);
path = path_cvt(path);
}
g.propname = props[0];
-
+
if (!(session = session_get(1)))
return -EIO;
path = path_cvt(path);
name = fix_xattr(name);
-
+
if (debug)
fprintf(stderr, "setxattr(%s, %s)\n", path, name);
r = ENOTSUP;
goto finish;
}
-
+
if (parse_xattr(name, dnspace, sizeof(dnspace), dname, sizeof(dname)) < 0) {
r = -ENOATTR;
goto finish;
propname.nspace = dnspace;
propname.name = dname;
-
+
/* Add trailing NUL byte if required */
if (!memchr(value, 0, size)) {
value_fixed = malloc(size+1);
assert(value_fixed);
-
+
memcpy(value_fixed, value, size);
value_fixed[size] = 0;
value = value_fixed;
}
-
+
ops[0].name = &propname;
ops[0].type = ne_propset;
ops[0].value = value;
-
+
ops[1].name = NULL;
if (!(session = session_get(1))) {
r = -EIO;
goto finish;
}
-
+
if (proppatch_with_redirect(session, path, ops)) {
fprintf(stderr, "PROPPATCH failed: %s\n", ne_get_error(session));
r = -ENOTSUP;
goto finish;
}
-
+
stat_cache_invalidate(path);
finish:
free(value_fixed);
-
+
return r;
}
path = path_cvt(path);
name = fix_xattr(name);
-
+
if (debug)
fprintf(stderr, "removexattr(%s, %s)\n", path, name);
propname.nspace = dnspace;
propname.name = dname;
-
+
ops[0].name = &propname;
ops[0].type = ne_propremove;
ops[0].value = NULL;
-
+
ops[1].name = NULL;
if (!(session = session_get(1))) {
r = -EIO;
goto finish;
}
-
+
if (proppatch_with_redirect(session, path, ops)) {
fprintf(stderr, "PROPPATCH failed: %s\n", ne_get_error(session));
r = -ENOTSUP;
goto finish;
}
-
+
stat_cache_invalidate(path);
finish:
-
+
return r;
}
const ne_propname executable = { "http://apache.org/dav/props/", "executable" };
ne_proppatch_operation ops[2];
int r = 0;
-
+
assert(path);
path = path_cvt(path);
-
+
if (debug)
fprintf(stderr, "chmod(%s, %04o)\n", path, mode);
-
+
ops[0].name = &executable;
ops[0].type = ne_propset;
ops[0].value = mode & 0111 ? "T" : "F";
r = -ENOTSUP;
goto finish;
}
-
+
stat_cache_invalidate(path);
finish:
-
+
return r;
}
e++;
else
e = argv0;
-
+
fprintf(stderr,
"%s [-hDL] [-t SECS] [-u USERNAME] [-p PASSWORD] [-o OPTIONS] URL MOUNTPOINT\n"
"\t-h Show this help\n"
static int setup_signal_handlers(void) {
struct sigaction sa;
sigset_t m;
-
+
sa.sa_handler = exit_handler;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
-
+
if (sigaction(SIGHUP, &sa, NULL) == -1 ||
sigaction(SIGINT, &sa, NULL) == -1 ||
sigaction(SIGTERM, &sa, NULL) == -1) {
-
+
fprintf(stderr, "Cannot set exit signal handlers: %s\n", strerror(errno));
return -1;
}
-
+
sa.sa_handler = SIG_IGN;
-
+
if (sigaction(SIGPIPE, &sa, NULL) == -1) {
fprintf(stderr, "Cannot set ignored signals: %s\n", strerror(errno));
return -1;
sigaddset(&m, SIGPIPE);
sigaddset(&m, SIGUSR1);
pthread_sigmask(SIG_SETMASK, &m, NULL);
-
+
return 0;
}
char _owner[64], *owner;
int i;
int ret;
-
+
lock = ne_lock_create();
assert(lock);
}
ne_fill_server_uri(session, &lock->uri);
-
+
lock->uri.path = strdup(base_directory);
lock->depth = NE_DEPTH_INFINITE;
lock->timeout = lock_timeout;
if (debug)
fprintf(stderr, "Acquiring lock...\n");
-
+
for (i = 0; i < MAX_REDIRECTS; i++) {
const ne_uri *u;
lock_store = ne_lockstore_create();
assert(lock_store);
-
+
ne_lockstore_add(lock_store, lock);
-
+
return 0;
}
while (!lock_thread_exit) {
int r, t;
-
+
lock->timeout = lock_timeout;
pthread_sigmask(SIG_BLOCK, &block, NULL);
t = 1;
sleep(t);
}
-
+
if (debug)
fprintf(stderr, "lock_thread exiting\n");
pthread_t lock_thread;
int lock_thread_running = 0;
int enable_locking = 0;
-
+
static char *mount_args_strings[] = {
NULL, /* path*/
NULL, /* -o */
NULL,
NULL};
-
+
struct fuse_args mount_args = {
.argc = 1,
.argv = mount_args_strings,
.allocated = 0
};
-
+
if (ne_sock_init()) {
fprintf(stderr, "Failed to initialize libneon.\n");
goto finish;
fprintf(stderr, "fusedav requires libneon built with SSL, SSL thread safety and LFS enabled.\n");
goto finish;
}
-
+
mask = umask(0);
umask(mask);
if (setup_signal_handlers() < 0)
goto finish;
-
+
while ((c = getopt(argc, argv, "hu:p:Do:Lt:")) != -1) {
switch(c) {
case 'u':
u = optarg;
break;
-
+
case 'p':
p = optarg;
break;
-
+
case 'D':
debug = !debug;
break;
goto finish;
}
break;
-
+
case 'h':
ret = 0;
mount_args_strings[2] = o;
mount_args.argc += 2;
}
-
+
if ((fuse_fd = fuse_mount(mountpoint, &mount_args)) < 0) {
fprintf(stderr, "Failed to mount FUSE file system.\n");
goto finish;
fprintf(stderr, "Failed to create FUSE object.\n");
goto finish;
}
-
+
if (enable_locking && create_lock() >= 0) {
int r;
if ((r = pthread_create(&lock_thread, NULL, lock_thread_func, NULL)) < 0) {
fprintf(stderr, "pthread_create(): %s\n", strerror(r));
goto finish;
}
-
+
lock_thread_running = 1;
}
-
+
fuse_loop_mt(fuse);
if (debug)
fprintf(stderr, "Exiting cleanly.\n");
-
+
ret = 0;
-
+
finish:
-
+
if (lock_thread_running) {
lock_thread_exit = 1;
pthread_kill(lock_thread, SIGUSR1);
if (fuse)
fuse_destroy(fuse);
-
+
if (fuse_fd >= 0)
fuse_unmount(mountpoint);
-
+
file_cache_close_all();
cache_free();
session_free();
-
+
return ret;
}
diff --git a/src/session.c b/src/session.c
index acf4a581c1c6bb6d58af4b4f650e2c9ce7ad2566..d1224b1353c76028094810ee3c375854f623838e 100644 (file)
--- a/src/session.c
+++ b/src/session.c
}
}
}
-
+
fprintf(stderr, "%s: ", p);
r = fgets(q, sizeof(q), stdin);
l = strlen(q);
tcsetattr(fileno(stdin), TCSANOW, &t);
fprintf(stderr, "\n");
}
-
+
return r ? strdup(r) : NULL;
}
@@ -102,7 +102,7 @@ static int ssl_verify_cb(__unused void *userdata, __unused int failures, __unuse
static int ne_auth_creds_cb(__unused void *userdata, const char *realm, int attempt, char *u, char *p) {
int r = -1;
-
+
pthread_mutex_lock(&credential_mutex);
if (attempt) {
@@ -114,10 +114,10 @@ static int ne_auth_creds_cb(__unused void *userdata, const char *realm, int atte
if (!username || !password)
fprintf(stderr, "Realm '%s' requires authentication.\n", realm);
-
+
if (!username)
username = ask_user("Username", 0);
-
+
if (username && !password)
password = ask_user("Password", 1);
return NULL;
scheme = uri.scheme ? uri.scheme : "http";
-
+
if (!(session = ne_session_create(scheme, uri.host, uri.port ? uri.port : ne_uri_defaultport(scheme)))) {
fprintf(stderr, "Failed to create session\n");
return NULL;
if (with_lock && lock_store)
ne_lockstore_register(lock_store, session);
-
+
return session;
}
ne_session *session_get(int with_lock) {
ne_session *session;
-
+
pthread_once(&session_once, session_tsd_key_init);
if ((session = pthread_getspecific(session_tsd_key)))
int session_set_uri(const char *s, const char *u, const char *p) {
int l;
-
+
assert(!b_uri);
assert(!username);
assert(!password);
password = strdup(p);
return 0;
-
+
finish:
-
+
if (b_uri) {
ne_uri_free(&uri);
b_uri = 0;
strcmp(u->host, uri.host) == 0 &&
u->port == uri.port;
}
-
diff --git a/src/statcache.c b/src/statcache.c
index b7cb063bb305cf950fe3e7474b014608fa16cdfb..3105a5b84c9f2620fd9439584df135551acc5a9e 100644 (file)
--- a/src/statcache.c
+++ b/src/statcache.c
if (debug)
fprintf(stderr, "CGET: %s\n", fn);
-
+
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
pthread_mutex_lock(&stat_cache_mutex);
-
+
if (ce->stat_info.valid &&
ce->stat_info.filename &&
ce->stat_info.hash == h &&
!strcmp(ce->stat_info.filename, fn) &&
time(NULL) <= ce->stat_info.dead) {
-
+
*st = ce->stat_info.st;
if ((f = file_cache_get(fn))) {
}
pthread_mutex_unlock(&stat_cache_mutex);
-
+
return r;
}
if (debug)
fprintf(stderr, "CSET: %s\n", fn);
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
ce->stat_info.filename = strdup(fn);
ce->stat_info.hash = h;
}
-
+
ce->stat_info.st = *st;
ce->stat_info.dead = time(NULL)+CACHE_TIMEOUT;
ce->stat_info.valid = 1;
struct cache_entry *ce;
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
ce->stat_info.valid = 0;
free(ce->stat_info.filename);
ce->stat_info.filename = NULL;
-
+
pthread_mutex_unlock(&stat_cache_mutex);
}
struct cache_entry *ce;
struct dir_entry *de = NULL, *de2 = NULL;
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
-
+
pthread_mutex_lock(&dir_cache_mutex);
if (!ce->dir_info.filling) {
-
+
if (!ce->dir_info.filename || ce->dir_info.hash != h || strcmp(ce->dir_info.filename, fn)) {
free(ce->dir_info.filename);
ce->dir_info.filename = strdup(fn);
ce->dir_info.valid2 = 0;
ce->dir_info.filling = 1;
}
-
+
pthread_mutex_unlock(&dir_cache_mutex);
free_dir_entries(de);
free_dir_entries(de2);
struct cache_entry *ce;
struct dir_entry *de = NULL;
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
-
+
pthread_mutex_lock(&dir_cache_mutex);
-
+
if (ce->dir_info.filling &&
ce->dir_info.filename &&
ce->dir_info.hash == h &&
assert(!ce->dir_info.valid2);
if (success) {
-
+
ce->dir_info.valid2 = 1;
ce->dir_info.filling = 0;
ce->dir_info.dead2 = time(NULL)+CACHE_TIMEOUT;
-
+
if (!ce->dir_info.in_use) {
de = ce->dir_info.entries;
ce->dir_info.entries = ce->dir_info.entries2;
ce->dir_info.valid2 = 0;
ce->dir_info.valid = 1;
}
-
+
} else {
ce->dir_info.filling = 0;
de = ce->dir_info.entries2;
uint32_t h;
struct cache_entry *ce;
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
-
+
pthread_mutex_lock(&dir_cache_mutex);
-
+
if (ce->dir_info.filling &&
ce->dir_info.filename &&
ce->dir_info.hash == h &&
assert(n);
strcpy(n->filename, subdir);
-
+
n->next = ce->dir_info.entries2;
ce->dir_info.entries2 = n;
}
@@ -290,12 +290,12 @@ int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *su
int r = -1;
assert(cache && f);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
-
+
pthread_mutex_lock(&dir_cache_mutex);
-
+
if (ce->dir_info.valid &&
ce->dir_info.filename &&
ce->dir_info.hash == h &&
@@ -322,23 +322,23 @@ int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *su
r = 0;
}
-
+
pthread_mutex_unlock(&dir_cache_mutex);
free_dir_entries(de);
return r;
-}
+}
void dir_cache_invalidate(const char*fn) {
uint32_t h;
struct cache_entry *ce;
struct dir_entry *de = NULL;
assert(cache && fn);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
pthread_mutex_lock(&dir_cache_mutex);
-
+
if (ce->dir_info.valid &&
ce->dir_info.filename &&
ce->dir_info.hash == h &&
de = ce->dir_info.entries;
ce->dir_info.entries = NULL;
}
-
+
pthread_mutex_unlock(&dir_cache_mutex);
free_dir_entries(de);
}
if (p[l-1] == '/')
p[l-1] = 0;
}
-
+
dir_cache_invalidate(p);
free(p);
} else
}
void cache_alloc(void) {
-
+
if (cache)
return;
assert(cache);
memset(cache, 0, sizeof(struct cache_entry)*CACHE_SIZE);
}
-