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:
Andrew Borodin 2009-11-09 13:08:52 +03:00
commit cae3e29bce
5 changed files with 89 additions and 71 deletions

View File

@ -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 ();

View File

@ -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);

View File

@ -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;
}

View File

@ -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"));

View File

@ -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;