From e4961563c4019892d8965779c6979c38c2f68017 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Tue, 19 Jul 2011 11:30:20 +0300 Subject: [PATCH] Ticket #81: savannah: can't access files on ftp starting with space files starting with space can't be acessed by mc through ftp - it shows the file as not having the leading space and attempts to access it produce 'permission denied' errors. Signed-off-by: Slava Zanko --- lib/vfs/mc-vfs/direntry.c | 25 +++++++++++++++++++++++++ lib/vfs/mc-vfs/extfs.c | 3 ++- lib/vfs/mc-vfs/ftpfs.c | 6 +++++- lib/vfs/mc-vfs/utilvfs.c | 19 ++++++++++++++----- lib/vfs/mc-vfs/utilvfs.h | 2 +- lib/vfs/mc-vfs/xdirentry.h | 9 +++++++++ 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/lib/vfs/mc-vfs/direntry.c b/lib/vfs/mc-vfs/direntry.c index 314696b..959f8ca 100644 --- a/lib/vfs/mc-vfs/direntry.c +++ b/lib/vfs/mc-vfs/direntry.c @@ -1468,3 +1468,28 @@ vfs_s_get_line_interruptible (struct vfs_class *me, char *buffer, int size, int #endif /* ENABLE_VFS_NET */ /* --------------------------------------------------------------------------------------------- */ + +/** + * Normalize filenames start position + */ + +void +vfs_s_normalize_filename_pos (struct vfs_s_inode *root_inode, size_t final_filepos) +{ + struct vfs_s_entry *entry; + + for (entry = root_inode->subdir; entry != NULL; entry = entry->next) + { + if ((size_t) entry->ino->data_offset > final_filepos) + { + char *source_name = entry->name; + char *spacer = g_strnfill (entry->ino->data_offset - final_filepos, ' '); + entry->name = g_strdup_printf ("%s%s", spacer, source_name); + g_free (spacer); + g_free (source_name); + } + entry->ino->data_offset = -1; + } +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/lib/vfs/mc-vfs/extfs.c b/lib/vfs/mc-vfs/extfs.c index cb1475c..368a4fc 100644 --- a/lib/vfs/mc-vfs/extfs.c +++ b/lib/vfs/mc-vfs/extfs.c @@ -474,6 +474,7 @@ extfs_read_archive (int fstype, const char *name, struct archive **pparc) char *buffer; struct archive *current_archive; char *current_file_name, *current_link_name; + size_t filepos = 0; info = &g_array_index (extfs_plugins, extfs_plugin_info_t, fstype); @@ -491,7 +492,7 @@ extfs_read_archive (int fstype, const char *name, struct archive **pparc) struct stat hstat; current_link_name = NULL; - if (vfs_parse_ls_lga (buffer, &hstat, ¤t_file_name, ¤t_link_name)) + if (vfs_parse_ls_lga (buffer, &hstat, ¤t_file_name, ¤t_link_name, &filepos)) { struct entry *entry, *pent; struct inode *inode; diff --git a/lib/vfs/mc-vfs/ftpfs.c b/lib/vfs/mc-vfs/ftpfs.c index 9ed3b3a..47c9b9e 100644 --- a/lib/vfs/mc-vfs/ftpfs.c +++ b/lib/vfs/mc-vfs/ftpfs.c @@ -1644,6 +1644,7 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path int sock, num_entries = 0; char lc_buffer[BUF_8K]; int cd_first; + size_t filepos = 0; cd_first = ftpfs_first_cd_then_ls || (SUP.strict == RFC_STRICT) || (strchr (remote_path, ' ') != NULL); @@ -1714,13 +1715,14 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path ent = vfs_s_generate_entry (me, NULL, dir, 0); i = ent->ino->st.st_nlink; - if (!vfs_parse_ls_lga (lc_buffer, &ent->ino->st, &ent->name, &ent->ino->linkname)) + if (!vfs_parse_ls_lga (lc_buffer, &ent->ino->st, &ent->name, &ent->ino->linkname, &filepos)) { vfs_s_free_entry (me, ent); continue; } ent->ino->st.st_nlink = i; /* Ouch, we need to preserve our counts :-( */ num_entries++; + vfs_s_store_filename_pos (ent, filepos); vfs_s_insert_entry (me, dir, ent); } @@ -1745,6 +1747,8 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path goto again; } + vfs_s_normalize_filename_pos (dir, filepos); + if (SUP.strict == RFC_AUTODETECT) SUP.strict = RFC_DARING; diff --git a/lib/vfs/mc-vfs/utilvfs.c b/lib/vfs/mc-vfs/utilvfs.c index ab4cbdf..df57bce 100644 --- a/lib/vfs/mc-vfs/utilvfs.c +++ b/lib/vfs/mc-vfs/utilvfs.c @@ -929,8 +929,9 @@ vfs_parse_filedate (int idx, time_t * t) /* --------------------------------------------------------------------------------------------- */ -int -vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linkname) +gboolean +vfs_parse_ls_lga (const char *p, struct stat * s, char **filename, char **linkname, + size_t * filename_pos) { int idx, idx2, num_cols; int i; @@ -940,7 +941,7 @@ vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linknam size_t skipped; if (strncmp (p, "total", 5) == 0) - return 0; + return FALSE; if (!vfs_parse_filetype (p, &skipped, &s->st_mode)) goto error; @@ -1058,6 +1059,14 @@ vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linknam s->st_blocks = (s->st_size + 511) / 512; #endif + if (filename_pos != NULL) + { + if ((*filename_pos == 0) || (*filename_pos > (size_t) column_ptr[idx])) + *filename_pos = column_ptr[idx]; + else + column_ptr[idx] = *filename_pos; + } + for (i = idx + 1, idx2 = 0; i < num_cols; i++) if (strcmp (columns[i], "->") == 0) { @@ -1107,7 +1116,7 @@ vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linknam } g_free (p_copy); - return 1; + return TRUE; error: { @@ -1122,7 +1131,7 @@ vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linknam } g_free (p_copy); - return 0; + return FALSE; } /* --------------------------------------------------------------------------------------------- */ diff --git a/lib/vfs/mc-vfs/utilvfs.h b/lib/vfs/mc-vfs/utilvfs.h index 0c1159d..7967daf 100644 --- a/lib/vfs/mc-vfs/utilvfs.h +++ b/lib/vfs/mc-vfs/utilvfs.h @@ -52,7 +52,7 @@ gboolean vfs_parse_fileperms (const char *s, size_t * ret_skipped, mode_t * ret_ gboolean vfs_parse_filemode (const char *s, size_t * ret_skipped, mode_t * ret_mode); gboolean vfs_parse_raw_filemode (const char *s, size_t * ret_skipped, mode_t * ret_mode); -int vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linkname); +gboolean vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linkname, size_t *filename_pos); int vfs_parse_filedate (int idx, time_t * t); /*** inline functions ****************************************************************************/ diff --git a/lib/vfs/mc-vfs/xdirentry.h b/lib/vfs/mc-vfs/xdirentry.h index 9e87f1f..0d43743 100644 --- a/lib/vfs/mc-vfs/xdirentry.h +++ b/lib/vfs/mc-vfs/xdirentry.h @@ -249,5 +249,14 @@ int vfs_s_get_line_interruptible (struct vfs_class *me, char *buffer, int size, /* misc */ int vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino); +void vfs_s_normalize_filename_pos (struct vfs_s_inode *root_inode, size_t final_filepos); + /*** inline functions ****************************************************************************/ + +static inline void +vfs_s_store_filename_pos (struct vfs_s_entry *entry, size_t position) +{ + entry->ino->data_offset = (off_t) position; +} + #endif -- 1.7.3.3