}
TALLOC_FREE(tmp[i].name);
- if (*num_streams - 1 > i) {
- memmove(&tmp[i], &tmp[i+1],
- (*num_streams - i - 1) * sizeof(struct stream_struct));
- }
-
+ ARRAY_DEL_ELEMENT(tmp, i, *num_streams);
*num_streams -= 1;
return true;
}
}
TALLOC_FREE(tmp[i].name);
- if (*num_streams - 1 > i) {
- memmove(&tmp[i], &tmp[i+1],
- (*num_streams - i - 1) * sizeof(struct stream_struct));
- }
-
+ ARRAY_DEL_ELEMENT(tmp, i, *num_streams);
*num_streams -= 1;
return true;
}
stream_name = synthetic_smb_fname(talloc_tos(),
smb_fname->base_name,
AFPINFO_STREAM_NAME,
- NULL, smb_fname->flags);
+ NULL,
+ smb_fname->twrp,
+ smb_fname->flags);
if (stream_name == NULL) {
return false;
}
stream_name = synthetic_smb_fname(talloc_tos(),
smb_fname->base_name,
AFPRESOURCE_STREAM_NAME,
- NULL, 0);
+ NULL,
+ smb_fname->twrp,
+ 0);
if (stream_name == NULL) {
return 0;
}
int rc;
char *list = NULL, *newlist = NULL;
struct fruit_config_data *config;
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
DEBUG(10, ("fruit_connect\n"));
struct fruit_config_data, return -1);
if (config->veto_appledouble) {
- list = lp_veto_files(talloc_tos(), SNUM(handle->conn));
+ list = lp_veto_files(talloc_tos(), lp_sub, SNUM(handle->conn));
if (list) {
if (strstr(list, "/" ADOUBLE_NAME_PREFIX "*/") == NULL) {
DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
- if (!is_ntfs_stream_smb_fname(smb_fname)) {
+ if (!is_named_stream(smb_fname)) {
return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(fsp->fsp_name), fd);
- if (!is_ntfs_stream_smb_fname(fsp->fsp_name)) {
+ if (!is_named_stream(fsp->fsp_name)) {
return SMB_VFS_NEXT_CLOSE(handle, fsp);
}
}
static int fruit_unlink_meta_stream(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname)
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname)
{
- return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ return SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ 0);
}
static int fruit_unlink_meta_netatalk(vfs_handle_struct *handle,
switch (config->meta) {
case FRUIT_META_STREAM:
- rc = fruit_unlink_meta_stream(handle, smb_fname);
+ rc = fruit_unlink_meta_stream(handle,
+ dirfsp,
+ smb_fname);
break;
case FRUIT_META_NETATALK:
}
static int fruit_unlink_rsrc_stream(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- bool force_unlink)
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
{
int ret;
}
}
- ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ ret = SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ 0);
if ((ret != 0) && (errno == ENOENT) && force_unlink) {
ret = 0;
}
}
static int fruit_unlink_rsrc_adouble(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- bool force_unlink)
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
{
int rc;
struct adouble *ad = NULL;
return -1;
}
- rc = SMB_VFS_NEXT_UNLINK(handle, adp_smb_fname);
+ rc = SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ adp_smb_fname,
+ 0);
TALLOC_FREE(adp_smb_fname);
if ((rc != 0) && (errno == ENOENT) && force_unlink) {
rc = 0;
}
static int fruit_unlink_rsrc(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- bool force_unlink)
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
{
struct fruit_config_data *config = NULL;
int rc;
switch (config->rsrc) {
case FRUIT_RSRC_STREAM:
- rc = fruit_unlink_rsrc_stream(handle, smb_fname, force_unlink);
+ rc = fruit_unlink_rsrc_stream(handle,
+ dirfsp,
+ smb_fname,
+ force_unlink);
break;
case FRUIT_RSRC_ADFILE:
- rc = fruit_unlink_rsrc_adouble(handle, smb_fname, force_unlink);
+ rc = fruit_unlink_rsrc_adouble(handle,
+ dirfsp,
+ smb_fname,
+ force_unlink);
break;
case FRUIT_RSRC_XATTR:
return rc;
}
-static int fruit_unlink_internal(vfs_handle_struct *handle,
- struct files_struct *dirfsp,
- const struct smb_filename *smb_fname)
-{
- int rc;
- struct fruit_config_data *config = NULL;
- struct smb_filename *rsrc_smb_fname = NULL;
-
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
-
- if (is_afpinfo_stream(smb_fname->stream_name)) {
- return fruit_unlink_meta(handle,
- dirfsp,
- smb_fname);
- } else if (is_afpresource_stream(smb_fname->stream_name)) {
- return fruit_unlink_rsrc(handle, smb_fname, false);
- } else if (is_ntfs_stream_smb_fname(smb_fname)) {
- return SMB_VFS_NEXT_UNLINKAT(handle,
- dirfsp,
- smb_fname,
- 0);
- } else if (is_adouble_file(smb_fname->base_name)) {
- return SMB_VFS_NEXT_UNLINKAT(handle,
- dirfsp,
- smb_fname,
- 0);
- }
-
- /*
- * A request to delete the base file. Because 0 byte resource
- * fork streams are not listed by fruit_streaminfo,
- * delete_all_streams() can't remove 0 byte resource fork
- * streams, so we have to cleanup this here.
- */
- rsrc_smb_fname = synthetic_smb_fname(talloc_tos(),
- smb_fname->base_name,
- AFPRESOURCE_STREAM_NAME,
- NULL,
- smb_fname->flags);
- if (rsrc_smb_fname == NULL) {
- return -1;
- }
-
- rc = fruit_unlink_rsrc(handle, rsrc_smb_fname, true);
- if ((rc != 0) && (errno != ENOENT)) {
- DBG_ERR("Forced unlink of [%s] failed [%s]\n",
- smb_fname_str_dbg(rsrc_smb_fname), strerror(errno));
- TALLOC_FREE(rsrc_smb_fname);
- return -1;
- }
- TALLOC_FREE(rsrc_smb_fname);
-
- return SMB_VFS_NEXT_UNLINKAT(handle,
- dirfsp,
- smb_fname,
- 0);
-}
-
static int fruit_chmod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode)
return rc;
}
-static int fruit_chown(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname,
- uid_t uid,
- gid_t gid)
+static int fruit_unlinkat(vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ int flags)
{
- int rc = -1;
struct fruit_config_data *config = NULL;
- struct smb_filename *adp_smb_fname = NULL;
-
- rc = SMB_VFS_NEXT_CHOWN(handle, smb_fname, uid, gid);
- if (rc != 0) {
- return rc;
- }
-
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
-
- if (config->rsrc != FRUIT_RSRC_ADFILE) {
- return 0;
- }
-
- if (!VALID_STAT(smb_fname->st)) {
- return 0;
- }
-
- if (!S_ISREG(smb_fname->st.st_ex_mode)) {
- return 0;
- }
-
- rc = adouble_path(talloc_tos(), smb_fname, &adp_smb_fname);
- if (rc != 0) {
- goto done;
- }
+ struct smb_filename *rsrc_smb_fname = NULL;
+ int ret;
- DEBUG(10, ("fruit_chown: %s\n", adp_smb_fname->base_name));
+ SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
- rc = SMB_VFS_NEXT_CHOWN(handle, adp_smb_fname, uid, gid);
- if (errno == ENOENT) {
- rc = 0;
+ if (flags & AT_REMOVEDIR) {
+ return SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ AT_REMOVEDIR);
}
- done:
- TALLOC_FREE(adp_smb_fname);
- return rc;
-}
-
-static int fruit_rmdir_internal(struct vfs_handle_struct *handle,
- struct files_struct *dirfsp,
- const struct smb_filename *smb_fname)
-{
- DIR *dh = NULL;
- struct dirent *de;
- struct fruit_config_data *config;
-
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- if (config->rsrc != FRUIT_RSRC_ADFILE) {
- goto exit_rmdir;
+ if (is_afpinfo_stream(smb_fname->stream_name)) {
+ return fruit_unlink_meta(handle,
+ dirfsp,
+ smb_fname);
+ } else if (is_afpresource_stream(smb_fname->stream_name)) {
+ return fruit_unlink_rsrc(handle,
+ dirfsp,
+ smb_fname,
+ false);
+ } else if (is_named_stream(smb_fname)) {
+ return SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ 0);
+ } else if (is_adouble_file(smb_fname->base_name)) {
+ return SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ 0);
}
/*
- * Due to there is no way to change bDeleteVetoFiles variable
- * from this module, need to clean up ourselves
+ * A request to delete the base file. Because 0 byte resource
+ * fork streams are not listed by fruit_streaminfo,
+ * delete_all_streams() can't remove 0 byte resource fork
+ * streams, so we have to cleanup this here.
*/
-
- dh = SMB_VFS_OPENDIR(handle->conn, smb_fname, NULL, 0);
- if (dh == NULL) {
- goto exit_rmdir;
- }
-
- while ((de = SMB_VFS_READDIR(handle->conn, dh, NULL)) != NULL) {
- struct adouble *ad = NULL;
- char *p = NULL;
- struct smb_filename *ad_smb_fname = NULL;
- int ret;
-
- if (!is_adouble_file(de->d_name)) {
- continue;
- }
-
- p = talloc_asprintf(talloc_tos(), "%s/%s",
- smb_fname->base_name, de->d_name);
- if (p == NULL) {
- DBG_ERR("talloc_asprintf failed\n");
- return -1;
- }
-
- ad_smb_fname = synthetic_smb_fname(talloc_tos(), p,
- NULL, NULL,
- smb_fname->flags);
- TALLOC_FREE(p);
- if (ad_smb_fname == NULL) {
- DBG_ERR("synthetic_smb_fname failed\n");
- return -1;
- }
-
- /*
- * Check whether it's a valid AppleDouble file, if
- * yes, delete it, ignore it otherwise.
- */
- ad = ad_get(talloc_tos(), handle, ad_smb_fname, ADOUBLE_RSRC);
- if (ad == NULL) {
- TALLOC_FREE(ad_smb_fname);
- TALLOC_FREE(p);
- continue;
- }
- TALLOC_FREE(ad);
-
- ret = SMB_VFS_NEXT_UNLINKAT(handle,
- dirfsp,
- ad_smb_fname,
- 0);
- if (ret != 0) {
- DBG_ERR("Deleting [%s] failed\n",
- smb_fname_str_dbg(ad_smb_fname));
- }
- TALLOC_FREE(ad_smb_fname);
+ rsrc_smb_fname = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ AFPRESOURCE_STREAM_NAME,
+ NULL,
+ smb_fname->twrp,
+ smb_fname->flags);
+ if (rsrc_smb_fname == NULL) {
+ return -1;
}
-exit_rmdir:
- if (dh) {
- SMB_VFS_CLOSEDIR(handle->conn, dh);
+ ret = fruit_unlink_rsrc(handle, dirfsp, rsrc_smb_fname, true);
+ if ((ret != 0) && (errno != ENOENT)) {
+ DBG_ERR("Forced unlink of [%s] failed [%s]\n",
+ smb_fname_str_dbg(rsrc_smb_fname), strerror(errno));
+ TALLOC_FREE(rsrc_smb_fname);
+ return -1;
}
- return SMB_VFS_NEXT_RMDIR(handle, smb_fname);
-}
-
-static int fruit_rmdir(struct vfs_handle_struct *handle,
- const struct smb_filename *smb_fname)
-{
- return fruit_rmdir_internal(handle,
- handle->conn->cwd_fsp,
- smb_fname);
-}
-
-static int fruit_unlink(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname)
-{
- return fruit_unlink_internal(handle,
- handle->conn->cwd_fsp,
- smb_fname);
-}
-
-static int fruit_unlinkat(vfs_handle_struct *handle,
- struct files_struct *dirfsp,
- const struct smb_filename *smb_fname,
- int flags)
-{
- int ret;
+ TALLOC_FREE(rsrc_smb_fname);
- SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
- if (flags & AT_REMOVEDIR) {
- ret = fruit_rmdir_internal(handle,
- dirfsp,
- smb_fname);
- } else {
- ret = fruit_unlink_internal(handle,
- dirfsp,
- smb_fname);
- }
- return ret;
+ return SMB_VFS_NEXT_UNLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ 0);
}
static ssize_t fruit_pread_meta_stream(vfs_handle_struct *handle,
DBG_ERR("Removing [%s] after short read [%zd]\n",
fsp_str_dbg(fsp), nread);
- ret = SMB_VFS_NEXT_UNLINK(handle, fsp->fsp_name);
+ ret = SMB_VFS_NEXT_UNLINKAT(handle,
+ fsp->conn->cwd_fsp,
+ fsp->fsp_name,
+ 0);
if (ret != 0) {
DBG_ERR("Removing [%s] failed\n", fsp_str_dbg(fsp));
return -1;
DEBUG(10, ("fruit_stat called for %s\n",
smb_fname_str_dbg(smb_fname)));
- if (!is_ntfs_stream_smb_fname(smb_fname)
- || is_ntfs_default_stream_smb_fname(smb_fname)) {
+ if (!is_named_stream(smb_fname)) {
rc = SMB_VFS_NEXT_STAT(handle, smb_fname);
if (rc == 0) {
update_btime(handle, smb_fname);
DEBUG(10, ("fruit_lstat called for %s\n",
smb_fname_str_dbg(smb_fname)));
- if (!is_ntfs_stream_smb_fname(smb_fname)
- || is_ntfs_default_stream_smb_fname(smb_fname)) {
+ if (!is_named_stream(smb_fname)) {
rc = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
if (rc == 0) {
update_btime(handle, smb_fname);
sname = synthetic_smb_fname(talloc_tos(),
smb_fname->base_name,
AFPINFO_STREAM_NAME,
- NULL, 0);
+ NULL,
+ smb_fname->twrp,
+ 0);
if (sname == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ret = SMB_VFS_NEXT_UNLINK(handle, sname);
+ ret = SMB_VFS_NEXT_UNLINKAT(handle,
+ handle->conn->cwd_fsp,
+ sname,
+ 0);
TALLOC_FREE(sname);
if (ret != 0) {
DBG_ERR("Removing [%s] failed\n", smb_fname_str_dbg(sname));
return -1);
if ((config->meta != FRUIT_META_NETATALK) ||
- null_timespec(ft->create_time))
+ is_omit_timespec(&ft->create_time))
{
return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
}
}
ret = ad_convert(handle,
+ handle->conn->cwd_fsp,
smb_fname,
macos_string_replace_map,
conv_flags);
fsp = *result;
if (global_fruit_config.nego_aapl) {
- if (config->posix_rename && fsp->is_directory) {
+ if (config->posix_rename && fsp->fsp_flags.is_directory) {
/*
* Enable POSIX directory rename behaviour
*/
if (global_fruit_config.nego_aapl &&
create_disposition == FILE_OPEN &&
smb_fname->st.st_ex_size == 0 &&
- is_ntfs_stream_smb_fname(smb_fname) &&
- !(is_ntfs_default_stream_smb_fname(smb_fname)))
+ is_named_stream(smb_fname))
{
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
fio->created = true;
}
- if (is_ntfs_stream_smb_fname(smb_fname)
- || fsp->is_directory) {
+ if (is_named_stream(smb_fname) || fsp->fsp_flags.is_directory) {
return status;
}
conv_flags |= AD_CONV_DELETE;
}
- ret = ad_convert(handle, fname, macos_string_replace_map, conv_flags);
+ ret = ad_convert(handle,
+ handle->conn->cwd_fsp,
+ fname,
+ macos_string_replace_map,
+ conv_flags);
if (ret != 0) {
DBG_ERR("ad_convert() failed\n");
return NT_STATUS_UNSUCCESSFUL;
} else {
status = smbd_calculate_access_mask(
handle->conn,
+ handle->conn->cwd_fsp,
fname,
false,
SEC_FLAG_MAXIMUM_ALLOWED,
state->src_fsp->fsp_name->base_name,
streams[i].name,
NULL,
+ state->src_fsp->fsp_name->twrp,
state->src_fsp->fsp_name->flags);
if (tevent_req_nomem(src_fname_tmp, req)) {
return;
state->dst_fsp->fsp_name->base_name,
streams[i].name,
NULL,
+ state->dst_fsp->fsp_name->twrp,
state->dst_fsp->fsp_name->flags);
if (tevent_req_nomem(dst_fname_tmp, req)) {
TALLOC_FREE(src_fname_tmp);
goto out;
}
- smb_fname = synthetic_smb_fname(talloc_tos(), plist, NULL, NULL, 0);
+ smb_fname = synthetic_smb_fname(talloc_tos(),
+ plist,
+ NULL,
+ NULL,
+ 0,
+ 0);
if (smb_fname == NULL) {
ok = false;
goto out;
};
static bool fruit_get_num_bands(vfs_handle_struct *handle,
- char *bundle,
+ const char *bundle,
size_t *_nbands)
{
char *path = NULL;
struct smb_filename *bands_dir = NULL;
- DIR *d = NULL;
- struct dirent *e = NULL;
+ struct smb_Dir *dir_hnd = NULL;
+ const char *dname = NULL;
+ char *talloced = NULL;
+ long offset = 0;
size_t nbands;
- int ret;
path = talloc_asprintf(talloc_tos(),
"%s/%s/bands",
path,
NULL,
NULL,
+ 0,
0);
TALLOC_FREE(path);
if (bands_dir == NULL) {
return false;
}
- d = SMB_VFS_NEXT_OPENDIR(handle, bands_dir, NULL, 0);
- if (d == NULL) {
+ dir_hnd = OpenDir(talloc_tos(), handle->conn, bands_dir, NULL, 0);
+ if (dir_hnd == NULL) {
TALLOC_FREE(bands_dir);
return false;
}
nbands = 0;
- for (e = SMB_VFS_NEXT_READDIR(handle, d, NULL);
- e != NULL;
- e = SMB_VFS_NEXT_READDIR(handle, d, NULL))
+ while ((dname = ReadDirName(dir_hnd, &offset, NULL, &talloced))
+ != NULL)
{
- if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) {
+ if (ISDOT(dname) || ISDOTDOT(dname)) {
continue;
}
nbands++;
}
-
- ret = SMB_VFS_NEXT_CLOSEDIR(handle, d);
- if (ret != 0) {
- TALLOC_FREE(bands_dir);
- return false;
- }
+ TALLOC_FREE(dir_hnd);
DBG_DEBUG("%zu bands in [%s]\n", nbands, smb_fname_str_dbg(bands_dir));
static bool fruit_tmsize_do_dirent(vfs_handle_struct *handle,
struct fruit_disk_free_state *state,
- struct dirent *e)
+ const char *name)
{
bool ok;
char *p = NULL;
size_t nbands;
off_t tm_size;
- p = strstr(e->d_name, "sparsebundle");
+ p = strstr(name, "sparsebundle");
if (p == NULL) {
return true;
}
return true;
}
- DBG_DEBUG("Processing sparsebundle [%s]\n", e->d_name);
+ DBG_DEBUG("Processing sparsebundle [%s]\n", name);
- ok = fruit_get_bandsize(handle, e->d_name, &bandsize);
+ ok = fruit_get_bandsize(handle, name, &bandsize);
if (!ok) {
/*
* Beware of race conditions: this may be an uninitialized
* Info.plist that a client is just creating. We don't want let
* this to trigger complete failure.
*/
- DBG_ERR("Processing sparsebundle [%s] failed\n", e->d_name);
+ DBG_ERR("Processing sparsebundle [%s] failed\n", name);
return true;
}
- ok = fruit_get_num_bands(handle, e->d_name, &nbands);
+ ok = fruit_get_num_bands(handle, name, &nbands);
if (!ok) {
/*
* Beware of race conditions: this may be a backup sparsebundle
* in an early stage lacking a bands subdirectory. We don't want
* let this to trigger complete failure.
*/
- DBG_ERR("Processing sparsebundle [%s] failed\n", e->d_name);
+ DBG_ERR("Processing sparsebundle [%s] failed\n", name);
return true;
}
+ /*
+ * Arithmetic on 32-bit systems may cause overflow, depending on
+ * size_t precision. First we check its unlikely, then we
+ * force the precision into target off_t, then we check that
+ * the total did not overflow either.
+ */
if (bandsize > SIZE_MAX/nbands) {
- DBG_ERR("tmsize overflow: bandsize [%zu] nbands [%zu]\n",
+ DBG_ERR("tmsize potential overflow: bandsize [%zu] nbands [%zu]\n",
bandsize, nbands);
return false;
}
- tm_size = bandsize * nbands;
+ tm_size = (off_t)bandsize * (off_t)nbands;
if (state->total_size + tm_size < state->total_size) {
- DBG_ERR("tmsize overflow: bandsize [%zu] nbands [%zu]\n",
+ DBG_ERR("tm total size overflow: bandsize [%zu] nbands [%zu]\n",
bandsize, nbands);
return false;
}
state->total_size += tm_size;
DBG_DEBUG("[%s] tm_size [%jd] total_size [%jd]\n",
- e->d_name, (intmax_t)tm_size, (intmax_t)state->total_size);
+ name, (intmax_t)tm_size, (intmax_t)state->total_size);
return true;
}
{
struct fruit_config_data *config = NULL;
struct fruit_disk_free_state state = {0};
- DIR *d = NULL;
- struct dirent *e = NULL;
+ struct smb_Dir *dir_hnd = NULL;
+ const char *dname = NULL;
+ char *talloced = NULL;
+ long offset = 0;
uint64_t dfree;
uint64_t dsize;
- int ret;
bool ok;
SMB_VFS_HANDLE_GET_DATA(handle, config,
_dsize);
}
- d = SMB_VFS_NEXT_OPENDIR(handle, smb_fname, NULL, 0);
- if (d == NULL) {
+ dir_hnd = OpenDir(talloc_tos(), handle->conn, smb_fname, NULL, 0);
+ if (dir_hnd == NULL) {
return UINT64_MAX;
}
- for (e = SMB_VFS_NEXT_READDIR(handle, d, NULL);
- e != NULL;
- e = SMB_VFS_NEXT_READDIR(handle, d, NULL))
+ while ((dname = ReadDirName(dir_hnd, &offset, NULL, &talloced))
+ != NULL)
{
- ok = fruit_tmsize_do_dirent(handle, &state, e);
+ ok = fruit_tmsize_do_dirent(handle, &state, dname);
if (!ok) {
- SMB_VFS_NEXT_CLOSEDIR(handle, d);
+ TALLOC_FREE(talloced);
+ TALLOC_FREE(dir_hnd);
return UINT64_MAX;
}
+ TALLOC_FREE(talloced);
}
- ret = SMB_VFS_NEXT_CLOSEDIR(handle, d);
- if (ret != 0) {
- return UINT64_MAX;
- }
+ TALLOC_FREE(dir_hnd);
dsize = config->time_machine_max_size / 512;
dfree = dsize - (state.total_size / 512);
/* File operations */
.chmod_fn = fruit_chmod,
- .chown_fn = fruit_chown,
- .unlink_fn = fruit_unlink,
.unlinkat_fn = fruit_unlinkat,
.renameat_fn = fruit_renameat,
- .rmdir_fn = fruit_rmdir,
.open_fn = fruit_open,
.close_fn = fruit_close,
.pread_fn = fruit_pread,