bool MCFileSystemListEntries(const char *p_folder, uint32_t p_options, MCFileSystemListCallback p_callback, void *p_context) { bool t_success = true; char *t_resolved_path = nil; DIR *t_dir = nil; t_success = MCFileSystemPathResolve(p_folder, t_resolved_path); if (t_success) { t_dir = opendir(t_resolved_path); t_success = t_dir != nil; } if (t_success) { struct dirent *t_entry = nil; struct stat t_entry_stat; MCFileSystemEntry t_fs_entry; while (t_success && nil != (t_entry = readdir(t_dir))) { if (!MCCStringEqual(t_entry->d_name, ".") && !MCCStringEqual(t_entry->d_name, "..")) { char *t_child_path = nil; t_success = MCCStringFormat(t_child_path, "%s/%s", t_resolved_path, t_entry->d_name); if (t_success) t_success = -1 != lstat(t_child_path, &t_entry_stat); MCCStringFree(t_child_path); if (t_success) { t_fs_entry.filename = t_entry->d_name; if (S_ISLNK(t_entry_stat.st_mode)) t_fs_entry.type = kMCFileSystemEntryLink; else if (S_ISDIR(t_entry_stat.st_mode)) t_fs_entry.type = kMCFileSystemEntryFolder; else t_fs_entry.type = kMCFileSystemEntryFile; t_success = p_callback(p_context, t_fs_entry); } } } closedir(t_dir); } MCCStringFree(t_resolved_path); return t_success; }
static MCAssetFileHandle *Open(const char *p_path, const char *p_mode) { int32_t t_size = 0; int32_t t_offset = 0; if (!MCCStringEqual(p_mode, "r")) return NULL; if (!apk_get_file_length(p_path, t_size) || !apk_get_file_offset(p_path, t_offset)) return NULL; FILE *t_stream; t_stream = fopen(MCcmd, p_mode); if (t_stream == NULL) return NULL; if (fseeko(t_stream, t_offset, SEEK_SET) != 0) { fclose(t_stream); return NULL; } MCAssetFileHandle *t_handle; t_handle = new MCAssetFileHandle; t_handle -> m_stream = t_stream; t_handle -> m_size = t_size; t_handle -> m_offset = t_offset; t_handle -> m_position = 0; return t_handle; }
bool MCSessionIndexRemoveSession(MCSessionIndexRef p_index, MCSession *p_session) { for (uint32_t i = 0; i < p_index->session_count; i++) { if (MCCStringEqual(p_session->id, p_index->session[i]->id) && MCCStringEqual(p_session->ip, p_index->session[i]->ip)) { MCSessionDisposeSession(p_index->session[i]); MCMemoryMove(p_index->session + i, p_index->session + i + 1, (p_index->session_count - i - 1) * sizeof(MCSession*)); p_index->session_count -= 1; return true; } } return false; }
bool MCCachedImageRep::FindReferencedWithFilename(const char *p_filename, MCCachedImageRep *&r_rep) { for (MCCachedImageRep *t_rep = s_head; t_rep != nil; t_rep = t_rep->m_next) { if (t_rep->GetType() == kMCImageRepReferenced && MCCStringEqual(static_cast<MCReferencedImageRep*>(t_rep)->GetFilename(), p_filename)) { r_rep = t_rep; return true; } } return false; }
// We extract the list of open modules for a process by parsing out the // /proc/<pid>/maps // File. This lists all the files mapped into the processes memory space. bool MCSystemListProcessModules(uint32_t p_process_id, MCSystemListProcessModulesCallback p_callback, void *p_context) { char t_maps_file[6 + I4L + 5 + 1]; sprintf(t_maps_file, "/proc/%u/maps", p_process_id); FILE *t_stream; t_stream = fopen(t_maps_file, "r"); if (t_stream == nil) return false; bool t_success; t_success = true; // Each line is of a fixed format, with any module path appearing at '/'. // Modules are repeated in the map for each segment that is mapped in. Thus // we only report the first appearance, and assume that they are always // consecutive. char t_last_module[4096]; t_last_module[0] = '\0'; while(t_success) { char t_line[4096]; if (fgets(t_line, 4096, t_stream) == nil) break; // See if there is a module path char *t_path; t_path = strchr(t_line, '/'); if (t_path == nil) continue; // See if it is a shared library (terminated by .so, or containing .so.) if (!MCCStringEndsWith(t_path, ".so") || !MCCStringContains(t_path, ".so.") || MCCStringEqual(t_path, t_last_module)) continue; MCAutoStringRef t_path_str; /* UNCHECKED */ MCStringCreateWithSysString(t_path, &t_path_str); t_success = p_callback(p_context, *t_path_str); } fclose(t_stream); return t_success; }
bool MCSessionFindMatchingSession(MCSessionIndexRef p_index, MCStringRef p_session_id, MCSession *&r_session) { MCAutoStringRef t_remote_addr_str; const char *t_remote_addr = NULL; if (!MCS_getenv(MCSTR("REMOTE_ADDR"), &t_remote_addr_str)) t_remote_addr = ""; else t_remote_addr = MCStringGetCString(*t_remote_addr_str); for (uint32_t i = 0; i < p_index->session_count; i++) { if (MCStringIsEqualToCString(p_session_id, p_index->session[i]->id, kMCCompareExact) && MCCStringEqual(p_index->session[i]->ip, t_remote_addr)) { r_session = p_index->session[i]; return true; } } return false; }
static bool MCTextLayoutFontLinkCallback(void *p_context, const char *p_key, DWORD p_type, void *p_value, uint32_t p_value_length) { bool t_success; t_success = true; // Ignore the empty key if (MCCStringEqual(p_key, "")) return true; // Ignore a non REG_MULTI_SZ type if (p_type != REG_MULTI_SZ) return true; // Create a new linked font structure MCTextLayoutLinkedFont *t_font; t_font = nil; if (t_success) t_success = MCMemoryNew(t_font); if (t_success) t_success = MCCStringClone(p_key, t_font -> name); // Attempt to parse the font link string - it should be of type // REG_MULTI_SZ and be a list of entries of the form: // file, face, [ scale, scale ] if (t_success) { char *t_ptr; uint32_t t_len; t_ptr = (char *)p_value; t_len = p_value_length; while(t_success && t_len > 0) { char *t_end; for(t_end = t_ptr; *t_end != '\0' && t_len > 0; t_end += 1, t_len -= 1) ; if (t_end - t_ptr > 0) { char **t_items; uint32_t t_item_count; t_items = nil; t_item_count = 0; if (t_success) t_success = MCCStringSplit(t_ptr, ',', t_items, t_item_count); if (t_item_count >= 2) { if (t_success) t_success = MCMemoryResizeArray(t_font -> entry_count + 1, t_font -> entries, t_font -> entry_count); if (t_success) t_success = MCCStringClone(t_items[1], t_font -> entries[t_font -> entry_count - 1] . face); } for(uint32_t i = 0; i < t_item_count; i++) MCCStringFree(t_items[i]); MCMemoryDeleteArray(t_items); } t_ptr = t_end + 1; t_len -= 1; } } if (t_success) MCListPushFront(s_linked_fonts, t_font); else MCTextLayoutLinkedFontDestroy(t_font); return t_success; }
static void compute_simulator_redirect(const char *p_input, char*& r_output) { if (s_redirects == nil) { r_output = (char *)p_input; return; } char *t_resolved_input; t_resolved_input = nil; if (*p_input != '/') { char *t_cwd; t_cwd = getcwd(nil, 0); MCCStringFormat(t_resolved_input, "%s/%s", t_cwd, p_input); free(t_cwd); } else MCCStringClone(p_input, t_resolved_input); char **t_components; uint32_t t_component_count; MCCStringSplit(t_resolved_input, '/', t_components, t_component_count); MCCStringFree(t_resolved_input); uint32_t t_count; t_count = 1; for(uint32_t j = 1; j < t_component_count; j++) { if (MCCStringEqual(t_components[j], ".") || MCCStringEqual(t_components[j], "")) { MCCStringFree(t_components[j]); continue; } if (MCCStringEqual(t_components[j], "..")) { MCCStringFree(t_components[j]); if (t_count > 1) { MCCStringFree(t_components[t_count - 1]); t_count -= 1; } continue; } t_components[t_count] = t_components[j]; t_count += 1; } MCCStringCombine(t_components, t_count, '/', t_resolved_input); MCCStringArrayFree(t_components, t_count); r_output = t_resolved_input; if (MCCStringBeginsWith(t_resolved_input, s_redirect_base)) { const char *t_input_leaf; t_input_leaf = t_resolved_input + strlen(s_redirect_base) + 1; for(uint32_t i = 0; i < s_redirect_count; i++) { if (MCCStringEqual(s_redirects[i] . src, t_input_leaf)) { r_output = strdup(s_redirects[i] . dst); break; } if (MCCStringBeginsWith(t_input_leaf, s_redirects[i] . src) && t_input_leaf[MCCStringLength(s_redirects[i] . src)] == '/') { MCCStringFormat(r_output, "%s%s", s_redirects[i] . dst, t_input_leaf + MCCStringLength(s_redirects[i] . src)); break; } } } if (r_output != t_resolved_input) MCCStringFree(t_resolved_input); }
static DIR* opendir_wrapper(const char *dirname) { char *t_resolved_path; compute_simulator_redirect(dirname, t_resolved_path); if (s_redirect_base != nil && MCCStringEqual(t_resolved_path, s_redirect_base)) { DIR *t_sys_dir; t_sys_dir = opendir_trampoline(t_resolved_path); if (t_sys_dir == nil) return nil; DIR_wrapper *t_wrapper; t_wrapper = (DIR_wrapper *)malloc(sizeof(DIR_wrapper)); t_wrapper -> fd = -t_sys_dir -> __dd_fd; t_wrapper -> sys_dir = t_sys_dir; t_wrapper -> entry_count = 0; t_wrapper -> entries = nil; t_wrapper -> index = 0; for(;;) { struct dirent *t_dir_entry; t_dir_entry = readdir(t_sys_dir); if (t_dir_entry == nil) break; MCMemoryResizeArray(t_wrapper -> entry_count + 1, t_wrapper -> entries, t_wrapper -> entry_count); MCCStringClone(t_dir_entry -> d_name, t_wrapper -> entries[t_wrapper -> entry_count - 1]); } for(uint32_t i = 0; i < s_redirect_count; i++) { const char *t_src, *t_src_end; t_src = s_redirects[i] . src; t_src_end = strchr(t_src, '/'); if (t_src_end == nil) t_src_end = t_src + strlen(t_src); bool t_found; t_found = false; for(uint32_t j = 0; j < t_wrapper -> entry_count; j++) if (strlen(t_wrapper -> entries[j]) == (t_src_end - t_src) && strncmp(t_wrapper -> entries[j], t_src, t_src_end - t_src) == 0) { t_found = true; break; } if (t_found) continue; MCMemoryResizeArray(t_wrapper -> entry_count + 1, t_wrapper -> entries, t_wrapper -> entry_count); MCCStringCloneSubstring(t_src, t_src_end - t_src, t_wrapper -> entries[t_wrapper -> entry_count - 1]); } return (DIR *)t_wrapper; } DIR *t_result; t_result = opendir_trampoline(t_resolved_path); if (t_resolved_path != dirname) free(t_resolved_path); return t_result; }