Beispiel #1
0
bool platform_ensure_directory_exists(const utf8 *path)
{
    mode_t mask = getumask();
    char buffer[MAX_PATH];
    platform_utf8_to_multibyte(path, buffer, MAX_PATH);

    log_verbose("Create directory: %s", buffer);
    for (char *p = buffer + 1; *p != '\0'; p++) {
        if (*p == '/') {
            // Temporarily truncate
            *p = '\0';

            log_verbose("mkdir(%s)", buffer);
            if (mkdir(buffer, mask) != 0) {
                if (errno != EEXIST) {
                    return false;
                }
            }

            // Restore truncation
            *p = '/';
        }
    }

    log_verbose("mkdir(%s)", buffer);
    if (mkdir(buffer, mask) != 0) {
        if (errno != EEXIST) {
            return false;
        }
    }

    return true;
}
Beispiel #2
0
bool platform_file_exists(const utf8 *path)
{
    char buffer[MAX_PATH];
    platform_utf8_to_multibyte(path, buffer, MAX_PATH);
    bool exists = access(buffer, F_OK) != -1;
    log_verbose("file '%s' exists = %i", buffer, exists);
    return exists;
}
Beispiel #3
0
bool platform_original_game_data_exists(const utf8 *path)
{
    char buffer[MAX_PATH];
    platform_utf8_to_multibyte(path, buffer, MAX_PATH);
    char checkPath[MAX_PATH];
    safe_strcpy(checkPath, buffer, MAX_PATH);
    safe_strcat_path(checkPath, "Data", MAX_PATH);
    safe_strcat_path(checkPath, "g1.dat", MAX_PATH);
    return platform_file_exists(checkPath);
}
Beispiel #4
0
bool platform_directory_exists(const utf8 *path)
{
    char buffer[MAX_PATH];
    platform_utf8_to_multibyte(path, buffer, MAX_PATH);
    struct stat dirinfo;
    sint32 result = stat(buffer, &dirinfo);
    log_verbose("checking dir %s, result = %d, is_dir = %d", buffer, result, S_ISDIR(dirinfo.st_mode));
    if ((result != 0) || !S_ISDIR(dirinfo.st_mode))
    {
        return false;
    }
    return true;
}
Beispiel #5
0
sint32 platform_enumerate_directories_begin(const utf8 *directory)
{
    char npattern[MAX_PATH];
    sint32 length = platform_utf8_to_multibyte(directory, npattern, MAX_PATH) + 1;
    enumerate_file_info *enumFileInfo;
    log_verbose("begin directory listing, path: %s", npattern);

    // TODO: add some checking for stringness and directoryness

    sint32 cnt;
    for (sint32 i = 0; i < countof(_enumerateFileInfoList); i++) {
        enumFileInfo = &_enumerateFileInfoList[i];
        if (!enumFileInfo->active) {
            safe_strcpy(enumFileInfo->pattern, npattern, length);
            cnt = scandir(npattern, &enumFileInfo->fileListTemp, dirfilter, alphasort);
            if (cnt < 0)
            {
                break;
            }
            log_verbose("found %d files in dir '%s'", cnt, npattern);
            enumFileInfo->cnt = cnt;
            enumFileInfo->paths = malloc(cnt * sizeof(char *));
            char **paths = enumFileInfo->paths;
            // 256 is size of dirent.d_name
            const sint32 dir_name_len = strnlen(npattern, MAX_PATH);
            for (sint32 idx = 0; idx < cnt; idx++)
            {
                struct dirent *d = enumFileInfo->fileListTemp[idx];
                const sint32 entry_len = strnlen(d->d_name, MAX_PATH);
                // 1 for separator, 1 for trailing null
                size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
                paths[idx] = malloc(path_len);
                log_verbose("dir_name: %s", npattern);
                safe_strcpy(paths[idx], npattern, path_len);
                safe_strcat_path(paths[idx], d->d_name, path_len);
                log_verbose("paths[%d] = %s", idx, paths[idx]);
            }
            enumFileInfo->handle = 0;
            enumFileInfo->active = 1;
            return i;
        }
    }

    return -1;
}
Beispiel #6
0
sint32 platform_enumerate_files_begin(const utf8 *pattern)
{
    char npattern[MAX_PATH];
    platform_utf8_to_multibyte(pattern, npattern, MAX_PATH);
    enumerate_file_info *enumFileInfo;
    log_verbose("begin file search, pattern: %s", npattern);

    char *file_name = strrchr(npattern, *PATH_SEPARATOR);
    char *dir_name;
    if (file_name != NULL)
    {
        dir_name = strndup(npattern, file_name - npattern);
        file_name = &file_name[1];
    } else {
        file_name = npattern;
        dir_name = strdup(".");
    }


    sint32 pattern_length = strlen(file_name);
    g_file_pattern = strndup(file_name, pattern_length);
    for (sint32 j = 0; j < pattern_length; j++)
    {
        g_file_pattern[j] = (char)toupper(g_file_pattern[j]);
    }
    log_verbose("looking for file matching %s", g_file_pattern);
    sint32 cnt;
    for (sint32 i = 0; i < countof(_enumerateFileInfoList); i++) {
        enumFileInfo = &_enumerateFileInfoList[i];
        if (!enumFileInfo->active) {
            safe_strcpy(enumFileInfo->pattern, npattern, sizeof(enumFileInfo->pattern));
            cnt = scandir(dir_name, &enumFileInfo->fileListTemp, winfilter, alphasort);
            if (cnt < 0)
            {
                break;
            }
            log_verbose("found %d files matching in dir '%s'", cnt, dir_name);
            enumFileInfo->cnt = cnt;
            enumFileInfo->paths = malloc(cnt * sizeof(char *));
            char **paths = enumFileInfo->paths;
            // 256 is size of dirent.d_name
            const sint32 dir_name_len = strnlen(dir_name, MAX_PATH);
            for (sint32 idx = 0; idx < cnt; idx++)
            {
                struct dirent *d = enumFileInfo->fileListTemp[idx];
                const sint32 entry_len = strnlen(d->d_name, MAX_PATH);
                // 1 for separator, 1 for trailing null
                size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
                paths[idx] = malloc(path_len);
                log_verbose("dir_name: %s", dir_name);
                safe_strcpy(paths[idx], dir_name, path_len);
                safe_strcat_path(paths[idx], d->d_name, path_len);
                log_verbose("paths[%d] = %s", idx, paths[idx]);

// macOS uses decomposed Unicode strings (e.g. an 'e' and a combining accent) in filenames
// This causes problems with the sprite font, as the font only contains precomposed characters
// The block below converts all filename strings to their precomposed form, preventing mojibake
#ifdef __APPLE__
                utf8* precomp_path = macos_str_decomp_to_precomp(paths[idx]);
                size_t precomp_len = sizeof(utf8) * min(MAX_PATH, strnlen(precomp_path, MAX_PATH) + 2);
                paths[idx] = malloc(precomp_len);
                safe_strcpy(paths[idx], precomp_path, precomp_len);
                log_verbose("macOS decomp-to-precomp fix - paths[%d] = %s", idx, paths[idx]);
#endif
            }
            enumFileInfo->handle = 0;
            enumFileInfo->active = 1;
            free(dir_name);
            free(g_file_pattern);
            g_file_pattern = NULL;
            return i;
        }
    }

    free(dir_name);
    free(g_file_pattern);
    g_file_pattern = NULL;
    return -1;
}
Beispiel #7
0
sint32 platform_enumerate_files_begin(const utf8 *pattern)
{
	char npattern[MAX_PATH];
	platform_utf8_to_multibyte(pattern, npattern, MAX_PATH);
	enumerate_file_info *enumFileInfo;
	log_verbose("begin file search, pattern: %s", npattern);

	char *file_name = strrchr(npattern, *PATH_SEPARATOR);
	char *dir_name;
	if (file_name != NULL)
	{
		dir_name = strndup(npattern, file_name - npattern);
		file_name = &file_name[1];
	} else {
		file_name = npattern;
		dir_name = strdup(".");
	}


	sint32 pattern_length = strlen(file_name);
	g_file_pattern = strndup(file_name, pattern_length);
	for (sint32 j = 0; j < pattern_length; j++)
	{
		g_file_pattern[j] = (char)toupper(g_file_pattern[j]);
	}
	log_verbose("looking for file matching %s", g_file_pattern);
	sint32 cnt;
	for (sint32 i = 0; i < countof(_enumerateFileInfoList); i++) {
		enumFileInfo = &_enumerateFileInfoList[i];
		if (!enumFileInfo->active) {
			safe_strcpy(enumFileInfo->pattern, npattern, sizeof(enumFileInfo->pattern));
			cnt = scandir(dir_name, &enumFileInfo->fileListTemp, winfilter, alphasort);
			if (cnt < 0)
			{
				break;
			}
			log_verbose("found %d files matching in dir '%s'", cnt, dir_name);
			enumFileInfo->cnt = cnt;
			enumFileInfo->paths = malloc(cnt * sizeof(char *));
			char **paths = enumFileInfo->paths;
			// 256 is size of dirent.d_name
			const sint32 dir_name_len = strnlen(dir_name, MAX_PATH);
			for (sint32 idx = 0; idx < cnt; idx++)
			{
				struct dirent *d = enumFileInfo->fileListTemp[idx];
				const sint32 entry_len = strnlen(d->d_name, MAX_PATH);
				// 1 for separator, 1 for trailing null
				size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
				paths[idx] = malloc(path_len);
				log_verbose("dir_name: %s", dir_name);
				safe_strcpy(paths[idx], dir_name, path_len);
				safe_strcat_path(paths[idx], d->d_name, path_len);
				log_verbose("paths[%d] = %s", idx, paths[idx]);
			}
			enumFileInfo->handle = 0;
			enumFileInfo->active = 1;
			free(dir_name);
			free(g_file_pattern);
			g_file_pattern = NULL;
			return i;
		}
	}

	free(dir_name);
	free(g_file_pattern);
	g_file_pattern = NULL;
	return -1;
}