X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fglocalfileinfo.c;h=7c46837cee5689294bbc76cadb109b3b1e965b06;hb=7a1aaaa1fa02679ecf335a19fffe3f55505921b5;hp=af4fc43aa522b0ad7206d9378f0c2250f47414b8;hpb=6e64ba58b90d1d834a6b5f61acec6755e4b80072;p=platform%2Fupstream%2Fglib.git diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index af4fc43..7c46837 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -15,30 +15,25 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: Alexander Larsson */ #include "config.h" +#include + #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include -#ifdef HAVE_UNISTD_H -#include -#endif #include #include -#ifdef HAVE_GRP_H +#ifdef G_OS_UNIX #include -#endif -#ifdef HAVE_PWD_H #include #endif #ifdef HAVE_SELINUX @@ -62,7 +57,13 @@ #include #include -#include "glibintl.h" +#ifdef G_OS_UNIX +#include +#include "glib-unix.h" +#include "glib-private.h" +#endif + +#include "thumbnail-verify.h" #ifdef G_OS_WIN32 #include @@ -91,6 +92,7 @@ #include "gioerror.h" #include "gthemedicon.h" #include "gcontenttypeprivate.h" +#include "glibintl.h" struct ThumbMD5Context { @@ -660,6 +662,7 @@ get_xattrs_from_fd (int fd, g_free (escaped_attr); get_one_xattr_from_fd (fd, info, gio_attr, attr); + g_free (gio_attr); } len = strlen (attr) + 1; @@ -1094,6 +1097,7 @@ lookup_uid_data (uid_t uid) if (pwbufp->pw_name != NULL && pwbufp->pw_name[0] != 0) data->user_name = convert_pwd_string_to_utf8 (pwbufp->pw_name); +#ifndef __BIONIC__ gecos = pwbufp->pw_gecos; if (gecos) @@ -1103,6 +1107,7 @@ lookup_uid_data (uid_t uid) *comma = 0; data->real_name = convert_pwd_string_to_utf8 (gecos); } +#endif } /* Default fallbacks */ @@ -1257,7 +1262,7 @@ get_content_type (const char *basename, ssize_t res; res = read (fd, sniff_buffer, sniff_length); - close (fd); + (void) g_close (fd, NULL); if (res >= 0) { g_free (content_type); @@ -1272,9 +1277,11 @@ get_content_type (const char *basename, } +/* @stat_buf is the pre-calculated result of stat(path), or %NULL if that failed. */ static void -get_thumbnail_attributes (const char *path, - GFileInfo *info) +get_thumbnail_attributes (const char *path, + GFileInfo *info, + const GLocalFileStat *stat_buf) { GChecksum *checksum; char *uri; @@ -1285,32 +1292,53 @@ get_thumbnail_attributes (const char *path, checksum = g_checksum_new (G_CHECKSUM_MD5); g_checksum_update (checksum, (const guchar *) uri, strlen (uri)); - - g_free (uri); basename = g_strconcat (g_checksum_get_string (checksum), ".png", NULL); g_checksum_free (checksum); filename = g_build_filename (g_get_user_cache_dir (), - "thumbnails", "normal", basename, + "thumbnails", "large", basename, NULL); if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) - _g_file_info_set_attribute_byte_string_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH, filename); + { + _g_file_info_set_attribute_byte_string_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH, filename); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID, + thumbnail_verify (filename, uri, stat_buf)); + } else { g_free (filename); filename = g_build_filename (g_get_user_cache_dir (), - "thumbnails", "fail", - "gnome-thumbnail-factory", - basename, + "thumbnails", "normal", basename, NULL); if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) - _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAILING_FAILED, TRUE); + { + _g_file_info_set_attribute_byte_string_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH, filename); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID, + thumbnail_verify (filename, uri, stat_buf)); + } + else + { + g_free (filename); + filename = g_build_filename (g_get_user_cache_dir (), + "thumbnails", "fail", + "gnome-thumbnail-factory", + basename, + NULL); + + if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + { + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAILING_FAILED, TRUE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID, + thumbnail_verify (filename, uri, stat_buf)); + } + } } g_free (basename); g_free (filename); + g_free (uri); } #ifdef G_OS_WIN32 @@ -1405,6 +1433,109 @@ win32_get_file_user_info (const gchar *filename, } #endif /* G_OS_WIN32 */ +#ifndef G_OS_WIN32 +/* support for '.hidden' files */ +G_LOCK_DEFINE_STATIC (hidden_cache); +static GHashTable *hidden_cache; + +static gboolean +remove_from_hidden_cache (gpointer user_data) +{ + G_LOCK (hidden_cache); + g_hash_table_remove (hidden_cache, user_data); + G_UNLOCK (hidden_cache); + + return FALSE; +} + +static GHashTable * +read_hidden_file (const gchar *dirname) +{ + gchar *contents = NULL; + gchar *filename; + + filename = g_build_path ("/", dirname, ".hidden", NULL); + (void) g_file_get_contents (filename, &contents, NULL, NULL); + g_free (filename); + + if (contents != NULL) + { + GHashTable *table; + gchar **lines; + gint i; + + table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + lines = g_strsplit (contents, "\n", 0); + g_free (contents); + + for (i = 0; lines[i]; i++) + /* hash table takes the individual strings... */ + g_hash_table_add (table, lines[i]); + + /* ... so we only free the container. */ + g_free (lines); + + return table; + } + else + return NULL; +} + +static void +maybe_unref_hash_table (gpointer data) +{ + if (data != NULL) + g_hash_table_unref (data); +} + +static gboolean +file_is_hidden (const gchar *path, + const gchar *basename) +{ + gboolean result; + gchar *dirname; + gpointer table; + + dirname = g_path_get_dirname (path); + + G_LOCK (hidden_cache); + + if G_UNLIKELY (hidden_cache == NULL) + hidden_cache = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, maybe_unref_hash_table); + + if (!g_hash_table_lookup_extended (hidden_cache, dirname, + NULL, &table)) + { + gchar *mydirname; + GSource *remove_from_cache_source; + + g_hash_table_insert (hidden_cache, + mydirname = g_strdup (dirname), + table = read_hidden_file (dirname)); + + remove_from_cache_source = g_timeout_source_new_seconds (5); + g_source_set_priority (remove_from_cache_source, G_PRIORITY_DEFAULT); + g_source_set_callback (remove_from_cache_source, + remove_from_hidden_cache, + mydirname, + NULL); + g_source_attach (remove_from_cache_source, + GLIB_PRIVATE_CALL (g_get_worker_context) ()); + g_source_unref (remove_from_cache_source); + } + + result = table != NULL && g_hash_table_contains (table, basename); + + G_UNLOCK (hidden_cache); + + g_free (dirname); + + return result; +} +#endif /* !G_OS_WIN32 */ + void _g_local_file_info_get_nostat (GFileInfo *info, const char *basename, @@ -1448,6 +1579,96 @@ _g_local_file_info_get_nostat (GFileInfo *info, } } +static const char * +get_icon_name (const char *path, + const char *content_type, + gboolean use_symbolic, + gboolean *with_fallbacks_out) +{ + const char *name = NULL; + gboolean with_fallbacks = TRUE; + + if (strcmp (path, g_get_home_dir ()) == 0) + { + name = use_symbolic ? "user-home-symbolic" : "user-home"; + with_fallbacks = FALSE; + } + else if (strcmp (path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) == 0) + { + name = use_symbolic ? "user-desktop-symbolic" : "user-desktop"; + with_fallbacks = FALSE; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)) == 0) + { + name = use_symbolic ? "folder-documents-symbolic" : "folder-documents"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)) == 0) + { + name = use_symbolic ? "folder-download-symbolic" : "folder-download"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_MUSIC)) == 0) + { + name = use_symbolic ? "folder-music-symbolic" : "folder-music"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PICTURES)) == 0) + { + name = use_symbolic ? "folder-pictures-symbolic" : "folder-pictures"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE)) == 0) + { + name = use_symbolic ? "folder-publicshare-symbolic" : "folder-publicshare"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES)) == 0) + { + name = use_symbolic ? "folder-templates-symbolic" : "folder-templates"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS)) == 0) + { + name = use_symbolic ? "folder-videos-symbolic" : "folder-videos"; + } + else if (g_strcmp0 (content_type, "inode/directory") == 0) + { + name = use_symbolic ? "folder-symbolic" : "folder"; + } + else + { + name = NULL; + } + + if (with_fallbacks_out != NULL) + *with_fallbacks_out = with_fallbacks; + + return name; +} + +static GIcon * +get_icon (const char *path, + const char *content_type, + gboolean use_symbolic) +{ + GIcon *icon = NULL; + const char *icon_name; + gboolean with_fallbacks; + + icon_name = get_icon_name (path, content_type, use_symbolic, &with_fallbacks); + if (icon_name != NULL) + { + if (with_fallbacks) + icon = g_themed_icon_new_with_default_fallbacks (icon_name); + else + icon = g_themed_icon_new (icon_name); + } + else + { + if (use_symbolic) + icon = g_content_type_get_symbolic_icon (content_type); + else + icon = g_content_type_get_icon (content_type); + } + + return icon; +} + GFileInfo * _g_local_file_info_get (const char *basename, const char *path, @@ -1569,9 +1790,20 @@ _g_local_file_info_get (const char *basename, if (stat_ok) set_info_from_stat (info, &statbuf, attribute_matcher); -#ifndef G_OS_WIN32 - if (basename != NULL && basename[0] == '.') +#ifdef G_OS_UNIX + if (stat_ok && _g_local_file_is_lost_found_dir (path, statbuf.st_dev)) g_file_info_set_is_hidden (info, TRUE); +#endif + +#ifndef G_OS_WIN32 + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_IS_HIDDEN)) + { + if (basename != NULL && + (basename[0] == '.' || + file_is_hidden (path, basename))) + g_file_info_set_is_hidden (info, TRUE); + } if (basename != NULL && basename[strlen (basename) -1] == '~' && (stat_ok && S_ISREG (statbuf.st_mode))) @@ -1601,7 +1833,9 @@ _g_local_file_info_get (const char *basename, if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE) || _g_file_attribute_matcher_matches_id (attribute_matcher, - G_FILE_ATTRIBUTE_ID_STANDARD_ICON)) + G_FILE_ATTRIBUTE_ID_STANDARD_ICON) || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON)) { char *content_type = get_content_type (basename, path, stat_ok ? &statbuf : NULL, is_symlink, symlink_broken, flags, FALSE); @@ -1610,47 +1844,28 @@ _g_local_file_info_get (const char *basename, g_file_info_set_content_type (info, content_type); if (_g_file_attribute_matcher_matches_id (attribute_matcher, - G_FILE_ATTRIBUTE_ID_STANDARD_ICON)) + G_FILE_ATTRIBUTE_ID_STANDARD_ICON) + || _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON)) { GIcon *icon; - if (strcmp (path, g_get_home_dir ()) == 0) - icon = g_themed_icon_new ("user-home"); - else if (strcmp (path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) == 0) - icon = g_themed_icon_new ("user-desktop"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-documents"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-download"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_MUSIC)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-music"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PICTURES)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-pictures"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-publicshare"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-templates"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-videos"); - else + /* non symbolic icon */ + icon = get_icon (path, content_type, FALSE); + if (icon != NULL) { - icon = g_content_type_get_icon (content_type); - if (G_IS_THEMED_ICON (icon)) - { - const char *type_icon = NULL; - - if (S_ISDIR (statbuf.st_mode)) - type_icon = "folder"; - if (type_icon) - g_themed_icon_append_name (G_THEMED_ICON (icon), type_icon); - } + g_file_info_set_icon (info, icon); + g_object_unref (icon); } + /* symbolic icon */ + icon = get_icon (path, content_type, TRUE); if (icon != NULL) { - g_file_info_set_icon (info, icon); + g_file_info_set_symbolic_icon (info, icon); g_object_unref (icon); } + } g_free (content_type); @@ -1731,7 +1946,12 @@ _g_local_file_info_get (const char *basename, if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH)) - get_thumbnail_attributes (path, info); + { + if (stat_ok) + get_thumbnail_attributes (path, info, &statbuf); + else + get_thumbnail_attributes (path, info, NULL); + } vfs = g_vfs_get_default (); class = G_VFS_GET_CLASS (vfs); @@ -1934,7 +2154,7 @@ set_unix_mode (char *filename, return TRUE; } -#ifdef HAVE_CHOWN +#ifdef G_OS_UNIX static gboolean set_unix_uid_gid (char *filename, const GFileAttributeValue *uid_value, @@ -2218,7 +2438,7 @@ _g_local_file_info_set_attribute (char *filename, if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0) return set_unix_mode (filename, flags, &value, error); -#ifdef HAVE_CHOWN +#ifdef G_OS_UNIX else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0) return set_unix_uid_gid (filename, &value, NULL, flags, error); else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_GID) == 0) @@ -2295,13 +2515,11 @@ _g_local_file_info_set_attributes (char *filename, GError **error) { GFileAttributeValue *value; -#ifdef HAVE_CHOWN +#ifdef G_OS_UNIX GFileAttributeValue *uid, *gid; -#endif #ifdef HAVE_UTIMES GFileAttributeValue *mtime, *mtime_usec, *atime, *atime_usec; #endif -#if defined (HAVE_CHOWN) || defined (HAVE_UTIMES) GFileAttributeStatus status; #endif gboolean res; @@ -2331,7 +2549,7 @@ _g_local_file_info_set_attributes (char *filename, } #endif -#ifdef HAVE_CHOWN +#ifdef G_OS_UNIX /* Group uid and gid setting into one call * Change ownership before permissions, since ownership changes can change permissions (e.g. setuid)