diff -uprN a/daemon/gvfsftpdircache.c b/daemon/gvfsftpdircache.c --- a/daemon/gvfsftpdircache.c 2010-02-22 10:57:39.000000000 +0100 +++ b/daemon/gvfsftpdircache.c 2010-08-31 14:40:18.000000000 +0200 @@ -20,6 +20,9 @@ * Author: Benjamin Otte */ +#include +#include + #include #include @@ -599,6 +602,98 @@ g_vfs_ftp_dir_cache_funcs_process (GInpu g_file_info_set_is_hidden (info, result.fe_fnlen > 0 && result.fe_fname[0] == '.'); + /* If unix format then parse the attributes */ + if ( 'U' == state.lstyle) + { + char file_mode[10], uid[64], gid[64]; + + /* POSIX ls -l form: mode, links, owner, group */ + if ( 3 == sscanf( line, "%10c %*u %63s %63s", file_mode, uid, gid)) + { + GFileType file_type; + guint32 mode; + + /* File type */ + switch ( file_mode[0]) + { + case '-': /* Regular file */ + mode = S_IFREG; + file_type = G_FILE_TYPE_REGULAR; + break; + case 'b': /* Block special file */ + mode = S_IFBLK; + file_type = G_FILE_TYPE_SPECIAL; + break; + case 'c': /* Character special */ + mode = S_IFCHR; + file_type = G_FILE_TYPE_SPECIAL; + break; + case 'd': /* Directory */ + mode = S_IFDIR; + file_type = G_FILE_TYPE_DIRECTORY; + break; + case 'l': /* Symbolic link */ + mode = S_IFLNK; + file_type = G_FILE_TYPE_SYMBOLIC_LINK; + break; + case 'p': /* FIFO */ + mode = S_IFIFO; + file_type = G_FILE_TYPE_SPECIAL; + break; + default: + g_debug ("file_type: unknown (%c)\n", file_mode[0]); + mode = 0; + file_type = G_FILE_TYPE_UNKNOWN; + break; + } + g_file_info_set_file_type (info, file_type); + + /* Permissions */ + if ( 'r' == file_mode[1]) + mode |= S_IRUSR; + if ( 'w' == file_mode[2]) + mode |= S_IWUSR; + switch ( file_mode[3]) + { + case 'x': mode |= S_IXUSR; break; + case 'S': mode |= S_ISUID; break; + case 's': mode |= S_ISUID | S_IXUSR; break; + } + + if ( 'r' == file_mode[4]) + mode |= S_IRGRP; + if ( 'w' == file_mode[5]) + mode |= S_IWGRP; + switch ( file_mode[6]) + { + case 'x': mode |= S_IXGRP; break; + case 'S': mode |= S_ISGID; break; + case 's': mode |= S_ISGID | S_IXGRP; break; + } + + if ( 'r' == file_mode[7]) + mode |= S_IROTH; + if ( 'w' == file_mode[8]) + mode |= S_IWOTH; + switch ( file_mode[9]) + { + case 'x': mode |= S_IXOTH; break; + case 'T': mode |= S_ISVTX; break; + case 't': mode |= S_ISVTX | S_IXOTH; break; + } + + if ( mode) + g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, mode); + else + g_debug ("# unknown file_mode: %.10s\n", file_mode); + + g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER, uid); + g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP, gid); + } + else + g_debug ("# unknown listing format\n"); + } + /* Workaround: * result.fetime.tm_year contains actual year instead of offset-from-1900, * which mktime expects.