2525#include <string/stdstring.h>
2626#include <net/net_compat.h>
2727#include <vfs/vfs_implementation.h>
28- #include "../configuration.h"
29- #include "../verbosity.h"
30- #include "../../config.def.h"
3128#include "vfs_implementation_smb.h"
3229
3330#define SMB_PREFIX "smb://"
@@ -36,6 +33,7 @@ static struct smb2_context **smb_context_pool = NULL;
3633static int next_context_index = 0 ;
3734static bool smb_initialized = false;
3835static int max_context_configured = 0 ;
36+ static const struct smb_settings * smb_cfg = NULL ;
3937
4038static struct smb2_context * get_smb_context ()
4139{
@@ -54,10 +52,7 @@ static struct smb2_context *get_smb_context()
5452 next_context_index = (next_context_index + 1 ) % max_context_configured ;
5553
5654 if (!smb_context_pool [idx ])
57- {
58- RARCH_ERR ("[SMB] Context slot %d is NULL\n" , idx );
5955 return NULL ;
60- }
6156
6257 return smb_context_pool [idx ];
6358}
@@ -78,10 +73,15 @@ void reset(unsigned num_contexts)
7873 max_context_configured = 0 ;
7974}
8075
76+ bool smb_init_cfg (const struct smb_settings * new_cfg )
77+ {
78+ smb_cfg = new_cfg ;
79+ return true;
80+ }
81+
8182/* Initialize SMB context */
8283static bool smb_init ()
8384{
84- settings_t * settings ;
8585 char server [256 ];
8686 char share [256 ];
8787 char * username = NULL ;
@@ -94,71 +94,54 @@ static bool smb_init()
9494 if (smb_initialized )
9595 return true;
9696
97- RARCH_DBG ("[SMB] Initializing SMB client context\n" );
98-
9997 if (!network_init ())
100- RARCH_ERR ("[SMB]: Network initialization failed" );
101-
102- settings = config_get_ptr ();
103- if (!settings )
104- {
105- RARCH_ERR ("[SMB] Cannot retrieve settings for authentication\n" );
10698 return false;
107- }
10899
109- /* Parse server from settings */
110- if (string_is_empty (settings -> arrays .smb_client_server_address ))
111- {
112- RARCH_ERR ("[SMB] Server address not configured\n" );
100+ if (!smb_cfg || string_is_empty (smb_cfg -> server_address ))
113101 return false;
114- }
115102
116- unsigned max_smb_contexts = settings -> uints . smb_client_num_contexts ;
103+ unsigned max_smb_contexts = smb_cfg -> num_contexts ;
117104 smb_context_pool = calloc (max_smb_contexts , sizeof (struct smb2_context * ));
118105
119106 if (!smb_context_pool )
120- {
121- RARCH_ERR ("[SMB] Failed to allocate context pool\n" );
122107 return false;
123- }
124108
125109 for (i = 0 ; i < max_smb_contexts ; i ++ )
126110 {
127111 struct smb2_context * smb_context = smb2_init_context ();
128112
129113 if (!smb_context )
130114 {
131- RARCH_ERR ("[SMB] Failed to create context %d\n" , i );
132115 smb2_destroy_context (smb_context );
133116 reset (max_context_configured );
134117 return false;
135118 }
136119
137- strlcpy (server , settings -> arrays . smb_client_server_address , sizeof (server ));
120+ strlcpy (server , smb_cfg -> server_address , sizeof (server ));
138121
139122 /* Set credentials */
140- if (!string_is_empty (settings -> arrays . smb_client_username ))
123+ if (!string_is_empty (smb_cfg -> username ))
141124 {
142- username = settings -> arrays . smb_client_username ;
125+ username = ( char * ) smb_cfg -> username ;
143126 smb2_set_user (smb_context , username );
144127 }
145128
146- if (!string_is_empty (settings -> arrays . smb_client_password ))
147- smb2_set_password (smb_context , settings -> arrays . smb_client_password );
129+ if (!string_is_empty (smb_cfg -> password ))
130+ smb2_set_password (smb_context , smb_cfg -> password );
148131
149- if (!string_is_empty (settings -> arrays . smb_client_workgroup ))
150- smb2_set_domain (smb_context , settings -> arrays . smb_client_workgroup );
132+ if (!string_is_empty (smb_cfg -> workgroup ))
133+ smb2_set_domain (smb_context , smb_cfg -> workgroup );
151134
152- if (!string_is_empty (settings -> arrays . smb_client_share ))
153- strlcpy (share , settings -> arrays . smb_client_share , sizeof (share ));
135+ if (!string_is_empty (smb_cfg -> share ))
136+ strlcpy (share , smb_cfg -> share , sizeof (share ));
154137 else
155138 share [0 ] = '\0' ;
156139
157140 /* set timeout */
158- smb2_set_timeout (smb_context , settings -> uints . smb_client_timeout );
141+ smb2_set_timeout (smb_context , smb_cfg -> timeout );
159142
160143 /* SMB2_SEC_ defines missing on system headers but provided with latest libsmb2 */
161- switch (settings -> uints . smb_client_auth_mode )
144+ switch (smb_cfg -> auth_mode )
162145 {
163146 case RETRO_SMB2_SEC_NTLMSSP :
164147 smb2_set_security_mode (smb_context , RETRO_SMB2_SEC_NTLMSSP );
@@ -185,10 +168,7 @@ static bool smb_init()
185168 smb_context = smb2_init_context ();
186169
187170 if (!smb_context )
188- {
189- RARCH_ERR ("[SMB] Failed to create recreate context %d\n" , i );
190171 return false;
191- }
192172
193173 /* if that fails, try SMB2_SEC_KRB5 in fallthrough */
194174 smb2_set_security_mode (smb_context , RETRO_SMB2_SEC_NTLMSSP );
@@ -199,9 +179,6 @@ static bool smb_init()
199179 /* Connect to share */
200180 if ((error_no = smb2_connect_share (smb_context , server , share , username )) < 0 )
201181 {
202- RARCH_ERR ("[SMB] Failed to connect to %s/%s: %s (errno: %d) with context: %d\n" ,
203- server , share , smb2_get_error (smb_context ), error_no , i );
204-
205182 smb2_destroy_context (smb_context );
206183 reset (max_context_configured );
207184 return false;
@@ -212,7 +189,6 @@ static bool smb_init()
212189 }
213190
214191 smb_initialized = true;
215- RARCH_DBG ("[SMB] SMB client pool initialized successfully with %d contexts\n" , max_context_configured + 1 );
216192
217193 return true;
218194}
@@ -235,8 +211,6 @@ void smb_shutdown()
235211 if (!smb_initialized || max_context_configured == 0 )
236212 return ;
237213
238- RARCH_DBG ("[SMB] Shutting down SMB client pool\n" );
239-
240214 for (i = 0 ; i < max_context_configured ; i ++ )
241215 smb_close_context (i );
242216
@@ -246,15 +220,8 @@ void smb_shutdown()
246220/* Build full SMB path from settings */
247221static bool smb_build_path (char * dest , size_t dest_size , const char * relative_path )
248222{
249- settings_t * settings = config_get_ptr ();
250223 char temp_path [PATH_MAX_LENGTH ];
251224 const char * p ;
252-
253- if (!settings )
254- {
255- RARCH_ERR ("[SMB] Cannot retrieve settings\n" );
256- return false;
257- }
258225
259226 /* If already has smb:// prefix, extract just the path component */
260227 if (string_starts_with (relative_path , SMB_PREFIX ))
@@ -277,10 +244,10 @@ static bool smb_build_path(char *dest, size_t dest_size, const char *relative_pa
277244 temp_path [0 ] = '\0' ;
278245
279246 /* Add base folder if specified */
280- if (!string_is_empty (settings -> arrays . smb_client_subdir ))
247+ if (!string_is_empty (smb_cfg -> subdir ))
281248 {
282- strlcpy (temp_path , settings -> arrays . smb_client_subdir , sizeof (temp_path ));
283- if (temp_path [strlen (temp_path ) - 1 ] != '/' )
249+ strlcpy (temp_path , smb_cfg -> subdir , sizeof (temp_path ));
250+ if (temp_path [0 ] != '\0' && temp_path [ strlen (temp_path ) - 1 ] != '/' )
284251 strlcat (temp_path , "/" , sizeof (temp_path ));
285252 }
286253
@@ -293,7 +260,6 @@ static bool smb_build_path(char *dest, size_t dest_size, const char *relative_pa
293260 }
294261
295262 strlcpy (dest , temp_path , dest_size );
296- RARCH_DBG ("[SMB] Built path: %s\n" , dest );
297263
298264 return true;
299265}
@@ -314,31 +280,22 @@ bool retro_vfs_file_open_smb(libretro_vfs_implementation_file *stream,
314280 stream -> smb_ctx = (intptr_t )0 ;
315281
316282 if (!smb_init ())
317- {
318- RARCH_ERR ("[SMB] Failed to initialize SMB context\n" );
319283 return false;
320- }
321284
322285 smb_context = get_smb_context ();
323286 if (!smb_context )
324- {
325- RARCH_ERR ("[SMB] Failed to get SMB context from pool\n" );
326287 return false;
327- }
328288
329289 if (!smb_build_path (full_path , sizeof (full_path ), path ))
330290 return false;
331291
332292 /* Strip leading slash ONLY for non-empty subpaths */
333293 if (full_path [0 ] == '/' && full_path [1 ] != '\0' )
334- strlcpy (full_path , full_path + 1 , sizeof (full_path ));
294+ memmove (full_path , full_path + 1 , strlen (full_path ));
335295
336296 /* Do not treat empty string as a file path */
337297 if (full_path [0 ] == '\0' )
338- {
339- RARCH_ERR ("[SMB] Refusing to open empty file path\n" );
340298 return false;
341- }
342299
343300 /* Convert mode to SMB flags safely */
344301 if (mode & RETRO_VFS_FILE_ACCESS_READ )
@@ -359,16 +316,11 @@ bool retro_vfs_file_open_smb(libretro_vfs_implementation_file *stream,
359316
360317 fh = smb2_open (smb_context , full_path , flags );
361318 if (!fh )
362- {
363- RARCH_ERR ("[SMB] Failed to open '%s': %s\n" ,
364- full_path , smb2_get_error (smb_context ));
365319 return false;
366- }
367320
368321 stream -> smb_fh = (intptr_t )(uintptr_t )fh ;
369322 stream -> smb_ctx = (intptr_t )(uintptr_t )smb_context ;
370323 stream -> scheme = VFS_SCHEME_SMB ; /* ensure SMB dispatch on IO calls */
371- RARCH_DBG ("[SMB] Opened file: %s (fd: %p)\n" , full_path , fh );
372324 return true;
373325}
374326
@@ -386,8 +338,6 @@ int64_t retro_vfs_file_read_smb(libretro_vfs_implementation_file *stream,
386338 return -1 ;
387339
388340 ret = smb2_read (ctx , (struct smb2fh * )(intptr_t )stream -> smb_fh , s , len );
389- if (ret < 0 )
390- RARCH_ERR ("[SMB] Read error: %s\n" , smb2_get_error ((struct smb2_context * )(uintptr_t )stream -> smb_ctx ));
391341
392342 return ret ;
393343}
@@ -406,8 +356,6 @@ int64_t retro_vfs_file_write_smb(libretro_vfs_implementation_file *stream,
406356 return -1 ;
407357
408358 ret = smb2_write (ctx , (struct smb2fh * )(intptr_t )stream -> smb_fh , (void * )s , len );
409- if (ret < 0 )
410- RARCH_ERR ("[SMB] Write error: %s\n" , smb2_get_error ((struct smb2_context * )(uintptr_t )stream -> smb_ctx ));
411359
412360 return ret ;
413361}
@@ -443,10 +391,7 @@ int64_t retro_vfs_file_seek_smb(libretro_vfs_implementation_file *stream,
443391 /* libsmb2 returns status via ret, and the new offset via out param */
444392 ret = smb2_lseek (ctx , fh , offset , whence , & newpos );
445393 if (ret < 0 )
446- {
447- RARCH_ERR ("[SMB] Seek error: %s\n" , smb2_get_error (ctx ));
448394 return -1 ;
449- }
450395
451396 return (int64_t )newpos ;
452397}
@@ -475,10 +420,7 @@ int64_t retro_vfs_file_tell_smb(libretro_vfs_implementation_file *stream)
475420
476421 ret = smb2_lseek (ctx , fh , 0 , SEEK_CUR , & cur );
477422 if (ret < 0 )
478- {
479- RARCH_ERR ("[SMB] Tell error: %s\n" , smb2_get_error (ctx ));
480423 return -1 ;
481- }
482424
483425 return (int64_t )cur ;
484426}
@@ -500,8 +442,6 @@ int retro_vfs_file_close_smb(libretro_vfs_implementation_file *stream)
500442 return -1 ;
501443
502444 ret = smb2_close (ctx , (struct smb2fh * )(intptr_t )stream -> smb_fh );
503- if (ret < 0 )
504- RARCH_WARN ("[SMB] Error closing: %s\n" , smb2_get_error ((struct smb2_context * )(void * )(uintptr_t )stream -> smb_ctx ));
505445
506446 stream -> smb_fh = (intptr_t )-1 ;
507447 stream -> smb_ctx = (intptr_t )0 ;
@@ -527,21 +467,15 @@ smb_dir_handle* retro_vfs_opendir_smb(const char *path, bool include_hidden)
527467 /* If we have a leading slash AND a non-empty remainder, strip it.
528468 * Do NOT convert empty string to "." — root listing worked with "" */
529469 if (full_path [0 ] == '/' && full_path [1 ] != '\0' )
530- strlcpy (full_path , full_path + 1 , sizeof (full_path ));
470+ memmove (full_path , full_path + 1 , strlen (full_path ));
531471
532472 smb_context = get_smb_context ();
533473 if (!smb_context )
534- {
535- RARCH_ERR ("[SMB] retro_vfs_opendir_smb: invalid context\n" );
536474 return NULL ;
537- }
538475
539476 dir = smb2_opendir (smb_context , full_path );
540477 if (!dir )
541- {
542- RARCH_ERR ("[SMB] opendir '%s' failed: %s\n" , full_path , smb2_get_error (smb_context ));
543478 return NULL ;
544- }
545479
546480 handle = (smb_dir_handle * )malloc (sizeof (smb_dir_handle ));
547481 if (!handle )
@@ -565,10 +499,7 @@ struct smbc_dirent* retro_vfs_readdir_smb(smb_dir_handle* dh)
565499 return NULL ;
566500
567501 if (!dh -> ctx || !dh -> dir )
568- {
569- RARCH_ERR ("[SMB] retro_vfs_readdir_smb: invalid handle\n" );
570502 return NULL ;
571- }
572503
573504 ent = smb2_readdir (dh -> ctx , dh -> dir );
574505 if (!ent )
@@ -589,10 +520,7 @@ int retro_vfs_closedir_smb(smb_dir_handle* dh)
589520 return -1 ;
590521
591522 if (!dh -> ctx || !dh -> dir )
592- {
593- RARCH_ERR ("[SMB] retro_vfs_closedir_smb: invalid handle\n" );
594523 return -1 ;
595- }
596524
597525 smb2_closedir (dh -> ctx , dh -> dir );
598526 free (dh );
@@ -617,20 +545,14 @@ int retro_vfs_stat_smb(const char *path, int32_t *size)
617545
618546 /* Strip leading slash safely (preserve NULL terminator) */
619547 if (rel_path [0 ] == '/' && rel_path [1 ] != '\0' )
620- strlcpy (rel_path , rel_path + 1 , sizeof (rel_path ));
548+ memmove (rel_path , rel_path + 1 , strlen (rel_path ));
621549
622550 smb_context = get_smb_context ();
623551 if (!smb_context )
624- {
625- RARCH_ERR ("[SMB] retro_vfs_readdir_smb: invalid context\n" );
626552 return 0 ;
627- }
628553
629554 if (smb2_stat (smb_context , rel_path , & st ) < 0 )
630- {
631- RARCH_ERR ("[SMB] stat '%s' failed: %s\n" , rel_path , smb2_get_error (smb_context ));
632555 return 0 ;
633- }
634556
635557 if (size )
636558 * size = (int32_t )st .smb2_size ;
@@ -659,10 +581,7 @@ int retro_vfs_file_error_smb(libretro_vfs_implementation_file *stream)
659581
660582 err = smb2_get_error (ctx );
661583 if (err && err [0 ] != '\0' )
662- {
663- RARCH_ERR ("[SMB] Last error: %s\n" , err );
664584 return -1 ;
665- }
666585
667586 return 0 ;
668587}
0 commit comments