1
0
mirror of https://github.com/samba-team/samba.git synced 2025-10-28 03:33:13 +03:00

make vfs recycle use vfs facilities correctly!

WARNING: every vfs module maintainer should look at these changes to understand how to properly write a vfs module in head!!

also make installmodules work correctly when the directory structure is not yet in place.

Simo.
(This used to be commit 6dfa460986)
This commit is contained in:
Simo Sorce
2002-12-09 12:06:15 +00:00
parent 2ad2557d11
commit e6e3b79f74
2 changed files with 149 additions and 24 deletions

View File

@@ -37,7 +37,7 @@ static const char *delimiter = "|"; /* delimiter for options */
typedef struct recycle_bin_struct
{
TALLOC_CTX *ctx;
TALLOC_CTX *mem_ctx;
char *repository; /* name of the recycle bin directory */
BOOL keep_dir_tree; /* keep directory structure of deleted file in recycle bin */
BOOL versions; /* create versions of deleted files with identical name */
@@ -48,6 +48,19 @@ typedef struct recycle_bin_struct
SMB_OFF_T maxsize; /* maximum file size to be saved */
} recycle_bin_struct;
typedef struct recycle_bin_connections {
int conn;
recycle_bin_struct *data;
struct recycle_bin_connections *next;
} recycle_bin_connections;
typedef struct recycle_bin_private_data {
TALLOC_CTX *mem_ctx;
recycle_bin_connections *conns;
} recycle_bin_private_data;
struct smb_vfs_handle_struct *recycle_bin_private_handle;
/* VFS operations */
static struct vfs_ops default_vfs_ops; /* For passthrough operation */
@@ -87,6 +100,8 @@ static BOOL check_bool_param(const char *value)
vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
TALLOC_CTX *mem_ctx = NULL;
DEBUG(10, ("Initializing VFS module recycle\n"));
*vfs_version = SMB_VFS_INTERFACE_VERSION;
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
@@ -98,6 +113,20 @@ vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
DEBUG(0, ("vfs_recycle: Debug class number of 'vfs_recycle': %d\n", vfs_recycle_debug_level));
}
recycle_bin_private_handle = vfs_handle;
if (!(mem_ctx = talloc_init_named("recycle bin data"))) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
return NULL;
}
recycle_bin_private_handle->data = talloc(mem_ctx, sizeof(recycle_bin_private_data));
if (recycle_bin_private_handle->data == NULL) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
return NULL;
}
((recycle_bin_private_data *)(recycle_bin_private_handle->data))->mem_ctx = mem_ctx;
((recycle_bin_private_data *)(recycle_bin_private_handle->data))->conns = NULL;
return recycle_ops;
}
@@ -105,34 +134,68 @@ vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
* VFS finalization function.
*
**/
void vfs_done(connection_struct *conn)
void vfs_done(void)
{
DEBUG(10,("Called for connection %d\n", SNUM(conn)));
recycle_bin_private_data *recdata;
recycle_bin_connections *recconn;
DEBUG(10, ("Unloading/Cleaning VFS module recycle bin\n"));
if (recycle_bin_private_handle)
recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
else {
DEBUG(0, ("Recycle bin not initialized!\n"));
return;
}
if (recdata) {
if (recdata->conns) {
recconn = recdata->conns;
while (recconn) {
talloc_destroy(recconn->data->mem_ctx);
recconn = recconn->next;
}
}
if (recdata->mem_ctx) {
talloc_destroy(recdata->mem_ctx);
}
recdata = NULL;
}
}
static int recycle_connect(struct connection_struct *conn, const char *service, const char *user)
{
TALLOC_CTX *ctx = NULL;
recycle_bin_struct *recbin;
recycle_bin_connections *recconn;
recycle_bin_connections *recconnbase;
recycle_bin_private_data *recdata;
char *servicename;
char *tmp_str;
DEBUG(10, ("Called for service %s (%d) as user %s\n", service, SNUM(conn), user));
if (!(ctx = talloc_init_named("recycle bin"))) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
return 0;
if (recycle_bin_private_handle)
recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
else {
DEBUG(0, ("Recycle bin not initialized!\n"));
return -1;
}
recbin = talloc(ctx,sizeof(recycle_bin_struct));
if ( recbin == NULL) {
if (!(ctx = talloc_init_named("recycle bin connection"))) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
return -1;
}
recbin->ctx = ctx;
recbin = talloc(ctx, sizeof(recycle_bin_struct));
if (recbin == NULL) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
return -1;
}
recbin->mem_ctx = ctx;
/* Set defaults */
recbin->repository = talloc_strdup(ctx, ".recycle");
recbin->repository = talloc_strdup(recbin->mem_ctx, ".recycle");
ALLOC_CHECK(recbin->repository, error);
recbin->keep_dir_tree = False;
recbin->versions = False;
@@ -143,10 +206,10 @@ static int recycle_connect(struct connection_struct *conn, const char *service,
recbin->maxsize = 0;
/* parse configuration options */
servicename = talloc_strdup(recbin->ctx, lp_servicename(SNUM(conn)));
servicename = talloc_strdup(recbin->mem_ctx, lp_servicename(SNUM(conn)));
DEBUG(10, ("servicename = %s\n",servicename));
if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "repository")) != NULL) {
recbin->repository = talloc_sub_conn(ctx, conn, tmp_str);
recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str);
ALLOC_CHECK(recbin->repository, error);
trim_string(recbin->repository, "/", "/");
DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository));
@@ -176,22 +239,36 @@ static int recycle_connect(struct connection_struct *conn, const char *service,
}
}
if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "exclude")) != NULL) {
recbin->exclude = talloc_strdup(ctx, tmp_str);
recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str);
ALLOC_CHECK(recbin->exclude, error);
DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude));
}
if ((tmp_str = lp_parm_string(servicename,"vfs_recycle_bin", "exclude_dir")) != NULL) {
recbin->exclude_dir = talloc_strdup(ctx, tmp_str);
recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str);
ALLOC_CHECK(recbin->exclude_dir, error);
DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir));
}
if ((tmp_str = lp_parm_string(servicename,"vfs_recycle_bin", "noversions")) != NULL) {
recbin->noversions = talloc_strdup(ctx, tmp_str);
recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str);
ALLOC_CHECK(recbin->noversions, error);
DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions));
}
conn->vfs_private = (void *)recbin;
recconn = talloc(recdata->mem_ctx, sizeof(recycle_bin_connections));
if (recconn == NULL) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
goto error;
}
recconn->conn = SNUM(conn);
recconn->data = recbin;
recconn->next = NULL;
if (recdata->conns) {
recconnbase = recdata->conns;
while (recconnbase->next != NULL) recconnbase = recconnbase->next;
recconnbase->next = recconn;
} else {
recdata->conns = recconn;
}
return default_vfs_ops.connect(conn, service, user);
error:
@@ -201,10 +278,35 @@ error:
static void recycle_disconnect(struct connection_struct *conn)
{
recycle_bin_private_data *recdata;
recycle_bin_connections *recconn;
DEBUG(10, ("Disconnecting VFS module recycle bin\n"));
if (conn->vfs_private) {
talloc_destroy(((recycle_bin_struct *)conn->vfs_private)->ctx);
conn->vfs_private = NULL;
if (recycle_bin_private_handle)
recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
else {
DEBUG(0, ("Recycle bin not initialized!\n"));
return;
}
if (recdata) {
if (recdata->conns) {
if (recdata->conns->conn == SNUM(conn)) {
talloc_destroy(recdata->conns->data->mem_ctx);
recdata->conns = recdata->conns->next;
} else {
recconn = recdata->conns;
while (recconn->next) {
if (recconn->next->conn == SNUM(conn)) {
talloc_destroy(recconn->next->data->mem_ctx);
recconn->next = recconn->next->next;
break;
}
recconn = recconn->next;
}
}
}
}
default_vfs_ops.disconnect(conn);
}
@@ -391,6 +493,8 @@ static void recycle_touch(connection_struct *conn, const char *fname)
**/
static int recycle_unlink(connection_struct *conn, const char *inname)
{
recycle_bin_private_data *recdata;
recycle_bin_connections *recconn;
recycle_bin_struct *recbin;
char *file_name = NULL;
char *path_name = NULL;
@@ -398,17 +502,28 @@ static int recycle_unlink(connection_struct *conn, const char *inname)
char *final_name = NULL;
char *base;
int i;
SMB_BIG_UINT dfree, dsize, bsize;
SMB_OFF_T file_size, space_avail;
/* SMB_BIG_UINT dfree, dsize, bsize; */
SMB_OFF_T file_size; /* space_avail; */
BOOL exist;
int rc = -1;
file_name = strdup(inname);
ALLOC_CHECK(file_name, done);
if (conn->vfs_private)
recbin = (recycle_bin_struct *)conn->vfs_private;
else {
recbin = NULL;
if (recycle_bin_private_handle) {
recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
if (recdata) {
if (recdata->conns) {
recconn = recdata->conns;
while (recconn && recconn->conn != SNUM(conn)) recconn = recconn->next;
if (recconn != NULL) {
recbin = recconn->data;
}
}
}
}
if (recbin == NULL) {
DEBUG(0, ("Recycle bin not initialized!\n"));
rc = default_vfs_ops.unlink(conn, file_name);
goto done;