mirror of
https://github.com/MidnightCommander/mc
synced 2025-02-08 03:14:17 +03:00
Merge branch '1757_dotdot_dir'
* 1757_dotdot_dir: Display ATime, MTime and CTime for ".." in file panel. Fixed display info about ".." directory in Info panel. Set correct stat info for ".." directory. Ticket #1757: set actual stat info for ".." directory in panel.
This commit is contained in:
commit
cae3e29bce
96
src/dir.c
96
src/dir.c
@ -27,14 +27,17 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "../src/tty/tty.h"
|
||||
#include "dir.h"
|
||||
|
||||
#include "../src/search/search.h"
|
||||
|
||||
#include "global.h"
|
||||
#include "wtools.h"
|
||||
#include "treestore.h"
|
||||
#include "strutil.h"
|
||||
#include "fs.h"
|
||||
#include "../src/search/search.h"
|
||||
#include "util.h" /* canonicalize_pathname () */
|
||||
#include "dir.h"
|
||||
|
||||
/* If true show files starting with a dot */
|
||||
int show_dot_files = 1;
|
||||
@ -256,34 +259,29 @@ clean_dir (dir_list *list, int count)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
add_dotdot_to_list (dir_list *list, int lc_index)
|
||||
/* Used to set up a directory list when there is no access to a directory */
|
||||
gboolean
|
||||
set_zero_dir (dir_list *list)
|
||||
{
|
||||
/* Need to grow the *list? */
|
||||
if (lc_index == list->size) {
|
||||
if (list->size == 0) {
|
||||
list->list = g_realloc (list->list, sizeof (file_entry) *
|
||||
(list->size + RESIZE_STEPS));
|
||||
if (!list->list)
|
||||
return 0;
|
||||
if (list->list == NULL)
|
||||
return FALSE;
|
||||
|
||||
list->size += RESIZE_STEPS;
|
||||
}
|
||||
|
||||
memset (&(list->list) [lc_index], 0, sizeof(file_entry));
|
||||
(list->list) [lc_index].fnamelen = 2;
|
||||
(list->list) [lc_index].fname = g_strdup ("..");
|
||||
(list->list) [lc_index].f.link_to_dir = 0;
|
||||
(list->list) [lc_index].f.stale_link = 0;
|
||||
(list->list) [lc_index].f.dir_size_computed = 0;
|
||||
(list->list) [lc_index].f.marked = 0;
|
||||
(list->list) [lc_index].st.st_mode = 040755;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Used to set up a directory list when there is no access to a directory */
|
||||
int
|
||||
set_zero_dir (dir_list *list)
|
||||
{
|
||||
return (add_dotdot_to_list (list, 0));
|
||||
memset (&(list->list) [0], 0, sizeof(file_entry));
|
||||
list->list[0].fnamelen = 2;
|
||||
list->list[0].fname = g_strdup ("..");
|
||||
list->list[0].f.link_to_dir = 0;
|
||||
list->list[0].f.stale_link = 0;
|
||||
list->list[0].f.dir_size_computed = 0;
|
||||
list->list[0].f.marked = 0;
|
||||
list->list[0].st.st_mode = 040755;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If you change handle_dirent then check also handle_path. */
|
||||
@ -339,6 +337,26 @@ handle_dirent (dir_list *list, const char *filter, struct dirent *dp,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get info about ".." */
|
||||
static gboolean
|
||||
get_dotdot_dir_stat (const char *path, struct stat *st)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if ((path != NULL) && (path[0] != '\0') && (st != NULL)) {
|
||||
char *dotdot_dir;
|
||||
struct stat s;
|
||||
|
||||
dotdot_dir = g_strdup_printf ("%s/../", path);
|
||||
canonicalize_pathname (dotdot_dir);
|
||||
ret = mc_stat (dotdot_dir, &s) == 0;
|
||||
g_free (dotdot_dir);
|
||||
*st = s;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* handle_path is a simplified handle_dirent. The difference is that
|
||||
handle_path doesn't pay attention to show_dot_files and show_backups.
|
||||
Moreover handle_path can't be used with a filemask.
|
||||
@ -392,8 +410,11 @@ do_load_dir (const char *path, dir_list *list, sortfn *sort, int lc_reverse,
|
||||
struct stat st;
|
||||
|
||||
/* ".." (if any) must be the first entry in the list */
|
||||
if (set_zero_dir (list) == 0)
|
||||
if (!set_zero_dir (list))
|
||||
return next_free;
|
||||
|
||||
if (get_dotdot_dir_stat (path, &st))
|
||||
list->list[next_free].st = st;
|
||||
next_free++;
|
||||
|
||||
dirp = mc_opendir (path);
|
||||
@ -401,10 +422,13 @@ do_load_dir (const char *path, dir_list *list, sortfn *sort, int lc_reverse,
|
||||
message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
|
||||
return next_free;
|
||||
}
|
||||
|
||||
tree_store_start_check (path);
|
||||
|
||||
/* Do not add a ".." entry to the root directory */
|
||||
if (!strcmp (path, "/"))
|
||||
if ((path[0] == PATH_SEP) && (path[1] == '\0'))
|
||||
next_free--;
|
||||
|
||||
while ((dp = mc_readdir (dirp))) {
|
||||
status =
|
||||
handle_dirent (list, filter, dp, &st, next_free, &link_to_dir,
|
||||
@ -426,13 +450,13 @@ do_load_dir (const char *path, dir_list *list, sortfn *sort, int lc_reverse,
|
||||
list->list[next_free].sort_key = NULL;
|
||||
list->list[next_free].second_sort_key = NULL;
|
||||
next_free++;
|
||||
if (!(next_free % 32))
|
||||
|
||||
if ((next_free & 31) == 0)
|
||||
rotate_dash ();
|
||||
}
|
||||
|
||||
if (next_free) {
|
||||
if (next_free != 0)
|
||||
do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff);
|
||||
}
|
||||
|
||||
mc_closedir (dirp);
|
||||
tree_store_end_check ();
|
||||
@ -504,7 +528,7 @@ do_reload_dir (const char *path, dir_list *list, sortfn *sort, int count,
|
||||
if (!dirp) {
|
||||
message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
|
||||
clean_dir (list, count);
|
||||
return set_zero_dir (list);
|
||||
return set_zero_dir (list) ? 1 : 0;
|
||||
}
|
||||
|
||||
tree_store_start_check (path);
|
||||
@ -529,12 +553,16 @@ do_reload_dir (const char *path, dir_list *list, sortfn *sort, int count,
|
||||
|
||||
/* Add ".." except to the root directory. The ".." entry
|
||||
(if any) must be the first in the list. */
|
||||
if (strcmp (path, "/") != 0) {
|
||||
if (set_zero_dir (list) == 0) {
|
||||
if (!((path[0] == PATH_SEP) && (path[1] == '\0'))) {
|
||||
if (!set_zero_dir (list)) {
|
||||
clean_dir (list, count);
|
||||
clean_dir (&dir_copy, count);
|
||||
return next_free;
|
||||
}
|
||||
|
||||
if (get_dotdot_dir_stat (path, &st))
|
||||
list->list[next_free].st = st;
|
||||
|
||||
next_free++;
|
||||
}
|
||||
|
||||
@ -581,8 +609,8 @@ do_reload_dir (const char *path, dir_list *list, sortfn *sort, int count,
|
||||
list->list[next_free].f.stale_link = stale_link;
|
||||
list->list[next_free].f.dir_size_computed = 0;
|
||||
list->list[next_free].st = st;
|
||||
list->list[next_free].sort_key = NULL;
|
||||
list->list[next_free].second_sort_key = NULL;
|
||||
list->list[next_free].sort_key = NULL;
|
||||
list->list[next_free].second_sort_key = NULL;
|
||||
next_free++;
|
||||
if (!(next_free % 16))
|
||||
rotate_dash ();
|
||||
|
12
src/dir.h
12
src/dir.h
@ -6,17 +6,17 @@
|
||||
#ifndef MC_DIR_H
|
||||
#define MC_DIR_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#define MIN_FILES 128
|
||||
#define RESIZE_STEPS 128
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* keys are set only during sorting */
|
||||
typedef struct {
|
||||
|
||||
/* File attributes */
|
||||
|
||||
int fnamelen;
|
||||
size_t fnamelen;
|
||||
char *fname;
|
||||
struct stat st;
|
||||
/* key used for comparing names */
|
||||
@ -47,7 +47,7 @@ void do_sort (dir_list * list, sortfn * sort, int top, int reverse,
|
||||
int do_reload_dir (const char *path, dir_list * list, sortfn * sort, int count,
|
||||
int reverse, int case_sensitive, int exec_ff, const char *filter);
|
||||
void clean_dir (dir_list * list, int count);
|
||||
int set_zero_dir (dir_list * list);
|
||||
gboolean set_zero_dir (dir_list *list);
|
||||
int handle_path (dir_list *list, const char *path, struct stat *buf1,
|
||||
int next_free, int *link_to_dir, int *stale_link);
|
||||
|
||||
|
37
src/info.c
37
src/info.c
@ -70,7 +70,7 @@ static void info_box (Dlg_head *h, struct WInfo *info)
|
||||
static void
|
||||
info_show_info (struct WInfo *info)
|
||||
{
|
||||
static int i18n_adjust=0;
|
||||
static int i18n_adjust = 0;
|
||||
static const char *file_label;
|
||||
GString *buff;
|
||||
struct stat st;
|
||||
@ -96,10 +96,10 @@ info_show_info (struct WInfo *info)
|
||||
|
||||
/* Print only lines which fit */
|
||||
|
||||
if(!i18n_adjust) {
|
||||
if (i18n_adjust == 0) {
|
||||
/* This printf pattern string is used as a reference for size */
|
||||
file_label=_("File: %s");
|
||||
i18n_adjust = str_term_width1(file_label) + 2;
|
||||
file_label = _("File: %s");
|
||||
i18n_adjust = str_term_width1 (file_label) + 2;
|
||||
}
|
||||
|
||||
buff = g_string_new ("");
|
||||
@ -193,30 +193,30 @@ info_show_info (struct WInfo *info)
|
||||
tty_printf (_("Owner: %s/%s"),
|
||||
get_owner (st.st_uid),
|
||||
get_group (st.st_gid));
|
||||
|
||||
|
||||
case 6:
|
||||
widget_move (&info->widget, 6, 3);
|
||||
tty_printf (_("Links: %d"), (int) st.st_nlink);
|
||||
|
||||
|
||||
case 5:
|
||||
widget_move (&info->widget, 5, 3);
|
||||
tty_printf (_("Mode: %s (%04o)"),
|
||||
string_perm (st.st_mode), (unsigned) st.st_mode & 07777);
|
||||
|
||||
|
||||
case 4:
|
||||
widget_move (&info->widget, 4, 3);
|
||||
tty_printf (_("Location: %Xh:%Xh"), (int)st.st_dev, (int)st.st_ino);
|
||||
|
||||
|
||||
case 3:
|
||||
{
|
||||
const char *fname;
|
||||
|
||||
widget_move (&info->widget, 3, 2);
|
||||
/* .ado: fname is invalid if selected == 0 && info called from current panel */
|
||||
if (current_panel->selected){
|
||||
str_printf (buff, file_label,
|
||||
str_trunc (current_panel->dir.list [current_panel->selected].fname,
|
||||
info->widget.cols - i18n_adjust));
|
||||
tty_print_string (buff->str);
|
||||
} else
|
||||
tty_print_string (_("File: None"));
|
||||
fname = current_panel->dir.list [current_panel->selected].fname;
|
||||
str_printf (buff, file_label,
|
||||
str_trunc (fname, info->widget.cols - i18n_adjust));
|
||||
tty_print_string (buff->str);
|
||||
}
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
@ -230,13 +230,13 @@ static void info_hook (void *data)
|
||||
{
|
||||
struct WInfo *info = (struct WInfo *) data;
|
||||
Widget *other_widget;
|
||||
|
||||
|
||||
other_widget = get_panel_widget (get_current_index ());
|
||||
if (!other_widget)
|
||||
return;
|
||||
if (dlg_overlap (&info->widget, other_widget))
|
||||
return;
|
||||
|
||||
|
||||
info->ready = 1;
|
||||
info_show_info (info);
|
||||
}
|
||||
@ -301,4 +301,3 @@ info_new (void)
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ static void do_external_panelize (char *command)
|
||||
chdir (PATH_SEP_STR);
|
||||
}
|
||||
} else {
|
||||
current_panel->count = set_zero_dir (list);
|
||||
current_panel->count = set_zero_dir (list) ? 1 : 0;
|
||||
}
|
||||
if (pclose (external) < 0)
|
||||
message (D_NORMAL, _("External panelize"), _("Pipe close failed"));
|
||||
|
13
src/screen.c
13
src/screen.c
@ -300,9 +300,6 @@ static const char *
|
||||
string_file_mtime (file_entry *fe, int len)
|
||||
{
|
||||
(void) len;
|
||||
if (!strcmp (fe->fname, "..")) {
|
||||
return "";
|
||||
}
|
||||
return file_date (fe->st.st_mtime);
|
||||
}
|
||||
|
||||
@ -311,9 +308,6 @@ static const char *
|
||||
string_file_atime (file_entry *fe, int len)
|
||||
{
|
||||
(void) len;
|
||||
if (!strcmp (fe->fname, "..")) {
|
||||
return "";
|
||||
}
|
||||
return file_date (fe->st.st_atime);
|
||||
}
|
||||
|
||||
@ -322,9 +316,6 @@ static const char *
|
||||
string_file_ctime (file_entry *fe, int len)
|
||||
{
|
||||
(void) len;
|
||||
if (!strcmp (fe->fname, "..")) {
|
||||
return "";
|
||||
}
|
||||
return file_date (fe->st.st_ctime);
|
||||
}
|
||||
|
||||
@ -1338,7 +1329,7 @@ panel_reload (WPanel *panel)
|
||||
|
||||
if (panel->cwd[0] == PATH_SEP && panel->cwd[1] == 0) {
|
||||
panel_clean_dir (panel);
|
||||
panel->count = set_zero_dir (&panel->dir);
|
||||
panel->count = set_zero_dir (&panel->dir) ? 1 : 0;
|
||||
return;
|
||||
}
|
||||
last_slash = strrchr (panel->cwd, PATH_SEP);
|
||||
@ -3227,7 +3218,7 @@ reload_panelized (WPanel *panel)
|
||||
j++;
|
||||
}
|
||||
if (j == 0)
|
||||
panel->count = set_zero_dir (list);
|
||||
panel->count = set_zero_dir (list) ? 1 : 0;
|
||||
else
|
||||
panel->count = j;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user