static char *getScoreDir(char *level_subdir)
{
static char *score_dir = NULL;
- char *data_dir = getCommonDataDir();
+ static char *score_level_dir = NULL;
char *score_subdir = SCORES_DIRECTORY;
- checked_free(score_dir);
+ if (score_dir == NULL)
+ {
+ if (program.global_scores)
+ score_dir = getPath2(getCommonDataDir(), score_subdir);
+ else
+ score_dir = getPath2(getUserGameDataDir(), score_subdir);
+ }
if (level_subdir != NULL)
- score_dir = getPath3(data_dir, score_subdir, level_subdir);
- else
- score_dir = getPath2(data_dir, score_subdir);
+ {
+ checked_free(score_level_dir);
+
+ score_level_dir = getPath2(score_dir, level_subdir);
+
+ return score_level_dir;
+ }
return score_dir;
}
char *getProgramConfigFilename(char *command_filename_ptr)
{
- char *command_filename = getStringCopy(command_filename_ptr);
+ char *command_filename_1 = getStringCopy(command_filename_ptr);
// strip trailing executable suffix from command filename
- if (strSuffix(command_filename, ".exe"))
- command_filename[strlen(command_filename) - 4] = '\0';
+ if (strSuffix(command_filename_1, ".exe"))
+ command_filename_1[strlen(command_filename_1) - 4] = '\0';
+
+ char *command_basepath = getBasePath(command_filename_ptr);
+ char *command_basename = getBaseNameNoSuffix(command_filename_ptr);
+ char *command_filename_2 = getPath2(command_basepath, command_basename);
- return getStringCat2(command_filename, ".conf");
+ char *config_filename_1 = getStringCat2(command_filename_1, ".conf");
+ char *config_filename_2 = getStringCat2(command_filename_2, ".conf");
+
+ // 1st try: look for config file that exactly matches the binary filename
+ if (fileExists(config_filename_1))
+ return config_filename_1;
+
+ // 2nd try: return config filename that matches binary filename without suffix
+ return config_filename_2;
}
char *getTapeFilename(int nr)
void InitScoreDirectory(char *level_subdir)
{
- createDirectory(getCommonDataDir(), "common data", PERMS_PUBLIC);
- createDirectory(getScoreDir(NULL), "main score", PERMS_PUBLIC);
- createDirectory(getScoreDir(level_subdir), "level score", PERMS_PUBLIC);
+ int permissions = (program.global_scores ? PERMS_PUBLIC : PERMS_PRIVATE);
+
+ if (program.global_scores)
+ createDirectory(getCommonDataDir(), "common data", permissions);
+ else
+ createDirectory(getUserGameDataDir(), "user data", permissions);
+
+ createDirectory(getScoreDir(NULL), "main score", permissions);
+ createDirectory(getScoreDir(level_subdir), "level score", permissions);
}
static void SaveUserLevelInfo();
#define MODE_X_ALL (S_IXUSR | S_IXGRP | S_IXOTH)
#define MODE_W_PRIVATE (S_IWUSR)
-#define MODE_W_PUBLIC (S_IWUSR | S_IWGRP)
+#define MODE_W_PUBLIC_FILE (S_IWUSR | S_IWGRP)
#define MODE_W_PUBLIC_DIR (S_IWUSR | S_IWGRP | S_ISGID)
#define DIR_PERMS_PRIVATE (MODE_R_ALL | MODE_X_ALL | MODE_W_PRIVATE)
#define DIR_PERMS_PUBLIC (MODE_R_ALL | MODE_X_ALL | MODE_W_PUBLIC_DIR)
+#define DIR_PERMS_PUBLIC_ALL (MODE_R_ALL | MODE_X_ALL | MODE_W_ALL)
#define FILE_PERMS_PRIVATE (MODE_R_ALL | MODE_W_PRIVATE)
-#define FILE_PERMS_PUBLIC (MODE_R_ALL | MODE_W_PUBLIC)
+#define FILE_PERMS_PUBLIC (MODE_R_ALL | MODE_W_PUBLIC_FILE)
+#define FILE_PERMS_PUBLIC_ALL (MODE_R_ALL | MODE_W_ALL)
+
char *getHomeDir()
{
#if defined(PLATFORM_ANDROID)
if (user_game_data_dir == NULL)
- user_game_data_dir = (char *)SDL_AndroidGetInternalStoragePath();
+ user_game_data_dir = (char *)(SDL_AndroidGetExternalStorageState() &
+ SDL_ANDROID_EXTERNAL_STORAGE_WRITE ?
+ SDL_AndroidGetExternalStoragePath() :
+ SDL_AndroidGetInternalStoragePath());
#else
if (user_game_data_dir == NULL)
user_game_data_dir = getPath2(getPersonalDataDir(),
return user_game_data_dir;
}
-void updateUserGameDataDir()
-{
-#if defined(PLATFORM_MACOSX)
- char *userdata_dir_old = getPath2(getHomeDir(), program.userdata_subdir_unix);
- char *userdata_dir_new = getUserGameDataDir(); /* do not free() this */
-
- /* convert old Unix style game data directory to Mac OS X style, if needed */
- if (directoryExists(userdata_dir_old) && !directoryExists(userdata_dir_new))
- {
- if (rename(userdata_dir_old, userdata_dir_new) != 0)
- {
- Error(ERR_WARN, "cannot move game data directory '%s' to '%s'",
- userdata_dir_old, userdata_dir_new);
-
- /* continue using Unix style data directory -- this should not happen */
- program.userdata_path = getPath2(getPersonalDataDir(),
- program.userdata_subdir_unix);
- }
- }
-
- free(userdata_dir_old);
-#endif
-}
-
char *getSetupDir()
{
return getUserGameDataDir();
void createDirectory(char *dir, char *text, int permission_class)
{
+ if (directoryExists(dir))
+ return;
+
/* leave "other" permissions in umask untouched, but ensure group parts
of USERDATA_DIR_MODE are not masked */
mode_t dir_mode = (permission_class == PERMS_PRIVATE ?
mode_t group_umask = ~(dir_mode & S_IRWXG);
int running_setgid = posix_process_running_setgid();
- /* if we're setgid, protect files against "other" */
- /* else keep umask(0) to make the dir world-writable */
+ if (permission_class == PERMS_PUBLIC)
+ {
+ /* if we're setgid, protect files against "other" */
+ /* else keep umask(0) to make the dir world-writable */
- if (running_setgid)
- posix_umask(last_umask & group_umask);
- else
- dir_mode |= MODE_W_ALL;
+ if (running_setgid)
+ posix_umask(last_umask & group_umask);
+ else
+ dir_mode = DIR_PERMS_PUBLIC_ALL;
+ }
- if (!directoryExists(dir))
- if (posix_mkdir(dir, dir_mode) != 0)
- Error(ERR_WARN, "cannot create %s directory '%s': %s",
- text, dir, strerror(errno));
+ if (posix_mkdir(dir, dir_mode) != 0)
+ Error(ERR_WARN, "cannot create %s directory '%s': %s",
+ text, dir, strerror(errno));
if (permission_class == PERMS_PUBLIC && !running_setgid)
chmod(dir, dir_mode);
FILE_PERMS_PRIVATE : FILE_PERMS_PUBLIC);
if (permission_class == PERMS_PUBLIC && !running_setgid)
- perms |= MODE_W_ALL;
+ perms = FILE_PERMS_PUBLIC_ALL;
chmod(filename, perms);
}