mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 04:46:55 +03:00
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:
commit
f0a3794b0e
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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);
|
||||
|
@ -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."));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
Loading…
Reference in New Issue
Block a user