diff --git a/ios/RetroArch/RAModuleInfo.m b/ios/RetroArch/RAModuleInfo.m
index 56d0ed2a85..0a7834c74e 100644
--- a/ios/RetroArch/RAModuleInfo.m
+++ b/ios/RetroArch/RAModuleInfo.m
@@ -186,7 +186,7 @@ static NSString* get_data_string(config_file_t* config, const char* name, NSStri
cell.detailTextLabel.text = _sections[indexPath.section][indexPath.row * 2 + 2];
if (indexPath.section == _firmwareSectionIndex)
- cell.backgroundColor = ra_ios_is_file(_sections[indexPath.section][indexPath.row * 2 + 2]) ? [UIColor blueColor] : [UIColor redColor];
+ cell.backgroundColor = path_file_exists(((NSString*)_sections[indexPath.section][indexPath.row * 2 + 2]).UTF8String) ? [UIColor blueColor] : [UIColor redColor];
else
cell.backgroundColor = [UIColor whiteColor];
diff --git a/ios/RetroArch/browser/browser.h b/ios/RetroArch/browser/browser.h
index ec82cc4bc0..2275554e81 100644
--- a/ios/RetroArch/browser/browser.h
+++ b/ios/RetroArch/browser/browser.h
@@ -13,13 +13,7 @@
* If not, see .
*/
-extern BOOL ra_ios_is_directory(NSString* path);
-extern BOOL ra_ios_is_file(NSString* path);
-
-@interface RADirectoryItem : NSObject
-@property (strong) NSString* path;
-@property bool isDirectory;
-@end
+#include "file.h"
@interface RADirectoryList : UITableViewController
+ (id)directoryListAtBrowseRoot;
diff --git a/ios/RetroArch/browser/browser.m b/ios/RetroArch/browser/browser.m
index 46d1daeb9a..0697d28f54 100644
--- a/ios/RetroArch/browser/browser.m
+++ b/ios/RetroArch/browser/browser.m
@@ -16,85 +16,19 @@
#include
#include
#import "browser.h"
-#import "conf/config_file.h"
+#include "conf/config_file.h"
-@implementation RADirectoryItem
-+ (RADirectoryItem*)directoryItemFromPath:(const char*)thePath
-{
- RADirectoryItem* result = [RADirectoryItem new];
- result.path = [NSString stringWithUTF8String:thePath];
-
- struct stat statbuf;
- if (stat(thePath, &statbuf) == 0)
- result.isDirectory = S_ISDIR(statbuf.st_mode);
-
- return result;
-}
+@interface RADirectoryItem : NSObject
+@property (strong) NSString* path;
+@property bool isDirectory;
@end
-
-BOOL ra_ios_is_file(NSString* path)
-{
- return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil];
-}
-
-BOOL ra_ios_is_directory(NSString* path)
-{
- BOOL result = NO;
- [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&result];
- return result;
-}
-
-static NSArray* ra_ios_list_directory(NSString* path)
-{
- NSMutableArray* result = [NSMutableArray arrayWithCapacity:27];
- for (int i = 0; i < 28; i ++)
- {
- [result addObject:[NSMutableArray array]];
- }
-
- // Build list
- char* cpath = malloc([path length] + sizeof(struct dirent));
- sprintf(cpath, "%s/", [path UTF8String]);
- size_t cpath_end = strlen(cpath);
-
- DIR* dir = opendir(cpath);
- if (!dir)
- return result;
-
- for(struct dirent* item = readdir(dir); item; item = readdir(dir))
- {
- if (strncmp(item->d_name, ".", 1) == 0)
- continue;
-
- cpath[cpath_end] = 0;
- strcat(cpath, item->d_name);
-
- RADirectoryItem* value = [RADirectoryItem directoryItemFromPath:cpath];
-
- uint32_t section = isalpha(item->d_name[0]) ? (toupper(item->d_name[0]) - 'A') + 2 : 1;
- section = value.isDirectory ? 0 : section;
- [result[section] addObject:[RADirectoryItem directoryItemFromPath:cpath]];
- }
-
- closedir(dir);
- free(cpath);
-
- // Sort
- for (int i = 0; i < result.count; i ++)
- [result[i] sortUsingComparator:^(RADirectoryItem* left, RADirectoryItem* right)
- {
- return (left.isDirectory != right.isDirectory) ?
- (left.isDirectory ? -1 : 1) :
- ([left.path caseInsensitiveCompare:right.path]);
- }];
-
- return result;
-}
+@implementation RADirectoryItem
+@end
@implementation RADirectoryList
{
- NSArray* _list;
+ NSMutableArray* _list;
}
+ (id)directoryListAtBrowseRoot
@@ -102,7 +36,7 @@ static NSArray* ra_ios_list_directory(NSString* path)
NSString* rootPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSString* ragPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/RetroArchGames"];
- return [RADirectoryList directoryListForPath:ra_ios_is_directory(ragPath) ? ragPath : rootPath];
+ return [RADirectoryList directoryListForPath:path_is_directory(ragPath.UTF8String) ? ragPath : rootPath];
}
+ (id)directoryListForPath:(NSString*)path
@@ -114,17 +48,40 @@ static NSArray* ra_ios_list_directory(NSString* path)
- (id)initWithPath:(NSString*)path
{
self = [super initWithStyle:UITableViewStylePlain];
+ [self setTitle: [path lastPathComponent]];
- if (!ra_ios_is_directory(path))
+ // Need one array per section
+ _list = [NSMutableArray arrayWithCapacity:28];
+ for (int i = 0; i < 28; i ++)
+ [_list addObject:[NSMutableArray array]];
+
+ // List contents
+ struct string_list* contents = dir_list_new(path.UTF8String, 0, true);
+
+ if (contents)
{
- [RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Browsed path is not a directory: %@", path]];
- _list = [NSArray array];
+ dir_list_sort(contents, true);
+
+ for (int i = 0; i < contents->size; i ++)
+ {
+ const char* basename = path_basename(contents->elems[i].data);
+
+ if (basename[0] == '.')
+ continue;
+
+ uint32_t section = isalpha(basename[0]) ? (toupper(basename[0]) - 'A') + 2 : 1;
+ section = contents->elems[i].attr.b ? 0 : section;
+
+ RADirectoryItem* item = RADirectoryItem.new;
+ item.path = [NSString stringWithUTF8String:contents->elems[i].data];
+ item.isDirectory = contents->elems[i].attr.b;
+ [_list[section] addObject:item];
+ }
+
+ dir_list_free(contents);
}
else
- {
- [self setTitle: [path lastPathComponent]];
- _list = ra_ios_list_directory(path);
- }
+ [RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Browsed path is not a directory: %@", path]];
return self;
}
diff --git a/ios/RetroArch/main.m b/ios/RetroArch/main.m
index a4af4450d0..562c57bfbc 100644
--- a/ios/RetroArch/main.m
+++ b/ios/RetroArch/main.m
@@ -24,6 +24,7 @@
#include "rarch_wrapper.h"
#include "general.h"
+#include "file.h"
#include "frontend/menu/rmenu.h"
#import "browser/browser.h"
@@ -252,7 +253,14 @@ static void event_reload_config(void* userdata)
self.system_directory = [NSString stringWithFormat:@"%@/.RetroArch", documentsPath];
self.systemConfigPath = [NSString stringWithFormat:@"%@/.RetroArch/frontend.cfg", documentsPath];
- mkdir([self.system_directory UTF8String], 0755);
+
+ // Build system paths and test permissions
+ if (!path_is_directory(documentsPath.UTF8String) && mkdir(documentsPath.UTF8String, 0755))
+ [RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Failed to create base directory: %@", documentsPath]];
+ else if (!path_is_directory(self.system_directory.UTF8String) && mkdir(self.system_directory.UTF8String, 0755))
+ [RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Failed to create system directory: %@", self.system_directory]];
+ else if (access(self.system_directory.UTF8String, R_OK | W_OK | X_OK))
+ [RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"System directory has incorrect permissions: %@", self.system_directory]];
// Setup window
self.delegate = self;
@@ -344,8 +352,8 @@ static void event_reload_config(void* userdata)
[self pushViewController:RAGameView.get animated:NO];
_isRunning = true;
- const char* const sd = [[RetroArch_iOS get].system_directory UTF8String];
- const char* const cf = (ra_ios_is_file(_module.configPath)) ? [_module.configPath UTF8String] : 0;
+ const char* const sd = RetroArch_iOS.get.system_directory.UTF8String;
+ const char* const cf = (path_file_exists(_module.configPath.UTF8String)) ? [_module.configPath UTF8String] : 0;
const char* const libretro = [_module.path UTF8String];
struct rarch_main_wrap* load_data = malloc(sizeof(struct rarch_main_wrap));