fish: partially fixed perl backend for FISH
Broken: * spacy files are still broken (like " a b") Changes: * vfs/fish.c learned to parse 'R' (raw filemode) * fixed perl backend escaping Signed-off-by: Sergei Trofimovich <slyfox@inbox.ru>
Этот коммит содержится в:
родитель
636b1ff16f
Коммит
a944b8ca5b
30
vfs/fish.c
30
vfs/fish.c
@ -392,19 +392,30 @@ fish_dir_load(struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
||||
"while( (my $filename = readdir(DIR))){\n"
|
||||
"my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = lstat(\"$dirname/$filename\");\n"
|
||||
"my $mloctime= scalar localtime $mtime;\n"
|
||||
"\n"
|
||||
"# shell escs are taken from here: http://www.slac.stanford.edu/slac/www/resource/how-to-use/cgi-rexx/cgi-esc.html\n"
|
||||
" sub esc_shell_chars {\n"
|
||||
" my $s = $_[0];\n"
|
||||
" $s =~ s/([;<>\\*\\|`&\\$!#\\(\\)\\[\\]\\{\\}:'\\''\"\\ ])/\\\\$1/g;\n"
|
||||
" return $s;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"my $e_filename = esc_shell_chars($filename);\n"
|
||||
"if (S_ISLNK($mode) ) {\n"
|
||||
"my $linkname = readlink (\"$dirname/$filename\");\n"
|
||||
"printf(\"P$mode $uid.$gid\\n"
|
||||
"my $e_linkname = esc_shell_chars($linkname);\n"
|
||||
"\n"
|
||||
"printf(\"R%%o %%o $uid.$gid\\n"
|
||||
"S$size\\n"
|
||||
"d$mloctime\\n"
|
||||
":\\\"$filename\\\" -> \\\"$linkname\\\"\\n"
|
||||
"\\n\");\n"
|
||||
":\\\"$e_filename\\\" -> \\\"$e_linkname\\\"\\n"
|
||||
"\\n\", S_IMODE($mode), S_IFMT($mode));\n"
|
||||
"} else {\n"
|
||||
"printf(\"P$mode $uid.$gid\\n"
|
||||
"printf(\"R%%o %%o $uid.$gid\\n"
|
||||
"S$size\\n"
|
||||
"d$mloctime\\n"
|
||||
":\\\"$filename\\\"\\n"
|
||||
"\\n\");\n"
|
||||
":\\\"$e_filename\\\"\\n"
|
||||
"\\n\", S_IMODE($mode), S_IFMT($mode));\n"
|
||||
"}}\n"
|
||||
"printf(\"### 200\\n\");\n"
|
||||
"closedir(DIR);\n"
|
||||
@ -544,6 +555,13 @@ fish_dir_load(struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
||||
vfs_parse_filemode (buffer + 1, &skipped, &ST.st_mode);
|
||||
break;
|
||||
}
|
||||
case 'R': {
|
||||
// raw filemode:
|
||||
// we expect: Roctal-filemode octal-filetype uid.gid
|
||||
size_t skipped;
|
||||
vfs_parse_raw_filemode (buffer + 1, &skipped, &ST.st_mode);
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
vfs_split_text(buffer+1);
|
||||
if (!vfs_parse_filedate(0, &ST.st_ctime))
|
||||
|
@ -539,6 +539,64 @@ vfs_parse_filemode (const char *s, size_t *ret_skipped,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
vfs_parse_raw_filemode (const char *s, size_t *ret_skipped,
|
||||
mode_t *ret_mode)
|
||||
{
|
||||
const char *p;
|
||||
mode_t remote_type = 0, local_type, perms = 0;
|
||||
|
||||
p = s;
|
||||
|
||||
// isoctal
|
||||
while(*p >= '0' && *p <= '7')
|
||||
{
|
||||
perms *= 010;
|
||||
perms += (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p++ != ' ')
|
||||
return FALSE;
|
||||
|
||||
while(*p >= '0' && *p <= '7')
|
||||
{
|
||||
remote_type *= 010;
|
||||
remote_type += (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p++ != ' ')
|
||||
return FALSE;
|
||||
|
||||
/* generated with:
|
||||
$ perl -e 'use Fcntl ":mode";
|
||||
my @modes = (S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFREG);
|
||||
foreach $t (@modes) { printf ("%o\n", $t); };'
|
||||
TODO: S_IFDOOR, S_IFIFO, S_IFSOCK (if supported by os)
|
||||
(see vfs_parse_filetype)
|
||||
*/
|
||||
|
||||
switch (remote_type)
|
||||
{
|
||||
case 020000:
|
||||
local_type = S_IFCHR; break;
|
||||
case 040000:
|
||||
local_type = S_IFDIR; break;
|
||||
case 060000:
|
||||
local_type = S_IFBLK; break;
|
||||
case 0120000:
|
||||
local_type = S_IFLNK; break;
|
||||
case 0100000:
|
||||
default:// don't know what is it
|
||||
local_type = S_IFREG; break;
|
||||
}
|
||||
|
||||
*ret_skipped = p - s;
|
||||
*ret_mode = local_type | perms;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* This function parses from idx in the columns[] array */
|
||||
int
|
||||
vfs_parse_filedate (int idx, time_t *t)
|
||||
|
@ -24,6 +24,8 @@ gboolean vfs_parse_fileperms (const char *s, size_t *ret_skipped,
|
||||
mode_t *ret_perms);
|
||||
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);
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user