diff --git a/src/browser.c b/src/browser.c index 7fda929..4c5afec 100644 --- a/src/browser.c +++ b/src/browser.c @@ -46,7 +46,7 @@ static size_t selected = 0; * start browsing from. */ char *do_browser(char *path) { - char *retval = NULL; + char *retval = NULL, *newpath = NULL; int kbinput; char *present_name = NULL; /* The name of the currently selected file, or of the directory we @@ -75,17 +75,37 @@ char *do_browser(char *path) /* Start with no key pressed. */ kbinput = ERR; - path = mallocstrassn(path, get_full_path(path)); + if (newpath == NULL) + path = mallocstrassn(path, get_full_path(path)); + else { + path = mallocstrassn(path, get_full_path(newpath)); + + if (path == NULL) { + statusline(ALERT, "Directory is inaccessible"); + path = mallocstrcpy(NULL, present_path); + present_name = mallocstrcpy(present_name, newpath); + } else if (strcmp(tail(newpath), "..") == 0) + /* We moved up a level -- remember where we came from, so + * this directory can be highlighted and easily reentered. */ + present_name = striponedir(newpath); + + newpath = NULL; + + dir = opendir(path); + } /* Save the current path in order to be used later. */ present_path = mallocstrcpy(present_path, path); assert(path != NULL && path[strlen(path) - 1] == '/'); - /* Get the file list, and set longest and width in the process. */ - read_the_list(path, dir); - - closedir(dir); + if (dir == NULL) + statusline(ALERT, _("Error reading %s: %s"), path, strerror(errno)); + else { + /* Get the file list, and set longest and width in the process. */ + read_the_list(path, dir); + closedir(dir); + } /* If given, reselect the present_name and then discard it. */ if (present_name != NULL) { @@ -104,9 +124,6 @@ char *do_browser(char *path) while (TRUE) { struct stat st; int i; - char *new_path; - /* The path we switch to at the "Go to Directory" - * prompt. */ /* Make sure that the cursor is off. */ curs_set(0); @@ -240,37 +257,26 @@ char *do_browser(char *path) sunder(answer); align(&answer); - new_path = real_dir_from_tilde(answer); + newpath = real_dir_from_tilde(answer); - if (new_path[0] != '/') { - new_path = charealloc(new_path, strlen(path) + + if (newpath[0] != '/') { + newpath = charealloc(newpath, strlen(path) + strlen(answer) + 1); - sprintf(new_path, "%s%s", path, answer); + sprintf(newpath, "%s%s", path, answer); } #ifndef DISABLE_OPERATINGDIR - if (check_operating_dir(new_path, FALSE)) { + if (check_operating_dir(newpath, FALSE)) { /* TRANSLATORS: This refers to the option --operatingdir, * not to --restricted. */ statusline(ALERT, _("Can't go outside of %s " "in confined mode"), full_operating_dir); - free(new_path); + free(newpath); continue; } #endif - dir = opendir(new_path); - if (dir == NULL) { - /* We can't open this directory for some reason. */ - statusline(ALERT, _("Error reading %s: %s"), answer, - strerror(errno)); - free(new_path); - continue; - } - - /* Start over again with the new path value. */ - free(path); - path = new_path; + /* Try opening and reading the selected directory in newpath. */ goto read_directory_contents; } else if (func == do_up_void) { if (selected >= width) @@ -323,22 +329,8 @@ char *do_browser(char *path) break; } - dir = opendir(filelist[selected]); - - if (dir == NULL) { - statusline(ALERT, _("Error reading %s: %s"), - filelist[selected], strerror(errno)); - continue; - } - - /* If we moved up one level, remember where we came from, so - * this directory can be highlighted and easily reentered. */ - if (strcmp(tail(filelist[selected]), "..") == 0) - present_name = striponedir(filelist[selected]); - - path = mallocstrcpy(path, filelist[selected]); - - /* Start over again with the new path value. */ + /* Try opening and reading the selected directory. */ + newpath = filelist[selected]; goto read_directory_contents; } else if (func == do_exit) { /* Exit from the file browser. */