// Helper function for get_dirlist, it does the bulk of the work. static int enumerate_folder(CalcHandle* handle, GNode** vars, const char * folder_name) { int ret; ticalcs_info("enumerate_folder<%s>\n", folder_name); do { char varname[VARNAME_MAX]; ret = nsp_cmd_s_dir_enum_init(handle, folder_name); if (ret) { break; } ret = nsp_cmd_r_dir_enum_init(handle); if (ret) { break; } for (;;) { VarEntry *fe; GNode *node; char *ext; uint32_t varsize; uint8_t vartype; ret = nsp_cmd_s_dir_enum_next(handle); if (ret) { break; } ret = nsp_cmd_r_dir_enum_next(handle, varname, &varsize, &vartype); if (ret == ERR_EOT) { ret = 0; break; } else if (ret != 0) { break; } fe = tifiles_ve_create(); ticalcs_strlcpy(fe->folder, folder_name + 1, sizeof(fe->folder)); // Skip leading / fe->size = varsize; fe->type = vartype; fe->attr = ATTRB_NONE; ext = tifiles_fext_get(varname); // Just a sanity check if (ext) { // Did the file name have any non-empty extension ? if (*ext) { // Do we know about this file type ? if (fe->type < NSP_MAXTYPES) { // Then we can remove the exension. *(ext-1) = '\0'; } // else don't remove the extension. } // else there is no extension to remove. } ticalcs_strlcpy(fe->name, varname, sizeof(fe->name)); node = dirlist_create_append_node(fe, vars); if (!node) { ret = ERR_MALLOC; break; } ticalcs_info(_("Name: %s | Type: %8s | Attr: %i | Size: %08X"), fe->name, tifiles_vartype2string(handle->model, fe->type), fe->attr, fe->size); } while (!ret) { int i; ret = nsp_cmd_s_dir_enum_done(handle); if (ret) { break; } ret = nsp_cmd_r_dir_enum_done(handle); if (ret) { break; } // Enumerate elements of root folder. for (i = 0; i < (int)g_node_n_children(*vars); i++) { char new_folder_name[FLDNAME_MAX]; const char * separator_if_any; GNode * folder = g_node_nth_child(*vars, i); uint8_t vartype = ((VarEntry *)(folder->data))->type; // Don't recurse into regular files (type 0, TNS or e.g. themes.csv on OS 3.0+). if (vartype == 0) { ticalcs_info(_("Not enumerating documents in %s because it's not a folder\n"), ((VarEntry *)(folder->data))->name); continue; } // Prevent names from starting with "//". if (strcmp(folder_name, "/")) { separator_if_any = "/"; } else { separator_if_any = ""; } ticalcs_slprintf(new_folder_name, sizeof(new_folder_name), "%s%s%s", folder_name, separator_if_any, ((VarEntry *)(folder->data))->name); ticalcs_info(_("Directory listing in <%s>...\n"), new_folder_name); ret = enumerate_folder(handle, &folder, new_folder_name); if (ret) { break; } } break; } } while (0); return ret; }
static int get_dirlist (CalcHandle* handle, GNode** vars, GNode** apps) { TreeInfo *ti; int err; GNode *root, *folder = NULL; char varname[VARNAME_MAX]; uint32_t varsize; uint8_t vartype; int i; (*apps) = g_node_new(NULL); ti = (TreeInfo *)g_malloc(sizeof(TreeInfo)); ti->model = handle->model; ti->type = APP_NODE_NAME; (*apps)->data = ti; (*vars) = g_node_new(NULL); ti = (TreeInfo *)g_malloc(sizeof(TreeInfo)); ti->model = handle->model; ti->type = VAR_NODE_NAME; (*vars)->data = ti; root = g_node_new(NULL); g_node_append(*apps, root); TRYF(nsp_session_open(handle, SID_FILE_MGMT)); TRYF(nsp_cmd_s_dir_attributes(handle, "/")); TRYF(nsp_cmd_r_dir_attributes(handle, NULL, NULL, NULL)); TRYF(nsp_session_close(handle)); TRYF(nsp_session_open(handle, SID_FILE_MGMT)); TRYF(nsp_cmd_s_dir_enum_init(handle, "/")); TRYF(nsp_cmd_r_dir_enum_init(handle)); for(;;) { VarEntry *fe; GNode *node; TRYF(nsp_cmd_s_dir_enum_next(handle)); err = nsp_cmd_r_dir_enum_next(handle, varname, &varsize, &vartype); if (err == ERR_EOT) break; else if (err != 0) return err; fe = tifiles_ve_create(); strcpy(fe->folder, varname); strcpy(fe->name, varname); fe->size = varsize; fe->type = vartype; fe->attr = ATTRB_NONE; node = g_node_new(fe); folder = g_node_append(*vars, node); ticalcs_info(_("Name: %s | Type: %8s | Attr: %i | Size: %08X"), fe->name, tifiles_vartype2string(handle->model, fe->type), fe->attr, fe->size); } TRYF(nsp_cmd_s_dir_enum_done(handle)); TRYF(nsp_cmd_r_dir_enum_done(handle)); for(i = 0; i < (int)g_node_n_children(*vars); i++) { char *folder_name; char *u1, *u2; folder = g_node_nth_child(*vars, i); folder_name = ((VarEntry *) (folder->data))->name; vartype = ((VarEntry *) (folder->data))->type; // Skip entries whose type is 0 (TNS), for example themes.csv on OS 3.0+. if (vartype == 0) { ticalcs_info(_("Not enumerating documents in %s because it's not a folder"), folder_name); continue; } ticalcs_info(_("Directory listing in <%s>..."), folder_name); TRYF(nsp_cmd_s_dir_enum_init(handle, folder_name)); TRYF(nsp_cmd_r_dir_enum_init(handle)); for(;;) { VarEntry *ve = tifiles_ve_create(); GNode *node; char *ext; TRYF(nsp_cmd_s_dir_enum_next(handle)); err = nsp_cmd_r_dir_enum_next(handle, varname, &varsize, &vartype); if (err == ERR_EOT) break; else if (err != 0) return err; ext = tifiles_fext_get(varname); strcpy(ve->folder, folder_name); ve->size = varsize; ve->type = tifiles_fext2vartype(handle->model, ext); ve->attr = ATTRB_NONE; // Just a sanity check if (ext) { // Did the file name have any non-empty extension ? if (*ext) { // Do we know about this file type ? if (ve->type < NSP_MAXTYPES) { // Then we can remove the exension. *(ext-1) = '\0'; } // else don't remove the extension. } // else there is no extension to remove. } strcpy(ve->name, varname); node = g_node_new(ve); g_node_append(folder, node); ticalcs_info(_("Name: %8s | Type: %8s | Attr: %i | Size: %08X"), ve->name, tifiles_vartype2string(handle->model, ve->type), ve->attr, ve->size); u1 = ticonv_varname_to_utf8(handle->model, ((VarEntry *) (folder->data))->name, -1); u2 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type); g_snprintf(update_->text, sizeof(update_->text), _("Parsing %s/%s"), u1, u2); g_free(u1); g_free(u2); update_label(); } TRYF(nsp_cmd_s_dir_enum_done(handle)); TRYF(nsp_cmd_r_dir_enum_done(handle)); } TRYF(nsp_session_close(handle)); return 0; }