From: Tim Prouty Date: Fri, 10 Jul 2009 22:35:08 +0000 (-0700) Subject: s3: Separate out a new file: filename_utils.c X-Git-Tag: tevent-0.9.8~710^2~25 X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=841efce8b5e931a7ec910afb7d0d8b6a123c6900;p=samba.git s3: Separate out a new file: filename_utils.c This is to ease the linking pain of everything that links LOCKING_OBJ --- diff --git a/source3/Makefile.in b/source3/Makefile.in index f6396ef1576..e6d0cf00ddd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -667,6 +667,8 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \ NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o +FNAME_UTIL_OBJ = smbd/filename_util.o + VFS_DEFAULT_OBJ = modules/vfs_default.o VFS_AUDIT_OBJ = modules/vfs_audit.o VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o @@ -786,7 +788,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ - $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ + $(NOTIFY_OBJ) $(FNAME_UTIL_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ @@ -828,16 +830,16 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O $(LOCKING_OBJ) $(PASSDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \ - $(PASSCHANGE_OBJ) $(LDB_OBJ) + $(PASSCHANGE_OBJ) $(LDB_OBJ) $(FNAME_UTIL_OBJ) STATUS_OBJ = utils/status.o utils/status_profile.o \ $(LOCKING_OBJ) $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) + $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) \ + $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \ $(PRINTBASE_OBJ) SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ @@ -1033,7 +1035,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIEN LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \ $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBNDR_GEN_OBJ0) + $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ) NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ @@ -1052,7 +1054,7 @@ LOG2PCAP_OBJ = utils/log2pcaphex.o LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBNDR_GEN_OBJ0) + $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ) SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \ diff --git a/source3/include/proto.h b/source3/include/proto.h index cdc58437f00..c26f2a7c3ae 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6307,6 +6307,24 @@ int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst); /* The following definitions come from smbd/filename.c */ +NTSTATUS unix_convert(TALLOC_CTX *ctx, + connection_struct *conn, + const char *orig_path, + struct smb_filename **smb_fname, + uint32_t ucf_flags); +NTSTATUS check_name(connection_struct *conn, const char *name); +int get_real_filename(connection_struct *conn, const char *path, + const char *name, TALLOC_CTX *mem_ctx, + char **found_name); +NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, + connection_struct *conn, + bool dfs_path, + const char *name_in, + struct smb_filename **pp_smb_fname, + char **pp_name); + +/* The following definitions come from smbd/filename_utils.c */ + NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname, char **full_name); NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, @@ -6317,31 +6335,13 @@ NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, const char *fname, const SMB_STRUCT_STAT *psbuf, struct smb_filename **smb_fname_out); -int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf); -int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf); const char *smb_fname_str_dbg(const struct smb_filename *smb_fname); +const char *fsp_str_dbg(const struct files_struct *fsp); NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out); bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); -NTSTATUS unix_convert(TALLOC_CTX *ctx, - connection_struct *conn, - const char *orig_path, - struct smb_filename **smb_fname, - uint32_t ucf_flags); -NTSTATUS check_name(connection_struct *conn, const char *name); -int get_real_filename(connection_struct *conn, const char *path, - const char *name, TALLOC_CTX *mem_ctx, - char **found_name); -NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, - connection_struct *conn, - bool dfs_path, - const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name); /* The following definitions come from smbd/files.c */ @@ -6370,7 +6370,6 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid); NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to); -const char *fsp_str_dbg(const struct files_struct *fsp); NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, const struct smb_filename *smb_fname_in); @@ -7117,6 +7116,10 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf); int vfs_ChDir(connection_struct *conn, const char *path); char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); NTSTATUS check_reduced_name(connection_struct *conn, const char *fname); +int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); +int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); /* The following definitions come from torture/denytest.c */ diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 1eb6ce5065f..c05f0e659fb 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -80,225 +80,6 @@ static NTSTATUS determine_path_error(const char *name, } } -/** - * XXX: This is temporary and there should be no callers of this outside of - * this file once smb_filename is plumbed through all path based operations. - * The one legitimate caller currently is smb_fname_str_dbg(), which this - * could be made static for. - */ -NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname, - char **full_name) -{ - if (smb_fname->stream_name) { - *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, - smb_fname->stream_name); - } else { - *full_name = talloc_strdup(ctx, smb_fname->base_name); - } - - if (!*full_name) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -/** - * There are actually legitimate callers of this such as functions that - * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to - * operate on each stream. - */ -NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, - const char *stream_name, - const SMB_STRUCT_STAT *psbuf, - struct smb_filename **smb_fname_out) -{ - struct smb_filename smb_fname_loc; - - ZERO_STRUCT(smb_fname_loc); - - /* Setup the base_name/stream_name. */ - smb_fname_loc.base_name = CONST_DISCARD(char *, base_name); - smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name); - - /* Copy the psbuf if one was given. */ - if (psbuf) - smb_fname_loc.st = *psbuf; - - /* Let copy_smb_filename() do the heavy lifting. */ - return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out); -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, - const char *fname, - const SMB_STRUCT_STAT *psbuf, - struct smb_filename **smb_fname_out) -{ - NTSTATUS status; - const char *stream_name = NULL; - char *base_name = NULL; - - if (!lp_posix_pathnames()) { - stream_name = strchr_m(fname, ':'); - } - - /* Setup the base_name/stream_name. */ - if (stream_name) { - base_name = talloc_strndup(ctx, fname, - PTR_DIFF(stream_name, fname)); - } else { - base_name = talloc_strdup(ctx, fname); - } - - if (!base_name) { - return NT_STATUS_NO_MEMORY; - } - - status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf, - smb_fname_out); - TALLOC_FREE(base_name); - return status; -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) -{ - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - int ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - ret = SMB_VFS_STAT(conn, smb_fname); - if (ret != -1) { - *psbuf = smb_fname->st; - } - - TALLOC_FREE(smb_fname); - return ret; -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) -{ - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - int ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - ret = SMB_VFS_LSTAT(conn, smb_fname); - if (ret != -1) { - *psbuf = smb_fname->st; - } - - TALLOC_FREE(smb_fname); - return ret; -} - -/** - * Return a string using the debug_ctx() - */ -const char *smb_fname_str_dbg(const struct smb_filename *smb_fname) -{ - char *fname = NULL; - NTSTATUS status; - - if (smb_fname == NULL) { - return ""; - } - status = get_full_smb_filename(debug_ctx(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return ""; - } - return fname; -} - -NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, - const struct smb_filename *smb_fname_in, - struct smb_filename **smb_fname_out) -{ - - *smb_fname_out = talloc_zero(ctx, struct smb_filename); - if (*smb_fname_out == NULL) { - return NT_STATUS_NO_MEMORY; - } - - if (smb_fname_in->base_name) { - (*smb_fname_out)->base_name = - talloc_strdup(*smb_fname_out, smb_fname_in->base_name); - if (!(*smb_fname_out)->base_name) - goto no_mem_err; - } - - if (smb_fname_in->stream_name) { - (*smb_fname_out)->stream_name = - talloc_strdup(*smb_fname_out, smb_fname_in->stream_name); - if (!(*smb_fname_out)->stream_name) - goto no_mem_err; - } - - if (smb_fname_in->original_lcomp) { - (*smb_fname_out)->original_lcomp = - talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp); - if (!(*smb_fname_out)->original_lcomp) - goto no_mem_err; - } - - (*smb_fname_out)->st = smb_fname_in->st; - return NT_STATUS_OK; - - no_mem_err: - TALLOC_FREE(*smb_fname_out); - return NT_STATUS_NO_MEMORY; -} - -/**************************************************************************** - Simple check to determine if the filename is a stream. - ***************************************************************************/ -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (lp_posix_pathnames()) { - return false; - } - - return smb_fname->stream_name; -} - -/**************************************************************************** - Returns true if the filename's stream == "::$DATA" - ***************************************************************************/ -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (!is_ntfs_stream_smb_fname(smb_fname)) { - return false; - } - - return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; -} - /**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format changes, diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c new file mode 100644 index 00000000000..1a7af714de0 --- /dev/null +++ b/source3/smbd/filename_util.c @@ -0,0 +1,194 @@ +/* + Unix SMB/CIFS implementation. + Filename utility functions. + Copyright (C) Tim Prouty 2009 + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see . +*/ +#include "includes.h" + +/** + * XXX: This is temporary and there should be no callers of this outside of + * this file once smb_filename is plumbed through all path based operations. + * The one legitimate caller currently is smb_fname_str_dbg(), which this + * could be made static for. + */ +NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, + const struct smb_filename *smb_fname, + char **full_name) +{ + if (smb_fname->stream_name) { + *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, + smb_fname->stream_name); + } else { + *full_name = talloc_strdup(ctx, smb_fname->base_name); + } + + if (!*full_name) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/** + * There are actually legitimate callers of this such as functions that + * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to + * operate on each stream. + */ +NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, + const char *stream_name, + const SMB_STRUCT_STAT *psbuf, + struct smb_filename **smb_fname_out) +{ + struct smb_filename smb_fname_loc; + + ZERO_STRUCT(smb_fname_loc); + + /* Setup the base_name/stream_name. */ + smb_fname_loc.base_name = CONST_DISCARD(char *, base_name); + smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name); + + /* Copy the psbuf if one was given. */ + if (psbuf) + smb_fname_loc.st = *psbuf; + + /* Let copy_smb_filename() do the heavy lifting. */ + return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out); +} + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, + const char *fname, + const SMB_STRUCT_STAT *psbuf, + struct smb_filename **smb_fname_out) +{ + NTSTATUS status; + const char *stream_name = NULL; + char *base_name = NULL; + + if (!lp_posix_pathnames()) { + stream_name = strchr_m(fname, ':'); + } + + /* Setup the base_name/stream_name. */ + if (stream_name) { + base_name = talloc_strndup(ctx, fname, + PTR_DIFF(stream_name, fname)); + } else { + base_name = talloc_strdup(ctx, fname); + } + + if (!base_name) { + return NT_STATUS_NO_MEMORY; + } + + status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf, + smb_fname_out); + TALLOC_FREE(base_name); + return status; +} + +/** + * Return a string using the debug_ctx() + */ +const char *smb_fname_str_dbg(const struct smb_filename *smb_fname) +{ + char *fname = NULL; + NTSTATUS status; + + if (smb_fname == NULL) { + return ""; + } + status = get_full_smb_filename(debug_ctx(), smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return ""; + } + return fname; +} + +/** + * Return a debug string using the debug_ctx(). This can only be called from + * DEBUG() macros due to the debut_ctx(). + */ +const char *fsp_str_dbg(const struct files_struct *fsp) +{ + return smb_fname_str_dbg(fsp->fsp_name); +} + +NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, + const struct smb_filename *smb_fname_in, + struct smb_filename **smb_fname_out) +{ + + *smb_fname_out = talloc_zero(ctx, struct smb_filename); + if (*smb_fname_out == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (smb_fname_in->base_name) { + (*smb_fname_out)->base_name = + talloc_strdup(*smb_fname_out, smb_fname_in->base_name); + if (!(*smb_fname_out)->base_name) + goto no_mem_err; + } + + if (smb_fname_in->stream_name) { + (*smb_fname_out)->stream_name = + talloc_strdup(*smb_fname_out, smb_fname_in->stream_name); + if (!(*smb_fname_out)->stream_name) + goto no_mem_err; + } + + if (smb_fname_in->original_lcomp) { + (*smb_fname_out)->original_lcomp = + talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp); + if (!(*smb_fname_out)->original_lcomp) + goto no_mem_err; + } + + (*smb_fname_out)->st = smb_fname_in->st; + return NT_STATUS_OK; + + no_mem_err: + TALLOC_FREE(*smb_fname_out); + return NT_STATUS_NO_MEMORY; +} + +/**************************************************************************** + Simple check to determine if the filename is a stream. + ***************************************************************************/ +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (lp_posix_pathnames()) { + return false; + } + + return smb_fname->stream_name; +} + +/**************************************************************************** + Returns true if the filename's stream == "::$DATA" + ***************************************************************************/ +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return false; + } + + return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; +} diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 8bd914bf0df..a170f774fe6 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -592,15 +592,6 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, return fsp_set_smb_fname(to, from->fsp_name); } -/** - * Return a debug string using the debug_ctx(). This can only be called from - * DEBUG() macros due to the debut_ctx(). - */ -const char *fsp_str_dbg(const struct files_struct *fsp) -{ - return smb_fname_str_dbg(fsp->fsp_name); -} - /** * The only way that the fsp->fsp_name field should ever be set. */ diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index a2e3ec504c2..55495183bd8 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -990,3 +990,58 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) } return NT_STATUS_OK; } + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + int ret; + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_STAT(conn, smb_fname); + if (ret != -1) { + *psbuf = smb_fname->st; + } + + TALLOC_FREE(smb_fname); + return ret; +} + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + int ret; + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_LSTAT(conn, smb_fname); + if (ret != -1) { + *psbuf = smb_fname->st; + } + + TALLOC_FREE(smb_fname); + return ret; +} +