Remove support for Coda
This commit is contained in:
@ -26,9 +26,9 @@ pkgsyscachedir = $(dav_syscachedir)/@PACKAGE@
|
||||
ssbindir = @ssbindir@
|
||||
|
||||
sbin_PROGRAMS = mount.davfs umount.davfs
|
||||
mount_davfs_SOURCES = cache.c dav_coda.c \
|
||||
dav_fuse.c kernel_interface.c mount_davfs.c webdav.c \
|
||||
cache.h coda.h defaults.h fuse_kernel.h \
|
||||
mount_davfs_SOURCES = cache.c \
|
||||
kernel_interface.c mount_davfs.c webdav.c \
|
||||
cache.h defaults.h fuse_kernel.h \
|
||||
kernel_interface.h mount_davfs.h webdav.h
|
||||
umount_davfs_SOURCES = umount_davfs.c defaults.h
|
||||
|
||||
|
93
src/cache.c
93
src/cache.c
@ -223,11 +223,6 @@ static off_t write_dir_entry_dummy(int fd, off_t off, const dav_node *node,
|
||||
}
|
||||
static dav_write_dir_entry_fn write_dir_entry = write_dir_entry_dummy;
|
||||
|
||||
/* Points to a flag in the kernel interface module. If set to 1, at the end of
|
||||
the upcall the kernel dentries will be flushed. */
|
||||
static int flush_dummy;
|
||||
static int *flush = &flush_dummy;
|
||||
|
||||
/* Whether to create debug messages. */
|
||||
static int debug;
|
||||
|
||||
@ -365,7 +360,7 @@ get_child(const dav_node *parent, const char *name)
|
||||
}
|
||||
|
||||
static dav_handle *
|
||||
get_file_handle(dav_node * node, int fd, int accmode, pid_t pid, pid_t pgid);
|
||||
get_file_handle(dav_node * node, int fd);
|
||||
|
||||
static int
|
||||
has_permission(const dav_node *node, uid_t uid, int how);
|
||||
@ -473,8 +468,7 @@ set_cache_file_times(dav_node *node)
|
||||
}
|
||||
|
||||
static int
|
||||
open_file(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid,
|
||||
uid_t uid);
|
||||
open_file(int *fd, dav_node *node, int flags);
|
||||
|
||||
static int
|
||||
update_cache_file(dav_node *node);
|
||||
@ -685,7 +679,6 @@ dav_close_cache(int got_sigterm)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Closing cache");
|
||||
|
||||
write_dir_entry = &write_dir_entry_dummy;
|
||||
flush = &flush_dummy;
|
||||
|
||||
clean_tree(root, !got_sigterm);
|
||||
|
||||
@ -725,18 +718,11 @@ dav_close_cache(int got_sigterm)
|
||||
|
||||
|
||||
size_t
|
||||
dav_register_kernel_interface(dav_write_dir_entry_fn write_fn, int *flush_flag,
|
||||
unsigned int *blksize)
|
||||
dav_register_kernel_interface(dav_write_dir_entry_fn write_fn)
|
||||
{
|
||||
if (write_fn)
|
||||
write_dir_entry = write_fn;
|
||||
|
||||
if (flush_flag)
|
||||
flush = flush_flag;
|
||||
|
||||
if (blksize)
|
||||
*blksize = fs_stat->bsize;
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
@ -797,7 +783,6 @@ dav_tidy_cache(void)
|
||||
delete_cache_file(node->parent);
|
||||
node->parent->utime = 0;
|
||||
remove_node(node);
|
||||
*flush = 1;
|
||||
}
|
||||
}
|
||||
} else if (is_locked(node) && !is_dirty(node) && !is_created(node)
|
||||
@ -842,9 +827,7 @@ dav_close(dav_node *node, int fd, int flags, pid_t pid, pid_t pgid)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " close %s", node->path);
|
||||
|
||||
dav_handle *fh = get_file_handle(node, fd,
|
||||
is_dir(node) ? O_RDWR : flags & O_ACCMODE,
|
||||
pid, pgid);
|
||||
dav_handle *fh = get_file_handle(node, fd);
|
||||
if (!fh)
|
||||
return EBADF;
|
||||
|
||||
@ -853,7 +836,6 @@ dav_close(dav_node *node, int fd, int flags, pid_t pid, pid_t pgid)
|
||||
if (!node->parent && node != root && !is_open(node)) {
|
||||
remove_from_table(node);
|
||||
delete_node(node);
|
||||
*flush = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -894,7 +876,6 @@ dav_close(dav_node *node, int fd, int flags, pid_t pid, pid_t pgid)
|
||||
delete_cache_file(node->parent);
|
||||
node->parent->utime = 0;
|
||||
remove_node(node);
|
||||
*flush = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -953,7 +934,6 @@ dav_create(dav_node **nodep, dav_node *parent, const char *name, uid_t uid,
|
||||
&(*nodep)->mime_type);
|
||||
(*nodep)->utime = (*nodep)->smtime;
|
||||
delete_cache_file(parent);
|
||||
*flush = 1;
|
||||
parent->mtime = (*nodep)->mtime;
|
||||
parent->ctime = (*nodep)->mtime;
|
||||
add_to_changed(*nodep);
|
||||
@ -1117,7 +1097,6 @@ dav_mkdir(dav_node **nodep, dav_node *parent, const char *name, uid_t uid,
|
||||
(*nodep)->smtime = (*nodep)->mtime;
|
||||
(*nodep)->utime = (*nodep)->mtime;
|
||||
delete_cache_file(parent);
|
||||
*flush = 1;
|
||||
parent->mtime = (*nodep)->mtime;
|
||||
parent->ctime = (*nodep)->mtime;
|
||||
} else {
|
||||
@ -1129,8 +1108,7 @@ dav_mkdir(dav_node **nodep, dav_node *parent, const char *name, uid_t uid,
|
||||
|
||||
|
||||
int
|
||||
dav_open(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid,
|
||||
int open_create)
|
||||
dav_open(int *fd, dav_node *node, int flags, uid_t uid, int open_create)
|
||||
{
|
||||
if (!is_valid(node))
|
||||
return ENOENT;
|
||||
@ -1157,7 +1135,7 @@ dav_open(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid,
|
||||
if (create_dir_cache_file(node) != 0)
|
||||
return EIO;
|
||||
node->atime = time(NULL);
|
||||
return open_file(fd, node, O_RDWR, pid, pgid, uid);
|
||||
return open_file(fd, node, O_RDWR);
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
@ -1165,7 +1143,7 @@ dav_open(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid,
|
||||
|
||||
ret = update_cache_file(node);
|
||||
if (!ret)
|
||||
ret = open_file(fd, node, flags & O_ACCMODE, pid, pgid, uid);
|
||||
ret = open_file(fd, node, flags & O_ACCMODE);
|
||||
|
||||
} else {
|
||||
|
||||
@ -1177,14 +1155,12 @@ dav_open(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid,
|
||||
ret = create_cache_file(node);
|
||||
if (!ret) {
|
||||
ret = open_file(fd, node,
|
||||
flags & (O_ACCMODE | O_TRUNC | O_APPEND),
|
||||
pid, pgid, uid);
|
||||
flags & (O_ACCMODE | O_TRUNC | O_APPEND));
|
||||
}
|
||||
} else if (!ret) {
|
||||
ret = update_cache_file(node);
|
||||
if (!ret)
|
||||
ret = open_file(fd, node, flags & (O_ACCMODE | O_APPEND),
|
||||
pid, pgid, uid);
|
||||
ret = open_file(fd, node, flags & (O_ACCMODE | O_APPEND));
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
@ -1202,7 +1178,7 @@ dav_read(ssize_t *len, dav_node * node, int fd, char *buf, size_t size,
|
||||
if (!exists(node))
|
||||
return ENOENT;
|
||||
|
||||
dav_handle *fh = get_file_handle(node, fd, 0, 0, 0);
|
||||
dav_handle *fh = get_file_handle(node, fd);
|
||||
if (!fh)
|
||||
return EBADF;
|
||||
if (fh->flags == O_WRONLY)
|
||||
@ -1247,7 +1223,6 @@ dav_remove(dav_node *parent, const char *name, uid_t uid)
|
||||
if (!node) {
|
||||
delete_cache_file(parent);
|
||||
parent->utime = 0;
|
||||
*flush = 1;
|
||||
return ENOENT;
|
||||
}
|
||||
if (is_dir(node))
|
||||
@ -1277,7 +1252,6 @@ dav_remove(dav_node *parent, const char *name, uid_t uid)
|
||||
delete_cache_file(parent);
|
||||
parent->mtime = time(NULL);
|
||||
parent->ctime = parent->mtime;
|
||||
*flush = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1309,7 +1283,6 @@ dav_rename(dav_node *src_parent, const char *src_name, dav_node *dst_parent,
|
||||
if (!src) {
|
||||
delete_cache_file(src_parent);
|
||||
src_parent->utime = 0;
|
||||
*flush = 1;
|
||||
return ENOENT;
|
||||
}
|
||||
if (src == backup || (dst && is_backup(dst)))
|
||||
@ -1341,7 +1314,6 @@ dav_rename(dav_node *src_parent, const char *src_name, dav_node *dst_parent,
|
||||
delete_cache_file(dst_parent);
|
||||
dst_parent->mtime = time(NULL);
|
||||
dst_parent->ctime = dst_parent->mtime;
|
||||
*flush = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1366,7 +1338,6 @@ dav_rmdir(dav_node *parent, const char *name, uid_t uid)
|
||||
if (!node) {
|
||||
delete_cache_file(parent);
|
||||
parent->utime = 0;
|
||||
*flush = 1;
|
||||
return ENOENT;
|
||||
}
|
||||
if (node == backup)
|
||||
@ -1382,7 +1353,6 @@ dav_rmdir(dav_node *parent, const char *name, uid_t uid)
|
||||
delete_cache_file(parent);
|
||||
parent->mtime = time(NULL);
|
||||
parent->ctime = parent->mtime;
|
||||
*flush = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1595,7 +1565,7 @@ dav_write(size_t *written, dav_node * node, int fd, char *buf, size_t size,
|
||||
if (is_dir(node))
|
||||
return EBADF;
|
||||
|
||||
dav_handle *fh = get_file_handle(node, fd, 0, 0, 0);
|
||||
dav_handle *fh = get_file_handle(node, fd);
|
||||
if (!fh)
|
||||
return EBADF;
|
||||
if (fh->flags == O_RDONLY)
|
||||
@ -1722,7 +1692,6 @@ backup_node(dav_node *orig)
|
||||
delete_cache_file(backup);
|
||||
backup->mtime = time(NULL);
|
||||
backup->ctime = backup->mtime;
|
||||
*flush = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -2185,8 +2154,7 @@ remove_node(dav_node *node)
|
||||
function will do nothing.
|
||||
utime and retry will be updated.
|
||||
If the contents or the mtime of the dir has changed, the dir-cache-file
|
||||
will be deleted and the flush flag will be set to force new lookups
|
||||
by the kernel. */
|
||||
will be deleted. */
|
||||
static int
|
||||
update_directory(dav_node *dir, time_t refresh)
|
||||
{
|
||||
@ -2252,7 +2220,6 @@ update_directory(dav_node *dir, time_t refresh)
|
||||
|
||||
if (changed) {
|
||||
delete_cache_file(dir);
|
||||
*flush = 1;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
@ -2268,8 +2235,6 @@ update_directory(dav_node *dir, time_t refresh)
|
||||
If props is incompatibel with node or indicates a lost update problem,
|
||||
a new node is created from props and the old node is deleted, creating
|
||||
a local back up if necessary.
|
||||
If nodes are removed or created, flag flush is set, to force new lookups
|
||||
by the kernel.
|
||||
node : The node to be updated. It must not be the root node and have a
|
||||
valid parent.
|
||||
props : The properties retrieved from the server. They will be freed.
|
||||
@ -2294,7 +2259,6 @@ update_node(dav_node *node, dav_props *props)
|
||||
|| (!is_dir(node) && props->is_dir)) {
|
||||
add_node(node->parent, props);
|
||||
remove_node(node);
|
||||
*flush = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2302,14 +2266,12 @@ update_node(dav_node *node, dav_props *props)
|
||||
free(node->name);
|
||||
node->name = xstrdup(props->name);
|
||||
ret = 1;
|
||||
*flush = 1;
|
||||
}
|
||||
|
||||
if (is_created(node)) {
|
||||
if (!is_open(node) && (props->size > 0)) {
|
||||
add_node(node->parent, props);
|
||||
remove_node(node);
|
||||
*flush = 1;
|
||||
return 1;
|
||||
} else {
|
||||
dav_delete_props(props);
|
||||
@ -2328,11 +2290,9 @@ update_node(dav_node *node, dav_props *props)
|
||||
} else if (is_dirty(node)) {
|
||||
add_node(node->parent, props);
|
||||
remove_node(node);
|
||||
*flush = 1;
|
||||
return 1;
|
||||
} else {
|
||||
delete_cache_file(node);
|
||||
*flush = 1;
|
||||
}
|
||||
} else {
|
||||
node->utime = time(NULL);
|
||||
@ -2348,7 +2308,6 @@ update_node(dav_node *node, dav_props *props)
|
||||
node->smtime = props->mtime;
|
||||
node->utime = 0;
|
||||
delete_cache_file(node);
|
||||
*flush = 1;
|
||||
}
|
||||
if (props->ctime > node->ctime)
|
||||
node->ctime = props->ctime;
|
||||
@ -2365,15 +2324,12 @@ update_node(dav_node *node, dav_props *props)
|
||||
node->mode |= (node->mode & S_IWGRP) ? S_IXGRP : 0;
|
||||
node->mode |= (node->mode & S_IWOTH) ? S_IXOTH : 0;
|
||||
node->mode &= ~file_umask;
|
||||
*flush = 1;
|
||||
} else if (props->is_exec == 0
|
||||
&& (node->mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
|
||||
node->mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
|
||||
*flush = 1;
|
||||
}
|
||||
if (props->size && props->size != node->size) {
|
||||
node->size = props->size;
|
||||
*flush = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2399,7 +2355,6 @@ update_path(dav_node *node, const char *src_path, const char *dst_path)
|
||||
if (!node->path || strstr(node->path, src_path) != node->path) {
|
||||
delete_cache_file(node->parent);
|
||||
node->parent->utime = 0;
|
||||
*flush = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2422,28 +2377,17 @@ exists(const dav_node *node)
|
||||
if (n) {
|
||||
return 1;
|
||||
} else {
|
||||
*flush = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static dav_handle *
|
||||
get_file_handle(dav_node * node, int fd, int accmode, pid_t pid, pid_t pgid)
|
||||
get_file_handle(dav_node * node, int fd)
|
||||
{
|
||||
dav_handle *fh = node->handles;
|
||||
if (fd) {
|
||||
while (fh && fh->fd != fd)
|
||||
fh = fh->next;
|
||||
} else {
|
||||
while (fh && (fh->flags != accmode || fh->pid != pid))
|
||||
fh = fh->next;
|
||||
if (!fh) {
|
||||
fh = node->handles;
|
||||
while (fh && (fh->flags != accmode || fh->pgid != pgid))
|
||||
fh = fh->next;
|
||||
}
|
||||
}
|
||||
while (fh && fh->fd != fd)
|
||||
fh = fh->next;
|
||||
|
||||
return fh;
|
||||
}
|
||||
@ -2627,7 +2571,7 @@ create_dir_cache_file(dav_node *dir)
|
||||
of handles.
|
||||
return value : 0 on success, EIO if the file could not be opend. */
|
||||
static int
|
||||
open_file(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid)
|
||||
open_file(int *fd, dav_node *node, int flags)
|
||||
{
|
||||
*fd = open(node->cache_path, flags, node->mode);
|
||||
if (*fd <= 0)
|
||||
@ -2635,9 +2579,6 @@ open_file(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid)
|
||||
dav_handle *fh = (dav_handle *) xmalloc(sizeof(dav_handle));
|
||||
fh->fd = *fd;
|
||||
fh->flags = O_ACCMODE & flags;
|
||||
fh->pid = pid;
|
||||
fh->pgid = pgid;
|
||||
fh->uid = uid;
|
||||
fh->next = node->handles;
|
||||
node->handles = fh;
|
||||
if ((O_ACCMODE & flags) == O_WRONLY || (O_ACCMODE & flags) == O_RDWR)
|
||||
@ -2683,7 +2624,6 @@ update_cache_file(dav_node *node)
|
||||
|| ret == EPERM || ret == ENOSPC) {
|
||||
delete_cache_file(node->parent);
|
||||
node->parent->utime = 0;
|
||||
*flush = 1;
|
||||
remove_node(node);
|
||||
ret = EIO;
|
||||
}
|
||||
@ -2735,7 +2675,6 @@ update_cache_file(dav_node *node)
|
||||
if (ret == ENOENT) {
|
||||
delete_cache_file(node->parent);
|
||||
node->parent->utime = 0;
|
||||
*flush = 1;
|
||||
remove_node(node);
|
||||
}
|
||||
delete_cache_file(node);
|
||||
|
17
src/cache.h
17
src/cache.h
@ -33,17 +33,12 @@
|
||||
/*============*/
|
||||
|
||||
/* File descriptors for open files are stored within a dav_node in a linked
|
||||
list. As coda does not return the file descriptor when closing a file,
|
||||
this data structure contains additional information to identify the
|
||||
appropriate file descriptor. */
|
||||
list. */
|
||||
typedef struct dav_handle dav_handle;
|
||||
struct dav_handle {
|
||||
dav_handle *next; /* Next in the list. */
|
||||
int fd; /* File descriptor of the open file. */
|
||||
int flags; /* Access mode flags only. */
|
||||
pid_t pid; /* id of requesting process. */
|
||||
pid_t pgid; /* Group id of requesting process. */
|
||||
uid_t uid; /* User id of requesting process. */
|
||||
};
|
||||
|
||||
|
||||
@ -207,11 +202,9 @@ dav_close_cache(int got_sigterm);
|
||||
|
||||
/* Registers the kernel_interface.
|
||||
Sets pointers to the write_dir_entry_fn flush_flag.
|
||||
If blksize is not NULL, the preferred bloksize for IO is asigned.
|
||||
It returns the value of alignment. */
|
||||
size_t
|
||||
dav_register_kernel_interface(dav_write_dir_entry_fn write_fn, int *flush_flag,
|
||||
unsigned int *blksize);
|
||||
dav_register_kernel_interface(dav_write_dir_entry_fn write_fn);
|
||||
|
||||
|
||||
/* Scans the hash table for file nodes to be saved them back on the server,
|
||||
@ -333,8 +326,7 @@ dav_mkdir(dav_node **nodep, dav_node *parent, const char *name, uid_t uid,
|
||||
|
||||
|
||||
/* Opens file or directory node according to flags and returns file descriptor
|
||||
fd. fd, together with pid, pgid and uid, is stored in node for read, write
|
||||
and close operations.
|
||||
fd. fd is stored in node for read, write and close operations.
|
||||
Only the O_ACCESSMOE, O_APPEND and O_TRUNC bits in flags will be honoured.
|
||||
O_CREATE and O_EXCL are not allowed.
|
||||
Permissions:
|
||||
@ -346,8 +338,7 @@ dav_mkdir(dav_node **nodep, dav_node *parent, const char *name, uid_t uid,
|
||||
O_CREATE. It allows dav_open to succeed if when the file mode would not
|
||||
allow this. */
|
||||
int
|
||||
dav_open(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid,
|
||||
int open_create);
|
||||
dav_open(int *fd, dav_node *node, int flags, uid_t uid, int open_create);
|
||||
|
||||
/* Reads size bytes from file descriptor fd, starting at position offset
|
||||
and copies them into buf.
|
||||
|
643
src/coda.h
643
src/coda.h
@ -1,643 +0,0 @@
|
||||
/* This header file was taken from Linux kernel 2.6.18.
|
||||
From the two alternative licences the Carnegie Mellon University
|
||||
specific licence has been chosen.
|
||||
Definitions intended for use by the kernel and not for userspace,
|
||||
old API definitions and other parts unused by davfs2 have been removed.
|
||||
Modifications by Werner Baumann, 2009-04-14. */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Coda: an Experimental Distributed File System
|
||||
Release 4.0
|
||||
|
||||
Copyright (c) 1987-1999 Carnegie Mellon University
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify and distribute this software and its
|
||||
documentation is hereby granted, provided that both the copyright
|
||||
notice and this permission notice appear in all copies of the
|
||||
software, derivative works or modified versions, and any portions
|
||||
thereof, and that both notices appear in supporting documentation, and
|
||||
that credit is given to Carnegie Mellon University in all documents
|
||||
and publicity pertaining to direct or indirect use of this code or its
|
||||
derivatives.
|
||||
|
||||
CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
|
||||
SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
|
||||
FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
|
||||
DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
|
||||
RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
|
||||
ANY DERIVATIVE WORK.
|
||||
|
||||
Carnegie Mellon encourages users of this software to return any
|
||||
improvements or extensions that they make, and to grant Carnegie
|
||||
Mellon the rights to redistribute these changes without encumbrance.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Based on cfs.h from Mach, but revamped for increased simplicity.
|
||||
* Linux modifications by
|
||||
* Peter Braam, Aug 1996
|
||||
*/
|
||||
|
||||
#ifndef _CODA_HEADER_
|
||||
#define _CODA_HEADER_
|
||||
|
||||
#define cdev_t dev_t
|
||||
|
||||
#ifndef __BIT_TYPES_DEFINED__
|
||||
#define __BIT_TYPES_DEFINED__
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char u_int8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short u_int16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int u_int32_t;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Cfs constants
|
||||
*/
|
||||
#define CODA_MAXNAMLEN 255
|
||||
#define CODA_MAXPATHLEN 1024
|
||||
#define CODA_MAXSYMLINK 10
|
||||
|
||||
/* these are Coda's version of O_RDONLY etc combinations
|
||||
* to deal with VFS open modes
|
||||
*/
|
||||
#define C_O_READ 0x001
|
||||
#define C_O_WRITE 0x002
|
||||
#define C_O_TRUNC 0x010
|
||||
#define C_O_EXCL 0x100
|
||||
#define C_O_CREAT 0x200
|
||||
|
||||
/* these are to find mode bits in Venus */
|
||||
#define C_M_READ 00400
|
||||
#define C_M_WRITE 00200
|
||||
|
||||
/* for access Venus will use */
|
||||
#define C_A_C_OK 8 /* Test for writing upon create. */
|
||||
#define C_A_R_OK 4 /* Test for read permission. */
|
||||
#define C_A_W_OK 2 /* Test for write permission. */
|
||||
#define C_A_X_OK 1 /* Test for execute permission. */
|
||||
#define C_A_F_OK 0 /* Test for existence. */
|
||||
|
||||
|
||||
|
||||
#ifndef _VENUS_DIRENT_T_
|
||||
#define _VENUS_DIRENT_T_ 1
|
||||
struct venus_dirent {
|
||||
u_int32_t d_fileno; /* file number of entry */
|
||||
u_int16_t d_reclen; /* length of this record */
|
||||
u_int8_t d_type; /* file type, see below */
|
||||
u_int8_t d_namlen; /* length of string in d_name */
|
||||
char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
|
||||
};
|
||||
#undef DIRSIZ
|
||||
#define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
|
||||
(((dp)->d_namlen+1 + 3) &~ 3))
|
||||
|
||||
/*
|
||||
* File types
|
||||
*/
|
||||
#define CDT_UNKNOWN 0
|
||||
#define CDT_FIFO 1
|
||||
#define CDT_CHR 2
|
||||
#define CDT_DIR 4
|
||||
#define CDT_BLK 6
|
||||
#define CDT_REG 8
|
||||
#define CDT_LNK 10
|
||||
#define CDT_SOCK 12
|
||||
#define CDT_WHT 14
|
||||
|
||||
/*
|
||||
* Convert between stat structure types and directory types.
|
||||
*/
|
||||
#define IFTOCDT(mode) (((mode) & 0170000) >> 12)
|
||||
#define CDTTOIF(dirtype) ((dirtype) << 12)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _VUID_T_
|
||||
#define _VUID_T_
|
||||
typedef u_int32_t vuid_t;
|
||||
typedef u_int32_t vgid_t;
|
||||
#endif /*_VUID_T_ */
|
||||
|
||||
struct CodaFid {
|
||||
u_int32_t opaque[4];
|
||||
};
|
||||
|
||||
#define coda_f2i(fid)\
|
||||
(fid ? (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]) : 0)
|
||||
|
||||
|
||||
#ifndef _VENUS_VATTR_T_
|
||||
#define _VENUS_VATTR_T_
|
||||
/*
|
||||
* Vnode types. VNON means no type.
|
||||
*/
|
||||
enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
|
||||
|
||||
struct coda_vattr {
|
||||
long va_type; /* vnode type (for create) */
|
||||
u_short va_mode; /* files access mode and type */
|
||||
short va_nlink; /* number of references to file */
|
||||
vuid_t va_uid; /* owner user id */
|
||||
vgid_t va_gid; /* owner group id */
|
||||
long va_fileid; /* file id */
|
||||
u_quad_t va_size; /* file size in bytes */
|
||||
long va_blocksize; /* blocksize preferred for i/o */
|
||||
struct timespec va_atime; /* time of last access */
|
||||
struct timespec va_mtime; /* time of last modification */
|
||||
struct timespec va_ctime; /* time file changed */
|
||||
u_long va_gen; /* generation number of file */
|
||||
u_long va_flags; /* flags defined for file */
|
||||
cdev_t va_rdev; /* device special file represents */
|
||||
u_quad_t va_bytes; /* bytes of disk space held by file */
|
||||
u_quad_t va_filerev; /* file modification number */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* structure used by CODA_STATFS for getting cache information from venus */
|
||||
struct coda_statfs {
|
||||
int32_t f_blocks;
|
||||
int32_t f_bfree;
|
||||
int32_t f_bavail;
|
||||
int32_t f_files;
|
||||
int32_t f_ffree;
|
||||
};
|
||||
|
||||
/*
|
||||
* Kernel <--> Venus communications.
|
||||
*/
|
||||
|
||||
#define CODA_ROOT 2
|
||||
#define CODA_OPEN_BY_FD 3
|
||||
#define CODA_OPEN 4
|
||||
#define CODA_CLOSE 5
|
||||
#define CODA_IOCTL 6
|
||||
#define CODA_GETATTR 7
|
||||
#define CODA_SETATTR 8
|
||||
#define CODA_ACCESS 9
|
||||
#define CODA_LOOKUP 10
|
||||
#define CODA_CREATE 11
|
||||
#define CODA_REMOVE 12
|
||||
#define CODA_LINK 13
|
||||
#define CODA_RENAME 14
|
||||
#define CODA_MKDIR 15
|
||||
#define CODA_RMDIR 16
|
||||
#define CODA_SYMLINK 18
|
||||
#define CODA_READLINK 19
|
||||
#define CODA_FSYNC 20
|
||||
#define CODA_VGET 22
|
||||
#define CODA_SIGNAL 23
|
||||
#define CODA_REPLACE 24 /* DOWNCALL */
|
||||
#define CODA_FLUSH 25 /* DOWNCALL */
|
||||
#define CODA_PURGEUSER 26 /* DOWNCALL */
|
||||
#define CODA_ZAPFILE 27 /* DOWNCALL */
|
||||
#define CODA_ZAPDIR 28 /* DOWNCALL */
|
||||
#define CODA_PURGEFID 30 /* DOWNCALL */
|
||||
#define CODA_OPEN_BY_PATH 31
|
||||
#define CODA_RESOLVE 32
|
||||
#define CODA_REINTEGRATE 33
|
||||
#define CODA_STATFS 34
|
||||
#define CODA_STORE 35
|
||||
#define CODA_RELEASE 36
|
||||
#define CODA_NCALLS 37
|
||||
|
||||
#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
|
||||
|
||||
#define VC_MAXDATASIZE 8192
|
||||
#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
|
||||
VC_MAXDATASIZE
|
||||
|
||||
#define CIOC_KERNEL_VERSION _IOWR('c', 10, size_t)
|
||||
|
||||
#define CODA_KERNEL_VERSION 3 /* 128-bit file identifiers */
|
||||
|
||||
|
||||
/*
|
||||
* Venus <-> Coda RPC arguments
|
||||
*/
|
||||
struct coda_in_hdr {
|
||||
u_int32_t opcode;
|
||||
u_int32_t unique; /* Keep multiple outstanding msgs distinct */
|
||||
pid_t pid;
|
||||
pid_t pgid;
|
||||
vuid_t uid;
|
||||
};
|
||||
|
||||
/* Really important that opcode and unique are 1st two fields! */
|
||||
struct coda_out_hdr {
|
||||
u_int32_t opcode;
|
||||
u_int32_t unique;
|
||||
u_int32_t result;
|
||||
};
|
||||
|
||||
/* coda_root: NO_IN */
|
||||
struct coda_root_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid VFid;
|
||||
};
|
||||
|
||||
struct coda_root_in {
|
||||
struct coda_in_hdr in;
|
||||
};
|
||||
|
||||
/* coda_open: */
|
||||
struct coda_open_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_open_out {
|
||||
struct coda_out_hdr oh;
|
||||
cdev_t dev;
|
||||
ino_t inode;
|
||||
};
|
||||
|
||||
|
||||
/* coda_store: */
|
||||
struct coda_store_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_store_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_release: */
|
||||
struct coda_release_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_release_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_close: */
|
||||
struct coda_close_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_close_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_ioctl: */
|
||||
struct coda_ioctl_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int cmd;
|
||||
int len;
|
||||
int rwflag;
|
||||
char *data; /* Place holder for data. */
|
||||
};
|
||||
|
||||
struct coda_ioctl_out {
|
||||
struct coda_out_hdr oh;
|
||||
int len;
|
||||
caddr_t data; /* Place holder for data. */
|
||||
};
|
||||
|
||||
|
||||
/* coda_getattr: */
|
||||
struct coda_getattr_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
};
|
||||
|
||||
struct coda_getattr_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct coda_vattr attr;
|
||||
};
|
||||
|
||||
|
||||
/* coda_setattr: NO_OUT */
|
||||
struct coda_setattr_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
struct coda_vattr attr;
|
||||
};
|
||||
|
||||
struct coda_setattr_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_access: NO_OUT */
|
||||
struct coda_access_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_access_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
|
||||
/* lookup flags */
|
||||
#define CLU_CASE_SENSITIVE 0x01
|
||||
#define CLU_CASE_INSENSITIVE 0x02
|
||||
|
||||
/* coda_lookup: */
|
||||
struct coda_lookup_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int name; /* Place holder for data. */
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_lookup_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid VFid;
|
||||
int vtype;
|
||||
};
|
||||
|
||||
|
||||
/* coda_create: */
|
||||
struct coda_create_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
struct coda_vattr attr;
|
||||
int excl;
|
||||
int mode;
|
||||
int name; /* Place holder for data. */
|
||||
};
|
||||
|
||||
struct coda_create_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid VFid;
|
||||
struct coda_vattr attr;
|
||||
};
|
||||
|
||||
|
||||
/* coda_remove: NO_OUT */
|
||||
struct coda_remove_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int name; /* Place holder for data. */
|
||||
};
|
||||
|
||||
struct coda_remove_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_link: NO_OUT */
|
||||
struct coda_link_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid sourceFid; /* cnode to link *to* */
|
||||
struct CodaFid destFid; /* Directory in which to place link */
|
||||
int tname; /* Place holder for data. */
|
||||
};
|
||||
|
||||
struct coda_link_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
|
||||
/* coda_rename: NO_OUT */
|
||||
struct coda_rename_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid sourceFid;
|
||||
int srcname;
|
||||
struct CodaFid destFid;
|
||||
int destname;
|
||||
};
|
||||
|
||||
struct coda_rename_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_mkdir: */
|
||||
struct coda_mkdir_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
struct coda_vattr attr;
|
||||
int name; /* Place holder for data. */
|
||||
};
|
||||
|
||||
struct coda_mkdir_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid VFid;
|
||||
struct coda_vattr attr;
|
||||
};
|
||||
|
||||
|
||||
/* coda_rmdir: NO_OUT */
|
||||
struct coda_rmdir_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int name; /* Place holder for data. */
|
||||
};
|
||||
|
||||
struct coda_rmdir_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_symlink: NO_OUT */
|
||||
struct coda_symlink_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid; /* Directory to put symlink in */
|
||||
int srcname;
|
||||
struct coda_vattr attr;
|
||||
int tname;
|
||||
};
|
||||
|
||||
struct coda_symlink_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_readlink: */
|
||||
struct coda_readlink_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
};
|
||||
|
||||
struct coda_readlink_out {
|
||||
struct coda_out_hdr oh;
|
||||
int count;
|
||||
caddr_t data; /* Place holder for data. */
|
||||
};
|
||||
|
||||
|
||||
/* coda_fsync: NO_OUT */
|
||||
struct coda_fsync_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
};
|
||||
|
||||
struct coda_fsync_out {
|
||||
struct coda_out_hdr out;
|
||||
};
|
||||
|
||||
/* coda_vget: */
|
||||
struct coda_vget_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
};
|
||||
|
||||
struct coda_vget_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid VFid;
|
||||
int vtype;
|
||||
};
|
||||
|
||||
|
||||
/* CODA_SIGNAL is out-of-band, doesn't need data. */
|
||||
/* CODA_INVALIDATE is a venus->kernel call */
|
||||
/* CODA_FLUSH is a venus->kernel call */
|
||||
|
||||
/* coda_purgeuser: */
|
||||
/* CODA_PURGEUSER is a venus->kernel call */
|
||||
struct coda_purgeuser_out {
|
||||
struct coda_out_hdr oh;
|
||||
vuid_t uid;
|
||||
};
|
||||
|
||||
/* coda_zapfile: */
|
||||
/* CODA_ZAPFILE is a venus->kernel call */
|
||||
struct coda_zapfile_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid CodaFid;
|
||||
};
|
||||
|
||||
/* coda_zapdir: */
|
||||
/* CODA_ZAPDIR is a venus->kernel call */
|
||||
struct coda_zapdir_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid CodaFid;
|
||||
};
|
||||
|
||||
/* coda_purgefid: */
|
||||
/* CODA_PURGEFID is a venus->kernel call */
|
||||
struct coda_purgefid_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid CodaFid;
|
||||
};
|
||||
|
||||
/* coda_replace: */
|
||||
/* CODA_REPLACE is a venus->kernel call */
|
||||
struct coda_replace_out { /* coda_replace is a venus->kernel call */
|
||||
struct coda_out_hdr oh;
|
||||
struct CodaFid NewFid;
|
||||
struct CodaFid OldFid;
|
||||
};
|
||||
|
||||
/* coda_open_by_fd: */
|
||||
struct coda_open_by_fd_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_open_by_fd_out {
|
||||
struct coda_out_hdr oh;
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* coda_open_by_path: */
|
||||
struct coda_open_by_path_in {
|
||||
struct coda_in_hdr ih;
|
||||
struct CodaFid VFid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct coda_open_by_path_out {
|
||||
struct coda_out_hdr oh;
|
||||
int path;
|
||||
};
|
||||
|
||||
/* coda_statfs: NO_IN */
|
||||
struct coda_statfs_in {
|
||||
struct coda_in_hdr in;
|
||||
};
|
||||
|
||||
struct coda_statfs_out {
|
||||
struct coda_out_hdr oh;
|
||||
struct coda_statfs stat;
|
||||
};
|
||||
|
||||
union inputArgs {
|
||||
struct coda_in_hdr ih; /* NB: every struct below begins with an ih */
|
||||
struct coda_open_in coda_open;
|
||||
struct coda_store_in coda_store;
|
||||
struct coda_release_in coda_release;
|
||||
struct coda_close_in coda_close;
|
||||
struct coda_ioctl_in coda_ioctl;
|
||||
struct coda_getattr_in coda_getattr;
|
||||
struct coda_setattr_in coda_setattr;
|
||||
struct coda_access_in coda_access;
|
||||
struct coda_lookup_in coda_lookup;
|
||||
struct coda_create_in coda_create;
|
||||
struct coda_remove_in coda_remove;
|
||||
struct coda_link_in coda_link;
|
||||
struct coda_rename_in coda_rename;
|
||||
struct coda_mkdir_in coda_mkdir;
|
||||
struct coda_rmdir_in coda_rmdir;
|
||||
struct coda_symlink_in coda_symlink;
|
||||
struct coda_readlink_in coda_readlink;
|
||||
struct coda_fsync_in coda_fsync;
|
||||
struct coda_vget_in coda_vget;
|
||||
struct coda_open_by_fd_in coda_open_by_fd;
|
||||
struct coda_open_by_path_in coda_open_by_path;
|
||||
struct coda_statfs_in coda_statfs;
|
||||
};
|
||||
|
||||
union outputArgs {
|
||||
struct coda_out_hdr oh; /* NB: every struct below begins with an oh */
|
||||
struct coda_root_out coda_root;
|
||||
struct coda_open_out coda_open;
|
||||
struct coda_ioctl_out coda_ioctl;
|
||||
struct coda_getattr_out coda_getattr;
|
||||
struct coda_lookup_out coda_lookup;
|
||||
struct coda_create_out coda_create;
|
||||
struct coda_mkdir_out coda_mkdir;
|
||||
struct coda_readlink_out coda_readlink;
|
||||
struct coda_vget_out coda_vget;
|
||||
struct coda_purgeuser_out coda_purgeuser;
|
||||
struct coda_zapfile_out coda_zapfile;
|
||||
struct coda_zapdir_out coda_zapdir;
|
||||
struct coda_purgefid_out coda_purgefid;
|
||||
struct coda_replace_out coda_replace;
|
||||
struct coda_open_by_fd_out coda_open_by_fd;
|
||||
struct coda_open_by_path_out coda_open_by_path;
|
||||
struct coda_statfs_out coda_statfs;
|
||||
};
|
||||
|
||||
union coda_downcalls {
|
||||
/* CODA_INVALIDATE is a venus->kernel call */
|
||||
/* CODA_FLUSH is a venus->kernel call */
|
||||
struct coda_purgeuser_out purgeuser;
|
||||
struct coda_zapfile_out zapfile;
|
||||
struct coda_zapdir_out zapdir;
|
||||
struct coda_purgefid_out purgefid;
|
||||
struct coda_replace_out replace;
|
||||
};
|
||||
|
||||
|
||||
/* Data passed to mount */
|
||||
|
||||
#define CODA_MOUNT_VERSION 1
|
||||
|
||||
struct coda_mount_data {
|
||||
int version;
|
||||
int fd; /* Opened device */
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
824
src/dav_coda.c
824
src/dav_coda.c
@ -1,824 +0,0 @@
|
||||
/* dav_coda.c: interface to the Coda kernel module CODA_KERNEL_VERSION 3.
|
||||
Copyright (C) 2006, 2007, 2008, 2009 Werner Baumann
|
||||
|
||||
This file is part of davfs2.
|
||||
|
||||
davfs2 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
davfs2 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 davfs2; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <ne_ssl.h>
|
||||
|
||||
#include "defaults.h"
|
||||
#include "mount_davfs.h"
|
||||
#include "cache.h"
|
||||
#include "kernel_interface.h"
|
||||
#include "coda.h"
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
#define _(String) gettext(String)
|
||||
#else
|
||||
#define _(String) String
|
||||
#endif
|
||||
|
||||
|
||||
/* Constants */
|
||||
/*===========*/
|
||||
|
||||
/* Size of buffer for communication with the kernel module. */
|
||||
#define BUF_SIZE 2048
|
||||
|
||||
/* This constants are used by davfs2 to fill fields of struct CodaFid that
|
||||
are not used by davfs2, but are expected by coda. */
|
||||
#define DAV_VOL 0x01234567
|
||||
#define DAV_VNODE 0xffffffff
|
||||
|
||||
|
||||
/* Private global variables */
|
||||
/*==========================*/
|
||||
|
||||
/* Buffer used for communication with the kernel module (in and out). */
|
||||
static char *buf;
|
||||
|
||||
/* The preferred blocksize used by the local filesystem for cache files.
|
||||
Used by set_attr(). */
|
||||
static unsigned int blocksize;
|
||||
|
||||
/* Alignment boundary of dav_node in byte.
|
||||
Used to compute file numbers from node pointers. */
|
||||
static size_t alignment;
|
||||
|
||||
/* Send debug messages to syslog if != 0. */
|
||||
int debug;
|
||||
|
||||
|
||||
/* Private function prototypes */
|
||||
/*=============================*/
|
||||
|
||||
/* Functions to handle upcalls fromthe kernel module. */
|
||||
|
||||
static uint32_t
|
||||
coda_access(void);
|
||||
|
||||
static uint32_t
|
||||
coda_close(void);
|
||||
|
||||
static uint32_t
|
||||
coda_create(void);
|
||||
|
||||
static uint32_t
|
||||
coda_getattr(void);
|
||||
|
||||
static uint32_t
|
||||
coda_lookup(void);
|
||||
|
||||
static uint32_t
|
||||
coda_mkdir(void);
|
||||
|
||||
static uint32_t
|
||||
coda_open_by_fd(void);
|
||||
|
||||
static uint32_t
|
||||
coda_root(void);
|
||||
|
||||
static uint32_t
|
||||
coda_setattr(void);
|
||||
|
||||
static uint32_t
|
||||
coda_statfs(void);
|
||||
|
||||
/* Functions that will do a downcall to the kernel module. */
|
||||
|
||||
static void
|
||||
coda_flush(int device);
|
||||
|
||||
/* Auxiliary functions. */
|
||||
|
||||
static off_t
|
||||
write_dir_entry(int fd, off_t off, const dav_node *node, const char *name);
|
||||
|
||||
static void
|
||||
set_attr(struct coda_vattr *attr, const dav_node *node);
|
||||
|
||||
|
||||
/* Public functions */
|
||||
/*==================*/
|
||||
|
||||
void
|
||||
dav_coda_loop(int device, size_t bufsize, time_t idle_time,
|
||||
dav_is_mounted_fn is_mounted, volatile int *keep_on_running,
|
||||
int dbg)
|
||||
{
|
||||
debug = dbg;
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "coda kernel version 3");
|
||||
|
||||
buf = malloc(BUF_SIZE);
|
||||
if (!buf) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR),
|
||||
_("can't allocate message buffer"));
|
||||
return;
|
||||
}
|
||||
static int flush = 0;
|
||||
alignment = dav_register_kernel_interface(&write_dir_entry, &flush,
|
||||
&blocksize);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = idle_time;
|
||||
tv.tv_usec = 0;
|
||||
time_t last_tidy_cache = time(NULL);
|
||||
|
||||
while (*keep_on_running) {
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(device, &fds);
|
||||
int ret = select(device + 1, &fds, NULL, NULL, &tv);
|
||||
|
||||
if (ret > 0) {
|
||||
ssize_t bytes_read = read(device, buf, BUF_SIZE);
|
||||
if (bytes_read <= 0) {
|
||||
if (bytes_read == 0 || errno == EINTR || errno == EAGAIN) {
|
||||
if (time(NULL) < (last_tidy_cache + idle_time)) {
|
||||
tv.tv_sec = last_tidy_cache + idle_time - time(NULL);
|
||||
} else {
|
||||
tv.tv_sec = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (ret == 0) {
|
||||
if (!is_mounted())
|
||||
break;
|
||||
if (dav_tidy_cache() == 0) {
|
||||
tv.tv_sec = idle_time;
|
||||
last_tidy_cache = time(NULL);
|
||||
} else {
|
||||
tv.tv_sec = 0;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
uint32_t len;
|
||||
switch (ih->opcode) {
|
||||
case CODA_ROOT:
|
||||
len = coda_root();
|
||||
break;
|
||||
case CODA_OPEN_BY_FD:
|
||||
len = coda_open_by_fd();
|
||||
break;
|
||||
case CODA_OPEN:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_OPEN:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_CLOSE:
|
||||
len = coda_close();
|
||||
last_tidy_cache = 0;
|
||||
break;
|
||||
case CODA_IOCTL:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_IOCTL:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_GETATTR:
|
||||
len = coda_getattr();
|
||||
break;
|
||||
case CODA_SETATTR:
|
||||
len = coda_setattr();
|
||||
break;
|
||||
case CODA_ACCESS:
|
||||
len = coda_access();
|
||||
break;
|
||||
case CODA_LOOKUP:
|
||||
len = coda_lookup();
|
||||
break;
|
||||
case CODA_CREATE:
|
||||
len = coda_create();
|
||||
break;
|
||||
case CODA_REMOVE: {
|
||||
struct coda_remove_in *in = (struct coda_remove_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_REMOVE:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " p %p, %s", node,
|
||||
buf + in->name);
|
||||
}
|
||||
oh->result = dav_remove(node, buf + in->name, ih->uid);
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break; }
|
||||
case CODA_LINK:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_LINK:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_RENAME: {
|
||||
struct coda_rename_in *in = (struct coda_rename_in *) buf;
|
||||
dav_node *src = *((dav_node **) &(in->sourceFid.opaque[2]));
|
||||
dav_node *dst = *((dav_node **) &(in->destFid.opaque[2]));
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_RENAME:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " sp %p, %s", src,
|
||||
buf + in->srcname);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " dp %p, %s", dst,
|
||||
buf + in->destname);
|
||||
}
|
||||
oh->result = dav_rename(src, buf + in->srcname, dst,
|
||||
buf + in->destname, ih->uid);
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break; }
|
||||
case CODA_MKDIR:
|
||||
len = coda_mkdir();
|
||||
break;
|
||||
case CODA_RMDIR: {
|
||||
struct coda_rmdir_in *in = (struct coda_rmdir_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_RMDIR:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " p %p, %s", node,
|
||||
buf + in->name);
|
||||
}
|
||||
oh->result = dav_rmdir(node, buf + in->name, ih->uid);
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break; }
|
||||
case CODA_SYMLINK:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_SYMLINK:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_READLINK:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_READLINK:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_FSYNC: {
|
||||
struct coda_fsync_in *in = (struct coda_fsync_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_FSYNC:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p", node);
|
||||
}
|
||||
oh->result = dav_sync(node);
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break; }
|
||||
case CODA_VGET:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_VGET:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_OPEN_BY_PATH:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"CODA_OPEN_BY_PATH:");
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
case CODA_STATFS:
|
||||
len = coda_statfs();
|
||||
break;
|
||||
case CODA_STORE: {
|
||||
struct coda_store_in *in = (struct coda_store_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_STORE:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p, f 0x%x",
|
||||
node, in->flags);
|
||||
}
|
||||
oh->result = dav_sync(node);
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break; }
|
||||
case CODA_RELEASE:
|
||||
len = coda_close();
|
||||
last_tidy_cache = 0;
|
||||
break;
|
||||
default:
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"UNKNOWN CODA CALL %u", ih->opcode);
|
||||
oh->result = ENOSYS;
|
||||
len = sizeof(struct coda_out_hdr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "RET: %s",
|
||||
strerror(oh->result));
|
||||
|
||||
ssize_t n = 0;
|
||||
ssize_t w = 0;
|
||||
while (n < len && w >= 0) {
|
||||
w = write(device, buf + n, len - n);
|
||||
n += w;
|
||||
}
|
||||
|
||||
if (time(NULL) < (last_tidy_cache + idle_time)) {
|
||||
tv.tv_sec = last_tidy_cache + idle_time - time(NULL);
|
||||
} else {
|
||||
dav_tidy_cache();
|
||||
tv.tv_sec = idle_time;
|
||||
last_tidy_cache = time(NULL);
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
coda_flush(device);
|
||||
flush = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Private functions */
|
||||
/*===================*/
|
||||
|
||||
/* Functions to handle upcalls fromthe kernel module.
|
||||
The cache module only uses data types from the C-library. For file access,
|
||||
mode and the like it only uses symbolic constants defined in the C-library.
|
||||
So the main porpose of this functions is to translate from kernel specific
|
||||
types and constants to types and constants from the C-library, and back.
|
||||
All of this functions return the amount of data in buf that is to be
|
||||
send to the kernel module. */
|
||||
|
||||
static uint32_t
|
||||
coda_access(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_access_in *in = (struct coda_access_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_ACCESS:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p, f %x",
|
||||
node, in->flags);
|
||||
}
|
||||
|
||||
int how = (in->flags & C_A_R_OK) ? R_OK : 0;
|
||||
how |= (in->flags & C_A_W_OK) ? W_OK : 0;
|
||||
how |= (in->flags & C_A_X_OK) ? X_OK : 0;
|
||||
how |= (in->flags & C_A_F_OK) ? F_OK : 0;
|
||||
|
||||
oh->result = dav_access(node, ih->uid, how);
|
||||
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_close(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_close_in *in = (struct coda_close_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
if (debug) {
|
||||
if (ih->opcode == CODA_CLOSE) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_CLOSE:");
|
||||
} else {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_RELEASE:");
|
||||
}
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p, f %x",
|
||||
node, in->flags);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " pid %i, pgid %i",
|
||||
ih->pid, ih->pgid);
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
if ((in->flags & C_O_READ) && (in->flags & C_O_WRITE)) {
|
||||
flags = O_RDWR;
|
||||
} else if (in->flags & C_O_READ) {
|
||||
flags = O_RDONLY;
|
||||
} else if (in->flags & C_O_WRITE) {
|
||||
flags = O_WRONLY;
|
||||
}
|
||||
|
||||
oh->result = dav_close(node, 0, flags, ih->pid, ih->pgid);
|
||||
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_create(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_create_in *in = (struct coda_create_in *) buf;
|
||||
dav_node *parent = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_create_out *out = (struct coda_create_out *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_CREATE:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " p %p, m %o",
|
||||
parent, in->mode);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " %s", buf + in->name);
|
||||
}
|
||||
|
||||
dav_node *node = NULL;
|
||||
oh->result = dav_create(&node, parent, buf + in->name, ih->uid,
|
||||
in->mode & DAV_A_MASK);
|
||||
|
||||
if (oh->result || !node) {
|
||||
if (!oh->result)
|
||||
oh->result = EIO;
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
out->VFid.opaque[0] = DAV_VOL;
|
||||
out->VFid.opaque[1] = DAV_VNODE;
|
||||
out->VFid.opaque[3] = 0;
|
||||
*((dav_node **) &(out->VFid.opaque[2])) = node;
|
||||
set_attr(&out->attr, node);
|
||||
|
||||
return sizeof(struct coda_create_out);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_getattr(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_getattr_in *in = (struct coda_getattr_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_getattr_out *out = (struct coda_getattr_out *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_GETATTR:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p", node);
|
||||
}
|
||||
|
||||
oh->result = dav_getattr(node, ih->uid);
|
||||
|
||||
if (oh->result)
|
||||
return sizeof(struct coda_out_hdr);
|
||||
|
||||
set_attr(&out->attr, node);
|
||||
|
||||
return sizeof(struct coda_getattr_out);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_lookup(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_lookup_in *in = (struct coda_lookup_in *) buf;
|
||||
dav_node *parent = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_lookup_out *out = (struct coda_lookup_out *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_LOOKUP:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " p %p, %s", parent,
|
||||
buf + in->name);
|
||||
}
|
||||
|
||||
dav_node *node = NULL;
|
||||
oh->result = dav_lookup(&node, parent, buf + in->name, ih->uid);
|
||||
|
||||
if (oh->result || !node) {
|
||||
if (!oh->result)
|
||||
oh->result = EIO;
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
out->VFid.opaque[0] = DAV_VOL;
|
||||
out->VFid.opaque[1] = DAV_VNODE;
|
||||
out->VFid.opaque[3] = 0;
|
||||
*((dav_node **) &(out->VFid.opaque[2])) = node;
|
||||
out->vtype = (node->mode & S_IFDIR) ? CDT_DIR : CDT_REG;
|
||||
|
||||
return sizeof(struct coda_lookup_out);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_mkdir(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_mkdir_in *in = (struct coda_mkdir_in *) buf;
|
||||
dav_node *parent = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_mkdir_out *out = (struct coda_mkdir_out *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_MKDIR:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " p %p, %s", parent,
|
||||
buf + in->name);
|
||||
}
|
||||
|
||||
dav_node *node = NULL;
|
||||
oh->result = dav_mkdir(&node, parent, buf + in->name, ih->uid,
|
||||
in->attr.va_mode & DAV_A_MASK);
|
||||
|
||||
if (oh->result || !node) {
|
||||
if (!oh->result)
|
||||
oh->result = EIO;
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
out->VFid.opaque[0] = DAV_VOL;
|
||||
out->VFid.opaque[1] = DAV_VNODE;
|
||||
out->VFid.opaque[3] = 0;
|
||||
*((dav_node **) &(out->VFid.opaque[2])) = node;
|
||||
set_attr(&out->attr, node);
|
||||
|
||||
return sizeof(struct coda_mkdir_out);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_open_by_fd(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_open_by_fd_in *in = (struct coda_open_by_fd_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_open_by_fd_out *out = (struct coda_open_by_fd_out *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_OPEN_BY_FD:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p, f %x", node,
|
||||
in->flags);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " pid %i, pgid %i",
|
||||
ih->pid, ih->pgid);
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
if ((in->flags & C_O_READ) && (in->flags & C_O_WRITE)) {
|
||||
flags = O_RDWR;
|
||||
} else if (in->flags & C_O_READ) {
|
||||
flags = O_RDONLY;
|
||||
} else if (in->flags & C_O_WRITE) {
|
||||
flags = O_WRONLY;
|
||||
}
|
||||
flags |= (in->flags & C_O_TRUNC) ? O_TRUNC : 0;
|
||||
|
||||
oh->result = dav_open(&out->fd, node, flags, ih->pid, ih->pgid, ih->uid, 0);
|
||||
|
||||
if (oh->result || !out->fd) {
|
||||
if (!oh->result)
|
||||
oh->result = EIO;
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
return sizeof(struct coda_open_by_fd_out);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_root(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_root_out *out = (struct coda_root_out *) buf;
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_ROOT:");
|
||||
|
||||
dav_node *node = NULL;
|
||||
oh->result = dav_root(&node, ih->uid);
|
||||
|
||||
if (oh->result || !node) {
|
||||
if (!oh->result)
|
||||
oh->result = EIO;
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
out->VFid.opaque[0] = DAV_VOL;
|
||||
out->VFid.opaque[1] = DAV_VNODE;
|
||||
out->VFid.opaque[3] = 0;
|
||||
*((dav_node **) &(out->VFid.opaque[2])) = node;
|
||||
|
||||
return sizeof(struct coda_root_out);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_setattr(void)
|
||||
{
|
||||
struct coda_in_hdr *ih = (struct coda_in_hdr *) buf;
|
||||
struct coda_setattr_in *in = (struct coda_setattr_in *) buf;
|
||||
dav_node *node = *((dav_node **) &(in->VFid.opaque[2]));
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_SETATTR:");
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " n %p, m %o", node,
|
||||
in->attr.va_mode);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " uid: %i, gid: %i",
|
||||
in->attr.va_uid, in->attr.va_gid);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " at %li, mt %li",
|
||||
in->attr.va_atime.tv_sec, in->attr.va_mtime.tv_sec);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " ct %li, sz %llu",
|
||||
in->attr.va_ctime.tv_sec, in->attr.va_size);
|
||||
}
|
||||
|
||||
oh->result = dav_setattr(node, ih->uid, in->attr.va_mode != USHRT_MAX,
|
||||
in->attr.va_mode & DAV_A_MASK,
|
||||
in->attr.va_uid != UINT32_MAX, in->attr.va_uid,
|
||||
in->attr.va_gid != UINT32_MAX, in->attr.va_gid,
|
||||
in->attr.va_atime.tv_sec != -1,
|
||||
in->attr.va_atime.tv_sec,
|
||||
in->attr.va_mtime.tv_sec != -1,
|
||||
in->attr.va_mtime.tv_sec,
|
||||
in->attr.va_size != UINT64_MAX,
|
||||
in->attr.va_size);
|
||||
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
coda_statfs(void)
|
||||
{
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
struct coda_statfs_out *out = (struct coda_statfs_out *) buf;
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "CODA_STATFS:");
|
||||
|
||||
dav_stat *st = dav_statfs();
|
||||
if (!st) {
|
||||
oh->result = ENOSYS;
|
||||
return sizeof(struct coda_out_hdr);
|
||||
}
|
||||
|
||||
out->stat.f_blocks = st->blocks;
|
||||
out->stat.f_bfree = st->bfree;
|
||||
out->stat.f_bavail = st->bavail;
|
||||
out->stat.f_files = st->files;
|
||||
out->stat.f_ffree = st->ffree;
|
||||
|
||||
oh->result = 0;
|
||||
return sizeof(struct coda_statfs_out);
|
||||
}
|
||||
|
||||
|
||||
/* Functions that will do a downcall to the kernel module. */
|
||||
|
||||
/* Downcall to inform the kernel that nodes have been added or removed. */
|
||||
static void
|
||||
coda_flush(int device)
|
||||
{
|
||||
struct coda_out_hdr *oh = (struct coda_out_hdr *) buf;
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " CODA_FLUSH:");
|
||||
|
||||
oh->opcode = CODA_FLUSH;
|
||||
oh->unique = 0;
|
||||
oh->result = 0;
|
||||
|
||||
ssize_t n = 0;
|
||||
ssize_t w = 0;
|
||||
while (n < sizeof(struct coda_out_hdr) && w >= 0) {
|
||||
w = write(device, buf + n, sizeof(struct coda_out_hdr) - n);
|
||||
n += w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Auxiliary functions. */
|
||||
|
||||
/* Writes a struct venus_dirent to file with file descriptor fd.
|
||||
fd : An open file descriptor to write to.
|
||||
off : The current file size.
|
||||
name : File name; if NULL, the last, empty entry is written.
|
||||
return value : New size of the file. -1 in case of an error. */
|
||||
static off_t
|
||||
write_dir_entry(int fd, off_t off, const dav_node *node, const char *name)
|
||||
{
|
||||
struct venus_dirent entry;
|
||||
size_t head = offsetof(struct venus_dirent, d_name);
|
||||
|
||||
if (name) {
|
||||
entry.d_fileno = (size_t) node / alignment;
|
||||
entry.d_type = (S_ISDIR(node->mode)) ? CDT_DIR : CDT_REG;
|
||||
entry.d_namlen = (strlen(name) > CODA_MAXNAMLEN)
|
||||
? CODA_MAXNAMLEN : strlen(name);
|
||||
entry.d_reclen = (head + entry.d_namlen +4) & ~3;
|
||||
} else {
|
||||
entry.d_fileno = 0;
|
||||
entry.d_type = 0;
|
||||
entry.d_namlen = 0;
|
||||
entry.d_reclen = (head + 4) & ~3;
|
||||
}
|
||||
|
||||
size_t size = 0;
|
||||
ssize_t ret = 0;
|
||||
while (ret >= 0 && size < head) {
|
||||
ret = write(fd, (char *) &entry + size, head - size);
|
||||
size += ret;
|
||||
}
|
||||
if (size != head)
|
||||
return -1;
|
||||
|
||||
ret = 0;
|
||||
while (ret >= 0 && size < (head + entry.d_namlen)) {
|
||||
ret = write(fd, name + size - head, entry.d_namlen - size + head);
|
||||
size += ret;
|
||||
}
|
||||
if (size != (head + entry.d_namlen))
|
||||
return -1;
|
||||
|
||||
ret = 0;
|
||||
while (ret >= 0 && size < entry.d_reclen) {
|
||||
ret = write(fd, "\0", 1);
|
||||
size += ret;
|
||||
}
|
||||
if (size != entry.d_reclen)
|
||||
return -1;
|
||||
|
||||
return off + entry.d_reclen;
|
||||
}
|
||||
|
||||
|
||||
/* Translates attribute from node to attr.
|
||||
Note: Members va_fileid, v_gen, va_flags, va_rdev and va_filerev have no
|
||||
meaning for davfs. va_fileid is treated like d_fileno in struct venus_dirent,
|
||||
the other are set to zero. The meaning of va_type is not clear at all.
|
||||
Times are only set with 1 second precision, as this is the precision of the
|
||||
last-modified time in HTTP. */
|
||||
static void
|
||||
set_attr(struct coda_vattr *attr, const dav_node *node)
|
||||
{
|
||||
attr->va_type = 0;
|
||||
attr->va_mode = node->mode;
|
||||
if (S_ISDIR(node->mode)) {
|
||||
attr->va_nlink = node->nref;
|
||||
} else {
|
||||
attr->va_nlink = 1;
|
||||
}
|
||||
attr->va_uid = node->uid;
|
||||
attr->va_gid = node->gid;
|
||||
attr->va_fileid = (size_t) node / alignment;
|
||||
attr->va_size = node->size;
|
||||
attr->va_blocksize = blocksize;
|
||||
attr->va_atime.tv_sec = node->atime;
|
||||
attr->va_atime.tv_nsec = 0;
|
||||
attr->va_mtime.tv_sec = node->mtime;
|
||||
attr->va_mtime.tv_nsec = 0;
|
||||
attr->va_ctime.tv_sec = node->ctime;
|
||||
attr->va_ctime.tv_nsec = 0;
|
||||
attr->va_gen = 0;
|
||||
attr->va_flags = 0;
|
||||
attr->va_rdev = 0;
|
||||
attr->va_bytes = node->size;
|
||||
attr->va_filerev = 0;
|
||||
}
|
1137
src/dav_fuse.c
1137
src/dav_fuse.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -22,29 +22,6 @@
|
||||
#define DAV_KERNEL_INTERFACE_H
|
||||
|
||||
|
||||
/* Function type definitions */
|
||||
/*===========================*/
|
||||
|
||||
/* Call back function to be passed to dav_init_kernel_interface(). Will be
|
||||
called to see whether the file system is still mounted.
|
||||
return value : 1 is mounted, 0 is not mounted. */
|
||||
typedef int (*dav_is_mounted_fn)(void);
|
||||
|
||||
|
||||
/* Typedef of the message loop of the specific kernel interfaces. The real
|
||||
function will be returned by dav_init_kernel_interface().
|
||||
device : File descriptor of the open fuse device.
|
||||
buf_size : Size of the buffer for communication with the kernel
|
||||
module.
|
||||
idle_t : Time to wait for upcalls before calling dav_tidy_cache().
|
||||
is_mounted_fn : Call back function to check of still mounted.
|
||||
keep_on_running : Pointer to run flag.
|
||||
dbg : send debug messages to syslog if dbg != 0 */
|
||||
typedef void (*dav_run_msgloop_fn)(int device, size_t bufsize, time_t idle_time,
|
||||
dav_is_mounted_fn is_mounted,
|
||||
volatile int *keep_on_running, int dbg);
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
/*=====================*/
|
||||
|
||||
@ -52,45 +29,18 @@ typedef void (*dav_run_msgloop_fn)(int device, size_t bufsize, time_t idle_time,
|
||||
mounts the file system and updates the interface data (dev,
|
||||
dav_ran_msgloop_fn, mdata, kernel_fs and buf_size).
|
||||
In case of an error it prints an error message and terminates the program.
|
||||
dev : File descriptor of the open device for communication with the
|
||||
kernel file system.
|
||||
msg_loop : The specific message loop function that will process the kernel
|
||||
upcalls.
|
||||
mdata : That mount data that will be passed to the mount function.
|
||||
kernel_fs : Type of the kernel file system to us (fuse or coda). If this
|
||||
does not work, the other file system will be tried. The name
|
||||
of the file system that is really used is returned.
|
||||
If NULL, fuse is tried first.
|
||||
buf_size : Size of the buffer for communication with the kernel file system
|
||||
(fuse only). The size passed to this function is checked against
|
||||
the requirements of the kernel fs and updated if necessary.
|
||||
url : Server url.
|
||||
mpoint : Mount point.
|
||||
mopts : Mount options.
|
||||
owner : The owner of the file system (fuse only).
|
||||
group : Group the file system belongs to (fuse only).
|
||||
mode : Mode of the root node (fuse only).
|
||||
return value : 0: the file system has not yet been mounted
|
||||
1: the file system has been mounted successfully. */
|
||||
int
|
||||
dav_init_kernel_interface(int *dev, dav_run_msgloop_fn *msg_loop, void **mdata,
|
||||
char **kernel_fs, size_t *buf_size, const char *url,
|
||||
const char *mpoint, const dav_args *args);
|
||||
|
||||
|
||||
/* Message loop for coda kernel module CODA_KERNEL_VERSION 3.
|
||||
Parameters see dav_run_msgloop_fn(). */
|
||||
void dav_coda_loop(int device, size_t bufsize, time_t idle_time,
|
||||
dav_is_mounted_fn is_mounted,
|
||||
volatile int *keep_on_running, int dbg);
|
||||
args : arguments. */
|
||||
void
|
||||
dav_init_kernel_interface(const char *url, const char *mpoint,
|
||||
const dav_args *args);
|
||||
|
||||
|
||||
/* Message loop for fuse kernel module with major number 7.
|
||||
Parameters see dav_run_msgloop_fn(). */
|
||||
keep_on_running : Pointer to run flag. */
|
||||
void
|
||||
dav_fuse_loop(int device, size_t bufsize, time_t idle_time,
|
||||
dav_is_mounted_fn is_mounted, volatile int *keep_on_running,
|
||||
int dbg);
|
||||
dav_run_msgloop(volatile int *keep_on_running);
|
||||
|
||||
|
||||
#endif /* DAV_KERNEL_INTERFACE_H */
|
||||
|
@ -102,9 +102,6 @@ static char *url;
|
||||
/* The canonicalized mointpoint. */
|
||||
static char *mpoint;
|
||||
|
||||
/* The type of the kernel file system used. */
|
||||
static char *kernel_fs;
|
||||
|
||||
/* The file that holds information about mounted filesystems
|
||||
(/proc/mounts or /etc/mtab) */
|
||||
static char *mounts;
|
||||
@ -120,6 +117,9 @@ static volatile int keep_on_running = 1;
|
||||
terminate without uploading dirty files. */
|
||||
static volatile int got_sigterm;
|
||||
|
||||
/* Send debug information about the configuration to the log file. */
|
||||
static int debug;
|
||||
|
||||
|
||||
/* Private function prototypes */
|
||||
/*=============================*/
|
||||
@ -144,12 +144,6 @@ check_permissions(dav_args *args);
|
||||
static void
|
||||
gain_privileges(const dav_args *args);
|
||||
|
||||
static int
|
||||
do_mount(dav_args *args, void *mdata);
|
||||
|
||||
static int
|
||||
is_mounted(void);
|
||||
|
||||
static dav_args *
|
||||
parse_commandline(dav_args *args, int argc, char *argv[]);
|
||||
|
||||
@ -274,46 +268,24 @@ main(int argc, char *argv[])
|
||||
|
||||
dav_init_cache(args, mpoint);
|
||||
|
||||
int dev = 0;
|
||||
dav_run_msgloop_fn run_msgloop = NULL;
|
||||
void *mdata = NULL;
|
||||
if (args->kernel_fs)
|
||||
kernel_fs = xstrdup(args->kernel_fs);
|
||||
size_t buf_size = args->buf_size * 1024;
|
||||
gain_privileges(args);
|
||||
int mounted = dav_init_kernel_interface(&dev, &run_msgloop, &mdata,
|
||||
&kernel_fs, &buf_size, url, mpoint,
|
||||
args);
|
||||
dav_init_kernel_interface(url, mpoint, args);
|
||||
release_privileges(args);
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "kernel_fs: %s", kernel_fs);
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Writing mtab entry");
|
||||
write_mtab_entry(args);
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Fork into daemon mode");
|
||||
pid_t childpid = fork();
|
||||
if (childpid > 0) {
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"Parent: parent pid: %i, child pid: %i", getpid(), childpid);
|
||||
if (!mounted) {
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"Parent: mounting filesystem");
|
||||
if (do_mount(args, mdata) != 0) {
|
||||
kill(childpid, SIGTERM);
|
||||
delete_args(args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"Parent: writing mtab entry");
|
||||
write_mtab_entry(args);
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Parent: leaving now");
|
||||
}
|
||||
delete_args(args);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
@ -322,7 +294,7 @@ main(int argc, char *argv[])
|
||||
error(EXIT_FAILURE, errno, _("can't start daemon process"));
|
||||
}
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Set signal handler");
|
||||
struct sigaction action;
|
||||
action.sa_handler = termination_handler;
|
||||
@ -335,7 +307,7 @@ main(int argc, char *argv[])
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Releasing root privileges");
|
||||
gain_privileges(args);
|
||||
ret = setuid(args->uid);
|
||||
@ -345,14 +317,11 @@ main(int argc, char *argv[])
|
||||
kill(getppid(), SIGHUP);
|
||||
}
|
||||
|
||||
time_t idle_time = args->delay_upload;
|
||||
if (!idle_time)
|
||||
idle_time = DAV_DELAY_UPLOAD;
|
||||
int debug = args->debug;
|
||||
delete_args(args);
|
||||
setsid();
|
||||
|
||||
if (!ret) {
|
||||
if (debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Releasing terminal");
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
@ -368,7 +337,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Writing pid file");
|
||||
ret = save_pid();
|
||||
if (ret) {
|
||||
@ -379,31 +348,49 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
if (debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Starting message loop");
|
||||
run_msgloop(dev, buf_size, idle_time, is_mounted, &keep_on_running,
|
||||
debug & DAV_DBG_KERNEL);
|
||||
dav_run_msgloop(&keep_on_running);
|
||||
}
|
||||
|
||||
if (debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Closing");
|
||||
dav_close_cache(got_sigterm);
|
||||
dav_close_webdav();
|
||||
if (is_mounted()) {
|
||||
if (dav_is_mounted()) {
|
||||
char *prog = xasprintf("/bin/umount -il %s", mpoint);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), _("unmounting %s"), mpoint);
|
||||
if (system(prog) != 0)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), _("unmounting failed"));
|
||||
}
|
||||
if (debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Removing %s", pidfile);
|
||||
remove(pidfile);
|
||||
if (debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Done.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dav_is_mounted(void)
|
||||
{
|
||||
int found = 0;
|
||||
FILE *mtab = setmntent(mounts, "r");
|
||||
if (mtab) {
|
||||
struct mntent *mt = getmntent(mtab);
|
||||
while (mt && !found) {
|
||||
if (strcmp(mpoint, mt->mnt_dir) == 0
|
||||
&& strcmp(url, mt->mnt_fsname) == 0)
|
||||
found = 1;
|
||||
mt = getmntent(mtab);
|
||||
}
|
||||
}
|
||||
endmntent(mtab);
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
dav_user_input_hidden(const char *prompt)
|
||||
{
|
||||
@ -451,7 +438,7 @@ change_persona(dav_args *args)
|
||||
args->uid = args->dav_uid;
|
||||
release_privileges(args);
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"changing persona: euid %i, gid %i", geteuid(), getgid());
|
||||
}
|
||||
@ -476,7 +463,7 @@ check_dirs(dav_args *args)
|
||||
} else {
|
||||
mounts = _PATH_MOUNTED;
|
||||
}
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "mounts in: %s", mounts);
|
||||
|
||||
gain_privileges(args);
|
||||
@ -660,7 +647,7 @@ check_double_mounts(dav_args *args)
|
||||
}
|
||||
char *pidf = xasprintf("%s/%s.pid", DAV_SYS_RUN, mp);
|
||||
free(mp);
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "PID file: %s", pidf);
|
||||
|
||||
FILE *file = fopen(pidf, "r");
|
||||
@ -768,7 +755,7 @@ check_permissions(dav_args *args)
|
||||
if (args->fsuid != args->uid)
|
||||
error(EXIT_FAILURE, 0,
|
||||
_("you can't set file owner different from your uid"));
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "uid ok");
|
||||
|
||||
if (args->gid != args->fsgid) {
|
||||
@ -781,7 +768,7 @@ check_permissions(dav_args *args)
|
||||
error(EXIT_FAILURE, 0,
|
||||
_("you must be member of the group of the file system"));
|
||||
}
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "gid ok");
|
||||
|
||||
int i;
|
||||
@ -792,36 +779,12 @@ check_permissions(dav_args *args)
|
||||
if (i == args->ngroups)
|
||||
error(EXIT_FAILURE, 0, _("user %s must be member of group %s"),
|
||||
args->uid_name, args->dav_group);
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
"memeber of group %s", args->dav_group);
|
||||
}
|
||||
|
||||
|
||||
/* Calls the mount()-function to mount the file system.
|
||||
Uses private global variables url and mpoint as device and mount point,
|
||||
kernel_fs as file system type, mopts as mount options and mdata
|
||||
as mount data.
|
||||
return value : 0 on success, -1 if mount() fails. */
|
||||
static int
|
||||
do_mount(dav_args *args, void *mdata)
|
||||
{
|
||||
gain_privileges(args);
|
||||
int ret = mount(url, mpoint, kernel_fs, args->mopts, mdata);
|
||||
release_privileges(args);
|
||||
|
||||
if (ret) {
|
||||
error(0, errno, _("can't mount %s on %s"), url, mpoint);
|
||||
if (errno == ENODEV)
|
||||
error(0, 0, _("kernel does not know file system %s"), kernel_fs);
|
||||
if (errno == EBUSY)
|
||||
error(0, 0, _("mount point is busy"));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Gains super user privileges. If an error occurs it prints an error
|
||||
message and calls exit(EXIT_FAILURE). */
|
||||
static void
|
||||
@ -838,29 +801,6 @@ gain_privileges(const dav_args *args)
|
||||
}
|
||||
|
||||
|
||||
/* Checks wether the file system is mounted.
|
||||
It uses information from the private global variables mounts (mtab-file),
|
||||
url (must be device in the mtab entry) and mpoint (mount point).
|
||||
return value : 0 - no matching entry in the mtab-file (not mounted)
|
||||
1 - matching entry in the mtab-file (mounted) */
|
||||
static int
|
||||
is_mounted(void)
|
||||
{
|
||||
int found = 0;
|
||||
FILE *mtab = setmntent(mounts, "r");
|
||||
if (mtab) {
|
||||
struct mntent *mt = getmntent(mtab);
|
||||
while (mt && !found) {
|
||||
if (strcmp(mpoint, mt->mnt_dir) == 0
|
||||
&& strcmp(url, mt->mnt_fsname) == 0)
|
||||
found = 1;
|
||||
mt = getmntent(mtab);
|
||||
}
|
||||
}
|
||||
endmntent(mtab);
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Parses commandline arguments and options and stores them in args and the
|
||||
private global variables url and mpoint.
|
||||
For arguments and options please see the usage()-funktion.
|
||||
@ -1044,7 +984,11 @@ parse_config(dav_args *args)
|
||||
if (!args->backup_dir)
|
||||
args->backup_dir = xstrdup(DAV_BACKUP_DIR);
|
||||
|
||||
if (args->debug & DAV_DBG_CONFIG)
|
||||
if (!args->delay_upload)
|
||||
args->delay_upload = DAV_DELAY_UPLOAD;
|
||||
|
||||
debug = args->debug & DAV_DBG_CONFIG;
|
||||
if (debug)
|
||||
log_dbg_config(args);
|
||||
}
|
||||
|
||||
@ -1364,8 +1308,6 @@ delete_args(dav_args *args)
|
||||
free(args->conf);
|
||||
if (args->add_mopts)
|
||||
free(args->add_mopts);
|
||||
if (args->kernel_fs)
|
||||
free(args->kernel_fs);
|
||||
if (args->scheme)
|
||||
free(args->scheme);
|
||||
if (args->host)
|
||||
@ -1739,8 +1681,6 @@ log_dbg_config(dav_args *args)
|
||||
" mopts: %#lx", args->mopts);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
" add_mopts: %s", args->add_mopts);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
" kernel_fs: %s", args->kernel_fs);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
" buf_size: %llu KiB", (unsigned long long) args->buf_size);
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
|
||||
@ -2134,10 +2074,6 @@ read_config(dav_args *args, const char * filename, int system)
|
||||
if (args->dav_group)
|
||||
free(args->dav_group);
|
||||
args->dav_group = xstrdup(parmv[1]);
|
||||
} else if (strcmp(parmv[0], "kernel_fs") == 0) {
|
||||
if (args->kernel_fs)
|
||||
free(args->kernel_fs);
|
||||
args->kernel_fs = xstrdup(parmv[1]);
|
||||
} else if (strcmp(parmv[0], "buf_size") == 0) {
|
||||
args->buf_size = arg_to_int(parmv[1], 10, parmv[0]);
|
||||
} else if (strcmp(parmv[0], "trust_ca_cert") == 0
|
||||
|
@ -51,7 +51,6 @@ typedef struct {
|
||||
int netdev; /* Command line */
|
||||
unsigned long int mopts; /* Command line */
|
||||
char *add_mopts;
|
||||
char *kernel_fs; /* User config file, system config file */
|
||||
size_t buf_size; /* User config file, system config file */
|
||||
/* File mode */
|
||||
uid_t fsuid; /* Command line */
|
||||
@ -164,6 +163,15 @@ int
|
||||
main(int argc, char *argv[]);
|
||||
|
||||
|
||||
/* Checks wether the file system is mounted.
|
||||
It uses information from the private global variables mounts (mtab-file),
|
||||
url (must be device in the mtab entry) and mpoint (mount point).
|
||||
return value : 0 - no matching entry in the mtab-file (not mounted)
|
||||
1 - matching entry in the mtab-file (mounted) */
|
||||
int
|
||||
dav_is_mounted(void);
|
||||
|
||||
|
||||
/* Prints prompt to stdout and reads a line from stdin.
|
||||
Echoing the user input to stdout is prohibited.
|
||||
A trailing newline is removed.
|
||||
|
Reference in New Issue
Block a user