Skip to content

Commit b8304e3

Browse files
committed
smb: libretro-common and apple related fixes
1 parent 3f5a03d commit b8304e3

File tree

4 files changed

+61
-108
lines changed

4 files changed

+61
-108
lines changed

intl/msg_hash_us.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17232,7 +17232,7 @@ MSG_HASH(
1723217232
)
1723317233
MSG_HASH(
1723417234
MENU_ENUM_SUBLABEL_SMB_CLIENT_ENABLE,
17235-
"Enable SMB network share access. Ethernet is strongly recommended over Wi-Fi for a more reliable connection."
17235+
"Enable SMB network share access. Ethernet is strongly recommended over Wi-Fi for a more reliable connection. Note: changing these settings requires a restart of RetroArch."
1723617236
)
1723717237
MSG_HASH(
1723817238
MENU_ENUM_LABEL_VALUE_SMB_CLIENT_SERVER,

libretro-common/vfs/vfs_implementation_smb.c

Lines changed: 26 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
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;
3633
static int next_context_index = 0;
3734
static bool smb_initialized = false;
3835
static int max_context_configured = 0;
36+
static const struct smb_settings *smb_cfg = NULL;
3937

4038
static 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 */
8283
static 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 */
247221
static 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

Comments
 (0)