Merge branch '4145_long_file_names'

* 4145_long_file_names:
  WTree: get rid of file name limitation in quick search.
  WPanel: get rid of file name limitation in quick search.
  (mc_g_string_copy): new API that extends GString one.
  (string_file_name): get rid of file name length limitation.
  Ticket #4145: file names longer than 255 bytes are not supported.
This commit is contained in:
Andrew Borodin 2020-12-12 20:26:03 +03:00
commit f0a3794b0e
21 changed files with 208 additions and 128 deletions

View File

@ -160,3 +160,29 @@ g_queue_clear_full (GQueue * queue, GDestroyNotify free_func)
#endif /* ! GLIB_CHECK_VERSION (2, 60, 0) */
/* --------------------------------------------------------------------------------------------- */
/**
* mc_g_string_copy:
* @dest: (not nullable): the destination #GString. Its current contents are destroyed
* @src: (not nullable): the source #GString
* @return: @dest
*
* Copies the bytes from a #GString into a #GString, destroying any previous contents.
* It is rather like the standard strcpy() function, except that you do not have to worry about
* having enough space to copy the string.
*
* There is no such API in GLib2.
*/
GString *
mc_g_string_copy (GString * dest, const GString * src)
{
g_return_val_if_fail (src != NULL, NULL);
g_return_val_if_fail (dest != NULL, NULL);
g_string_set_size (dest, 0);
g_string_append_len (dest, src->str, src->len);
return dest;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -24,6 +24,9 @@ void g_queue_free_full (GQueue * queue, GDestroyNotify free_func);
void g_queue_clear_full (GQueue * queue, GDestroyNotify free_func);
#endif /* ! GLIB_CHECK_VERSION (2, 60, 0) */
/* There is no such API in GLib2 */
GString *mc_g_string_copy (GString * dest, const GString * src);
/*** inline functions ****************************************************************************/
#endif /* MC_GLIBCOMPAT_H */

View File

@ -453,10 +453,10 @@ vfs_s_opendir (const vfs_path_t * vpath)
/* --------------------------------------------------------------------------------------------- */
static void *
static struct vfs_dirent *
vfs_s_readdir (void *data)
{
static union vfs_dirent dir;
struct vfs_dirent *dir = NULL;
struct dirhandle *info = (struct dirhandle *) data;
const char *name;
@ -465,13 +465,13 @@ vfs_s_readdir (void *data)
name = VFS_ENTRY (info->cur->data)->name;
if (name != NULL)
g_strlcpy (dir.dent.d_name, name, MC_MAXPATHLEN);
dir = vfs_dirent_init (NULL, name, 0);
else
vfs_die ("Null in structure-cannot happen");
info->cur = g_list_next (info->cur);
return (void *) &dir;
return dir;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -62,12 +62,10 @@
/* TODO: move it to separate private .h */
extern GString *vfs_str_buffer;
extern vfs_class *current_vfs;
extern struct dirent *mc_readdir_result;
extern struct vfs_dirent *mc_readdir_result;
/*** global variables ****************************************************************************/
struct dirent *mc_readdir_result = NULL;
/*** file scope macro definitions ****************************************************************/
/*** file scope type declarations ****************************************************************/
@ -458,30 +456,15 @@ mc_opendir (const vfs_path_t * vpath)
/* --------------------------------------------------------------------------------------------- */
struct dirent *
struct vfs_dirent *
mc_readdir (DIR * dirp)
{
int handle;
struct vfs_class *vfs;
void *fsinfo = NULL;
struct dirent *entry = NULL;
struct vfs_dirent *entry = NULL;
vfs_path_element_t *vfs_path_element;
if (mc_readdir_result == NULL)
{
/* We can't just allocate struct dirent as (see man dirent.h)
* struct dirent has VERY nonnaive semantics of allocating
* d_name in it. Moreover, linux's glibc-2.9 allocates dirents _less_,
* than 'sizeof (struct dirent)' making full bitwise (sizeof dirent) copy
* heap corrupter. So, allocate longliving dirent with at least
* (MAXNAMLEN + 1) for d_name in it.
* Strictly saying resulting dirent is unusable as we don't adjust internal
* structures, holding dirent size. But we don't use it in libc infrastructure.
* TODO: to make simpler homemade dirent-alike structure.
*/
mc_readdir_result = (struct dirent *) g_malloc (sizeof (struct dirent) + MAXNAMLEN + 1);
}
if (dirp == NULL)
{
errno = EFAULT;
@ -507,8 +490,8 @@ mc_readdir (DIR * dirp)
#else
g_string_assign (vfs_str_buffer, entry->d_name);
#endif
mc_readdir_result->d_ino = entry->d_ino;
g_strlcpy (mc_readdir_result->d_name, vfs_str_buffer->str, MAXNAMLEN + 1);
vfs_dirent_assign (mc_readdir_result, vfs_str_buffer->str, entry->d_ino);
vfs_dirent_free (entry);
}
if (entry == NULL)
errno = vfs->readdir ? vfs_ferrno (vfs) : E_NOTSUPP;

View File

@ -69,13 +69,14 @@
#include "gc.h"
/* TODO: move it to the separate .h */
extern struct dirent *mc_readdir_result;
extern struct vfs_dirent *mc_readdir_result;
extern GPtrArray *vfs__classes_list;
extern GString *vfs_str_buffer;
extern vfs_class *current_vfs;
/*** global variables ****************************************************************************/
struct vfs_dirent *mc_readdir_result = NULL;
GPtrArray *vfs__classes_list = NULL;
GString *vfs_str_buffer = NULL;
vfs_class *current_vfs = NULL;
@ -469,6 +470,7 @@ vfs_init (void)
vfs_str_buffer = g_string_new ("");
mc_readdir_result = vfs_dirent_init (NULL, "", -1);
}
/* --------------------------------------------------------------------------------------------- */
@ -518,10 +520,70 @@ vfs_shut (void)
vfs_str_buffer = NULL;
current_vfs = NULL;
vfs_free_handle_list = -1;
MC_PTR_FREE (mc_readdir_result);
vfs_dirent_free (mc_readdir_result);
mc_readdir_result = NULL;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Init or create vfs_dirent structure
*
* @d vfs_dirent structure to init. If NULL, new structure is created.
* @fname file name
* @ino file inode number
*
* @return pointer to d if d isn't NULL, or pointer to newly created structure.
*/
struct vfs_dirent *
vfs_dirent_init (struct vfs_dirent *d, const char *fname, ino_t ino)
{
struct vfs_dirent *ret = d;
if (ret == NULL)
ret = g_new0 (struct vfs_dirent, 1);
if (ret->d_name_str == NULL)
ret->d_name_str = g_string_sized_new (MC_MAXFILENAMELEN);
vfs_dirent_assign (ret, fname, ino);
return ret;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Assign members of vfs_dirent structure
*
* @d vfs_dirent structure for assignment
* @fname file name
* @ino file inode number
*/
void
vfs_dirent_assign (struct vfs_dirent *d, const char *fname, ino_t ino)
{
g_string_assign (d->d_name_str, fname);
d->d_name = d->d_name_str->str;
d->d_ino = ino;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Destroy vfs_dirent structure
*
* @d vfs_dirent structure to destroy.
*/
void
vfs_dirent_free (struct vfs_dirent *d)
{
g_string_free (d->d_name_str, TRUE);
g_free (d);
}
/* --------------------------------------------------------------------------------------------- */
/**
* These ones grab information from the VFS
* and handles them to an upper layer

View File

@ -9,7 +9,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <dirent.h> /* DIR */
#ifdef HAVE_UTIMENSAT
#include <sys/time.h>
#elif defined (HAVE_UTIME_H)
@ -20,7 +20,6 @@
#include <stddef.h>
#include "lib/global.h"
#include "lib/fs.h" /* MC_MAXPATHLEN */
#include "path.h"
@ -172,7 +171,7 @@ typedef struct vfs_class
ssize_t (*write) (void *vfs_info, const char *buf, size_t count);
void *(*opendir) (const vfs_path_t * vpath);
void *(*readdir) (void *vfs_info);
struct vfs_dirent *(*readdir) (void *vfs_info);
int (*closedir) (void *vfs_info);
int (*stat) (const vfs_path_t * vpath, struct stat * buf);
@ -211,13 +210,17 @@ typedef struct vfs_class
} vfs_class;
/*
* This union is used to ensure that there is enough space for the
* filename (d_name) when the dirent structure is created.
* This struct is used instead of standard dirent to hold file name of any length
* (not limited to NAME_MAX).
*/
union vfs_dirent
struct vfs_dirent
{
struct dirent dent;
char _extra_buffer[offsetof (struct dirent, d_name) + MC_MAXPATHLEN + 1];
/* private */
GString *d_name_str;
/* public */
ino_t d_ino;
char *d_name; /* Alias of d_name_str->str */
};
/*** global variables defined in .c file *********************************************************/
@ -278,6 +281,10 @@ void vfs_stamp_path (const vfs_path_t * path);
void vfs_release_path (const vfs_path_t * vpath);
struct vfs_dirent *vfs_dirent_init (struct vfs_dirent *d, const char *fname, ino_t ino);
void vfs_dirent_assign (struct vfs_dirent *d, const char *fname, ino_t ino);
void vfs_dirent_free (struct vfs_dirent *d);
void vfs_fill_names (fill_names_f);
/* *INDENT-OFF* */
@ -309,7 +316,7 @@ int mc_readlink (const vfs_path_t * vpath, char *buf, size_t bufsiz);
int mc_close (int handle);
off_t mc_lseek (int fd, off_t offset, int whence);
DIR *mc_opendir (const vfs_path_t * vpath);
struct dirent *mc_readdir (DIR * dirp);
struct vfs_dirent *mc_readdir (DIR * dirp);
int mc_closedir (DIR * dir);
int mc_stat (const vfs_path_t * vpath, struct stat *buf);
int mc_mknod (const vfs_path_t * vpath, mode_t mode, dev_t dev);

View File

@ -139,7 +139,7 @@ filename_completion_function (const char *text, int state, input_complete_t flag
static vfs_path_t *dirname_vpath = NULL;
gboolean isdir = TRUE, isexec = FALSE;
struct dirent *entry = NULL;
struct vfs_dirent *entry = NULL;
SHOW_C_CTX ("filename_completion_function");

View File

@ -145,7 +145,7 @@ clean_sort_keys (dir_list * list, int start, int count)
*/
static gboolean
handle_dirent (struct dirent *dp, const char *fltr, struct stat *buf1, gboolean * link_to_dir,
handle_dirent (struct vfs_dirent *dp, const char *fltr, struct stat *buf1, gboolean * link_to_dir,
gboolean * stale_link)
{
vfs_path_t *vpath;
@ -624,7 +624,7 @@ dir_list_load (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
const dir_sort_options_t * sort_op, const char *fltr)
{
DIR *dirp;
struct dirent *dp;
struct vfs_dirent *dp;
struct stat st;
file_entry_t *fentry;
const char *vpath_str;
@ -697,7 +697,7 @@ dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
const dir_sort_options_t * sort_op, const char *fltr)
{
DIR *dirp;
struct dirent *dp;
struct vfs_dirent *dp;
int i;
struct stat st;
int marked_cnt;

View File

@ -624,7 +624,7 @@ do_compute_dir_size (const vfs_path_t * dirname_vpath, dirsize_status_msg_t * ds
int res;
struct stat s;
DIR *dir;
struct dirent *dirent;
struct vfs_dirent *dirent;
FileProgressStatus ret = FILE_CONT;
(*dir_count)++;
@ -1403,7 +1403,7 @@ try_erase_dir (file_op_context_t * ctx, const char *dir)
static FileProgressStatus
recursive_erase (file_op_total_context_t * tctx, file_op_context_t * ctx, const vfs_path_t * vpath)
{
struct dirent *next;
struct vfs_dirent *next;
DIR *reading;
const char *s;
FileProgressStatus return_status = FILE_CONT;
@ -1458,7 +1458,7 @@ static int
check_dir_is_empty (const vfs_path_t * vpath)
{
DIR *dir;
struct dirent *d;
struct vfs_dirent *d;
int i = 1;
dir = mc_opendir (vpath);
@ -2766,7 +2766,7 @@ FileProgressStatus
copy_dir_dir (file_op_total_context_t * tctx, file_op_context_t * ctx, const char *s, const char *d,
gboolean toplevel, gboolean move_over, gboolean do_delete, GSList * parent_dirs)
{
struct dirent *next;
struct vfs_dirent *next;
struct stat dst_stat, src_stat;
DIR *reading;
FileProgressStatus return_status = FILE_CONT;

View File

@ -1247,7 +1247,7 @@ find_rotate_dash (const WDialog * h, gboolean show)
static int
do_search (WDialog * h)
{
static struct dirent *dp = NULL;
static struct vfs_dirent *dp = NULL;
static DIR *dirp = NULL;
static char *directory = NULL;
struct stat tmp_stat;

View File

@ -370,6 +370,8 @@ static WPanel *mouse_mark_panel = NULL;
static gboolean mouse_marking = FALSE;
static int state_mark = 0;
static GString *string_file_name_buffer;
/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
@ -451,12 +453,12 @@ add_permission_string (const char *dest, int width, file_entry_t * fe, int attr,
static const char *
string_file_name (file_entry_t * fe, int len)
{
static char buffer[MC_MAXPATHLEN * MB_LEN_MAX + 1];
(void) len;
g_strlcpy (buffer, fe->fname, sizeof (buffer));
return buffer;
g_string_set_size (string_file_name_buffer, 0);
g_string_append_len (string_file_name_buffer, fe->fname, fe->fnamelen);
return string_file_name_buffer->str;
}
/* --------------------------------------------------------------------------------------------- */
@ -994,7 +996,7 @@ display_mini_info (WPanel * panel)
{
tty_setcolor (INPUT_COLOR);
tty_print_char ('/');
tty_print_string (str_fit_to_term (panel->quick_search.buffer, w->cols - 3, J_LEFT));
tty_print_string (str_fit_to_term (panel->quick_search.buffer->str, w->cols - 3, J_LEFT));
return;
}
@ -1501,6 +1503,9 @@ panel_destroy (WPanel * p)
g_free (p->dir.list);
g_free (p->name);
g_string_free (p->quick_search.buffer, TRUE);
g_string_free (p->quick_search.prev_buffer, TRUE);
vfs_path_free (p->lwd_vpath);
vfs_path_free (p->cwd_vpath);
}
@ -2626,7 +2631,6 @@ panel_select_invert_files (WPanel * panel)
static void
do_search (WPanel * panel, int c_code)
{
size_t l;
int i, sel;
gboolean wrapped = FALSE;
char *act;
@ -2634,14 +2638,13 @@ do_search (WPanel * panel, int c_code)
char *reg_exp, *esc_str;
gboolean is_found = FALSE;
l = strlen (panel->quick_search.buffer);
if (c_code == KEY_BACKSPACE)
{
if (l != 0)
if (panel->quick_search.buffer->len != 0)
{
act = panel->quick_search.buffer + l;
str_prev_noncomb_char (&act, panel->quick_search.buffer);
act[0] = '\0';
act = panel->quick_search.buffer->str + panel->quick_search.buffer->len;
str_prev_noncomb_char (&act, panel->quick_search.buffer->str);
g_string_set_size (panel->quick_search.buffer, act - panel->quick_search.buffer->str);
}
panel->quick_search.chpoint = 0;
}
@ -2663,19 +2666,14 @@ do_search (WPanel * panel, int c_code)
panel->quick_search.chpoint = 0;
return;
default:
if (l + panel->quick_search.chpoint < sizeof (panel->quick_search.buffer))
{
memcpy (panel->quick_search.buffer + l, panel->quick_search.ch,
panel->quick_search.chpoint);
l += panel->quick_search.chpoint;
panel->quick_search.buffer[l] = '\0';
panel->quick_search.chpoint = 0;
}
g_string_append_len (panel->quick_search.buffer, panel->quick_search.ch,
panel->quick_search.chpoint);
panel->quick_search.chpoint = 0;
}
}
}
reg_exp = g_strdup_printf ("%s*", panel->quick_search.buffer);
reg_exp = g_strdup_printf ("%s*", panel->quick_search.buffer->str);
esc_str = strutils_escape (reg_exp, -1, ",|\\{}[]", TRUE);
search = mc_search_new (esc_str, NULL);
search->search_type = MC_SEARCH_T_GLOB;
@ -2721,9 +2719,9 @@ do_search (WPanel * panel, int c_code)
}
else if (c_code != KEY_BACKSPACE)
{
act = panel->quick_search.buffer + l;
str_prev_noncomb_char (&act, panel->quick_search.buffer);
act[0] = '\0';
act = panel->quick_search.buffer->str + panel->quick_search.buffer->len;
str_prev_noncomb_char (&act, panel->quick_search.buffer->str);
g_string_set_size (panel->quick_search.buffer, act - panel->quick_search.buffer->str);
}
mc_search_free (search);
g_free (reg_exp);
@ -2747,16 +2745,15 @@ start_search (WPanel * panel)
/* in case if there was no search string we need to recall
previous string, with which we ended previous searching */
if (panel->quick_search.buffer[0] == '\0')
g_strlcpy (panel->quick_search.buffer, panel->quick_search.prev_buffer,
sizeof (panel->quick_search.buffer));
if (panel->quick_search.buffer->len == 0)
mc_g_string_copy (panel->quick_search.buffer, panel->quick_search.prev_buffer);
do_search (panel, 0);
}
else
{
panel->quick_search.active = TRUE;
panel->quick_search.buffer[0] = '\0';
g_string_set_size (panel->quick_search.buffer, 0);
panel->quick_search.ch[0] = '\0';
panel->quick_search.chpoint = 0;
display_mini_info (panel);
@ -2773,9 +2770,8 @@ stop_search (WPanel * panel)
/* if user overrdied search string, we need to store it
to the quick_search.prev_buffer */
if (panel->quick_search.buffer[0] != '\0')
g_strlcpy (panel->quick_search.prev_buffer, panel->quick_search.buffer,
sizeof (panel->quick_search.prev_buffer));
if (panel->quick_search.buffer->len != 0)
mc_g_string_copy (panel->quick_search.prev_buffer, panel->quick_search.buffer);
display_mini_info (panel);
}
@ -4327,6 +4323,9 @@ panel_sized_empty_new (const char *panel_name, int y, int x, int lines, int cols
panel->frame_size = frame_half;
panel->quick_search.buffer = g_string_sized_new (MC_MAXFILENAMELEN);
panel->quick_search.prev_buffer = g_string_sized_new (MC_MAXFILENAMELEN);
panel->name = g_strdup (panel_name);
panel->dir_history.name = g_strconcat ("Dir Hist ", panel->name, (char *) NULL);
/* directories history will be get later */
@ -4992,6 +4991,8 @@ panel_init (void)
panel_filename_scroll_right_char =
mc_skin_get ("widget-panel", "filename-scroll-right-char", "}");
string_file_name_buffer = g_string_sized_new (MC_MAXFILENAMELEN);
mc_event_add (MCEVENT_GROUP_FILEMANAGER, "update_panels", event_update_panels, NULL, NULL);
mc_event_add (MCEVENT_GROUP_FILEMANAGER, "panel_save_current_file_to_clip_file",
panel_save_current_file_to_clip_file, NULL, NULL);
@ -5011,6 +5012,7 @@ panel_deinit (void)
g_free (panel_history_show_list_char);
g_free (panel_filename_scroll_left_char);
g_free (panel_filename_scroll_right_char);
g_string_free (string_file_name_buffer, TRUE);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -141,8 +141,8 @@ typedef struct
struct
{
gboolean active;
char buffer[MC_MAXFILENAMELEN];
char prev_buffer[MC_MAXFILENAMELEN];
GString *buffer;
GString *prev_buffer;
char ch[MB_LEN_MAX]; /* Buffer for multi-byte character */
int chpoint; /* Point after last characters in @ch */
} quick_search;

View File

@ -92,7 +92,7 @@ struct WTree
Widget widget;
struct TreeStore *store;
tree_entry *selected_ptr; /* The selected directory */
char search_buffer[MC_MAXFILENAMELEN]; /* Current search string */
GString *search_buffer; /* Current search string */
tree_entry **tree_shown; /* Entries currently on screen */
gboolean is_panel; /* panel or plain widget flag */
gboolean searching; /* Are we on searching mode? */
@ -195,6 +195,7 @@ tree_destroy (WTree * tree)
save_tree (tree);
MC_PTR_FREE (tree->tree_shown);
g_string_free (tree->search_buffer, TRUE);
tree->selected_ptr = NULL;
}
@ -239,7 +240,7 @@ tree_show_mini_info (WTree * tree, int tree_lines, int tree_cols)
tty_draw_hline (w->y + line, w->x + 1, ' ', tree_cols);
widget_gotoyx (w, line, 1);
tty_print_char (PATH_SEP);
tty_print_string (str_fit_to_term (tree->search_buffer, tree_cols - 2, J_LEFT_FIT));
tty_print_string (str_fit_to_term (tree->search_buffer->str, tree_cols - 2, J_LEFT_FIT));
tty_print_char (' ');
}
else
@ -618,19 +619,15 @@ maybe_chdir (WTree * tree)
/* --------------------------------------------------------------------------------------------- */
/** Search tree for text */
static int
search_tree (WTree * tree, char *text)
static gboolean
search_tree (WTree * tree, const GString * text)
{
tree_entry *current;
size_t len;
tree_entry *current = tree->selected_ptr;
gboolean wrapped = FALSE;
gboolean found = FALSE;
len = strlen (text);
current = tree->selected_ptr;
while (!found && (!wrapped || current != tree->selected_ptr))
if (strncmp (current->subname, text, len) == 0)
if (strncmp (current->subname, text->str, text->len) == 0)
{
tree->selected_ptr = current;
found = TRUE;
@ -656,19 +653,15 @@ search_tree (WTree * tree, char *text)
static void
tree_do_search (WTree * tree, int key)
{
size_t l;
/* TODO: support multi-byte characters, see do_search() in panel.c */
l = strlen (tree->search_buffer);
if ((l != 0) && (key == KEY_BACKSPACE))
tree->search_buffer[--l] = '\0';
else if (key && l < sizeof (tree->search_buffer) - 1)
{
tree->search_buffer[l] = key;
tree->search_buffer[++l] = '\0';
}
if (tree->search_buffer->len != 0 && key == KEY_BACKSPACE)
g_string_set_size (tree->search_buffer, tree->search_buffer->len - 1);
else if (key != 0)
g_string_append_c (tree->search_buffer, (gchar) key);
if (!search_tree (tree, tree->search_buffer))
tree->search_buffer[--l] = '\0';
g_string_set_size (tree->search_buffer, tree->search_buffer->len - 1);
show_tree (tree);
maybe_chdir (tree);
@ -970,7 +963,7 @@ tree_start_search (WTree * tree)
else
{
tree->searching = TRUE;
tree->search_buffer[0] = '\0';
g_string_set_size (tree->search_buffer, 0);
}
}
@ -1301,7 +1294,7 @@ tree_new (int y, int x, int lines, int cols, gboolean is_panel)
tree->store = tree_store_get ();
tree_store_add_entry_remove_hook (remove_callback, tree);
tree->tree_shown = NULL;
tree->search_buffer[0] = '\0';
tree->search_buffer = g_string_sized_new (MC_MAXPATHLEN);
tree->topdiff = w->lines / 2;
tree->searching = FALSE;

View File

@ -909,7 +909,7 @@ tree_store_rescan (const vfs_path_t * vpath)
dirp = mc_opendir (vpath);
if (dirp != NULL)
{
struct dirent *dp;
struct vfs_dirent *dp;
for (dp = mc_readdir (dirp); dp != NULL; dp = mc_readdir (dirp))
if (!DIR_IS_DOT (dp->d_name) && !DIR_IS_DOTDOT (dp->d_name))

View File

@ -1047,20 +1047,20 @@ extfs_opendir (const vfs_path_t * vpath)
/* --------------------------------------------------------------------------------------------- */
static void *
static struct vfs_dirent *
extfs_readdir (void *data)
{
static union vfs_dirent dir;
struct vfs_dirent *dir;
GList **info = (GList **) data;
if (*info == NULL)
return NULL;
g_strlcpy (dir.dent.d_name, VFS_ENTRY ((*info)->data)->name, MC_MAXPATHLEN);
dir = vfs_dirent_init (NULL, VFS_ENTRY ((*info)->data)->name, 0); /* FIXME: inode */
*info = g_list_next (*info);
return (void *) &dir;
return dir;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -103,10 +103,14 @@ local_opendir (const vfs_path_t * vpath)
/* --------------------------------------------------------------------------------------------- */
static void *
static struct vfs_dirent *
local_readdir (void *data)
{
return readdir (*(DIR **) data);
struct dirent *d;
d = readdir (*(DIR **) data);
return (d != NULL ? vfs_dirent_init (NULL, d->d_name, d->d_ino) : NULL);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -115,13 +115,12 @@ sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror)
* @return information about direntry if success, NULL otherwise
*/
void *
struct vfs_dirent *
sftpfs_readdir (void *data, GError ** mcerror)
{
char mem[BUF_MEDIUM];
LIBSSH2_SFTP_ATTRIBUTES attrs;
sftpfs_dir_data_t *sftpfs_dir = (sftpfs_dir_data_t *) data;
static union vfs_dirent sftpfs_dirent;
int rc;
mc_return_val_if_error (mcerror, NULL);
@ -137,11 +136,7 @@ sftpfs_readdir (void *data, GError ** mcerror)
}
while (rc == LIBSSH2_ERROR_EAGAIN);
if (rc == 0)
return NULL;
g_strlcpy (sftpfs_dirent.dent.d_name, mem, BUF_MEDIUM);
return &sftpfs_dirent;
return (rc != 0 ? vfs_dirent_init (NULL, mem, 0) : NULL); /* FIXME: inode */
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -91,7 +91,7 @@ void sftpfs_close_connection (struct vfs_s_super *super, const char *shutdown_me
vfs_file_handler_t *sftpfs_fh_new (struct vfs_s_inode *ino, gboolean changed);
void *sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror);
void *sftpfs_readdir (void *data, GError ** mcerror);
struct vfs_dirent *sftpfs_readdir (void *data, GError ** mcerror);
int sftpfs_closedir (void *data, GError ** mcerror);
int sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror);
int sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror);

View File

@ -188,11 +188,11 @@ sftpfs_cb_opendir (const vfs_path_t * vpath)
* @return information about direntry if success, NULL otherwise
*/
static void *
static struct vfs_dirent *
sftpfs_cb_readdir (void *data)
{
GError *mcerror = NULL;
union vfs_dirent *sftpfs_dirent;
struct vfs_dirent *sftpfs_dirent;
if (tty_got_interrupt ())
{
@ -204,7 +204,7 @@ sftpfs_cb_readdir (void *data)
if (!mc_error_message (&mcerror, NULL))
{
if (sftpfs_dirent != NULL)
vfs_print_message (_("sftp: (Ctrl-G break) Listing... %s"), sftpfs_dirent->dent.d_name);
vfs_print_message (_("sftp: (Ctrl-G break) Listing... %s"), sftpfs_dirent->d_name);
else
vfs_print_message ("%s", _("sftp: Listing done."));
}

View File

@ -915,11 +915,10 @@ smbfs_free_dir (dir_entry * de)
/* It's too slow to ask the server each time */
/* It now also sends the complete lstat information for each file */
static void *
static struct vfs_dirent *
smbfs_readdir (void *info)
{
static union vfs_dirent smbfs_readdir_data;
static char *const dirent_dest = smbfs_readdir_data.dent.d_name;
struct vfs_dirent *dirent;
opendir_info *smbfs_info = (opendir_info *) info;
DEBUG (4, ("smbfs_readdir(%s)\n", smbfs_info->dirname));
@ -937,10 +936,12 @@ smbfs_readdir (void *info)
#endif
return NULL;
}
g_strlcpy (dirent_dest, smbfs_info->current->text, MC_MAXPATHLEN);
dirent = vfs_dirent_init (NULL, smbfs_info->current->text, 0); /* FIXME: inode */
smbfs_info->current = smbfs_info->current->next;
return &smbfs_readdir_data;
return dirent;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -400,11 +400,10 @@ undelfs_opendir (const vfs_path_t * vpath)
/* --------------------------------------------------------------------------------------------- */
static void *
static struct vfs_dirent *
undelfs_readdir (void *vfs_info)
{
static union vfs_dirent undelfs_readdir_data;
static char *const dirent_dest = undelfs_readdir_data.dent.d_name;
struct vfs_dirent *dirent;
if (vfs_info != fs)
{
@ -414,13 +413,18 @@ undelfs_readdir (void *vfs_info)
if (readdir_ptr == num_delarray)
return NULL;
if (readdir_ptr < 0)
strcpy (dirent_dest, readdir_ptr == -2 ? "." : "..");
dirent = vfs_dirent_init (NULL, readdir_ptr == -2 ? "." : "..", 0); /* FIXME: inode */
else
{
char dirent_dest[MC_MAXPATHLEN];
g_snprintf (dirent_dest, MC_MAXPATHLEN, "%ld:%d",
(long) delarray[readdir_ptr].ino, delarray[readdir_ptr].num_blocks);
dirent = vfs_dirent_init (NULL, dirent_dest, 0); /* FIXME: inode */
}
readdir_ptr++;
return &undelfs_readdir_data;
return dirent;
}
/* --------------------------------------------------------------------------------------------- */