* AppleTalk VFS module for Samba-3.x
*
* Copyright (C) Alexei Kotovich, 2002
+ * Copyright (C) Stefan (metze) Metzmacher, 2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
#define APPLEDOUBLE ".AppleDouble"
#define ADOUBLEMODE 0777
static int atalk_unlink_file(const char *path);
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *atalk_handle;
-
static int atalk_get_path_ptr(char *path)
{
int i = 0;
}
}
- if (!(new_list = calloc(1,
- (count == 0 ? 1 : count + 1) * sizeof(name_compare_entry))))
+ if (!(new_list = SMB_CALLOC_ARRAY(name_compare_entry, (count == 0 ? 1 : count + 1))))
return;
for (i = 0; i < count; i ++) {
- new_list[i].name = strdup(cur_list[i].name);
+ new_list[i].name = SMB_STRDUP(cur_list[i].name);
new_list[i].is_wild = cur_list[i].is_wild;
}
- new_list[i].name = strdup(APPLEDOUBLE);
+ new_list[i].name = SMB_STRDUP(APPLEDOUBLE);
new_list[i].is_wild = False;
free_namearray(*list);
static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
{
char *dpath;
- struct dirent *dent = 0;
- DIR *dir;
+ SMB_STRUCT_DIRENT *dent = 0;
+ SMB_STRUCT_DIR *dir;
if (!path) return;
- dir = opendir(path);
+ dir = sys_opendir(path);
if (!dir) return;
- while (NULL != (dent = readdir(dir))) {
+ while (NULL != (dent = sys_readdir(dir))) {
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
atalk_unlink_file(dpath);
}
- closedir(dir);
+ sys_closedir(dir);
}
/* Disk operations */
/* Directory operations */
-DIR *atalk_opendir(struct connection_struct *conn, const char *fname)
+static SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
- DIR *ret = 0;
-
- ret = default_vfs_ops.opendir(conn, fname);
+ SMB_STRUCT_DIR *ret = 0;
+
+ ret = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
/*
* when we try to perform delete operation upon file which has fork
* list then it would be nice to add one.
*/
- atalk_add_to_list(&conn->hide_list);
- atalk_add_to_list(&conn->veto_list);
+ atalk_add_to_list(&handle->conn->hide_list);
+ atalk_add_to_list(&handle->conn->veto_list);
return ret;
}
-static int atalk_rmdir(struct connection_struct *conn, const char *path)
+static int atalk_rmdir(struct vfs_handle_struct *handle, const char *path)
{
BOOL add = False;
TALLOC_CTX *ctx = 0;
char *dpath;
- if (!conn || !conn->origpath || !path) goto exit_rmdir;
+ if (!handle->conn->origpath || !path) goto exit_rmdir;
/* due to there is no way to change bDeleteVetoFiles variable
* from this module, gotta use talloc stuff..
goto exit_rmdir;
if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
- conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
+ handle->conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
goto exit_rmdir;
atalk_rrmdir(ctx, dpath);
exit_rmdir:
talloc_destroy(ctx);
- return default_vfs_ops.rmdir(conn, path);
+ return SMB_VFS_NEXT_RMDIR(handle, path);
}
/* File operations */
-static int atalk_rename(struct connection_struct *conn, const char *old, const char *new)
+static int atalk_rename(struct vfs_handle_struct *handle, const char *oldname, const char *newname)
{
int ret = 0;
char *adbl_path = 0;
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.rename(conn, old, new);
+ ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
- if (!conn || !old) return ret;
+ if (!oldname) return ret;
if (!(ctx = talloc_init("rename_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, old, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, oldname, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
return ret;
}
-static int atalk_unlink(struct connection_struct *conn, const char *path)
+static int atalk_unlink(struct vfs_handle_struct *handle, const char *path)
{
int ret = 0, i;
char *adbl_path = 0;
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.unlink(conn, path);
+ ret = SMB_VFS_NEXT_UNLINK(handle, path);
- if (!conn || !path) return ret;
+ if (!path) return ret;
/* no .AppleDouble sync if veto or hide list is empty,
* otherwise "Cannot find the specified file" error will be caused
*/
- if (!conn->veto_list) return ret;
- if (!conn->hide_list) return ret;
+ if (!handle->conn->veto_list) return ret;
+ if (!handle->conn->hide_list) return ret;
- for (i = 0; conn->veto_list[i].name; i ++) {
- if (strstr(conn->veto_list[i].name, APPLEDOUBLE))
+ for (i = 0; handle->conn->veto_list[i].name; i ++) {
+ if (strstr(handle->conn->veto_list[i].name, APPLEDOUBLE))
break;
}
- if (!conn->veto_list[i].name) {
- for (i = 0; conn->hide_list[i].name; i ++) {
- if (strstr(conn->hide_list[i].name, APPLEDOUBLE))
+ if (!handle->conn->veto_list[i].name) {
+ for (i = 0; handle->conn->hide_list[i].name; i ++) {
+ if (strstr(handle->conn->hide_list[i].name, APPLEDOUBLE))
break;
else {
DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
if (!(ctx = talloc_init("unlink_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
return ret;
}
-static int atalk_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+static int atalk_chmod(struct vfs_handle_struct *handle, const char *path, mode_t mode)
{
int ret = 0;
char *adbl_path = 0;
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.chmod(conn, path, mode);
+ ret = SMB_VFS_NEXT_CHMOD(handle, path, mode);
- if (!conn || !path) return ret;
+ if (!path) return ret;
if (!(ctx = talloc_init("chmod_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
return ret;
}
-static int atalk_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+static int atalk_chown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
{
int ret = 0;
char *adbl_path = 0;
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = default_vfs_ops.chown(conn, path, uid, gid);
+ ret = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid);
- if (!conn || !path) return ret;
+ if (!path) return ret;
if (!(ctx = talloc_init("chown_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
/* Directory operations */
- {atalk_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
/* File operations */
- {atalk_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(atalk_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
/* Finish VFS operations definition */
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- atalk_handle = vfs_handle;
-
- DEBUG(3, ("ATALK: vfs module loaded\n"));
- return atalk_ops;
-}
-
-/* VFS finalization function. */
-void vfs_done(connection_struct *conn)
+NTSTATUS vfs_netatalk_init(void);
+NTSTATUS vfs_netatalk_init(void)
{
- DEBUG(3, ("ATALK: vfs module unloaded\n"));
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", atalk_ops);
}