doc: improve doc of g_file_equal()
[platform/upstream/glib.git] / gio / glocalfileinfo.c
index 6dfd75f..71ba728 100644 (file)
  * 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 <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Larsson <alexl@redhat.com>
  */
 
 #include "config.h"
 
+#include <glib.h>
+
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #include <fcntl.h>
 #include <errno.h>
-#ifdef HAVE_GRP_H
+#ifdef G_OS_UNIX
 #include <grp.h>
-#endif
-#ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
 #ifdef HAVE_SELINUX
 #include <gfileinfo-priv.h>
 #include <gvfs.h>
 
-#ifndef G_OS_WIN32
+#ifdef G_OS_UNIX
+#include <unistd.h>
+#include "glib-unix.h"
 #include "glib-private.h"
 #endif
-#include "glibintl.h"
+
+#include "thumbnail-verify.h"
 
 #ifdef G_OS_WIN32
 #include <windows.h>
@@ -94,6 +92,7 @@
 #include "gioerror.h"
 #include "gthemedicon.h"
 #include "gcontenttypeprivate.h"
+#include "glibintl.h"
 
 
 struct ThumbMD5Context {
@@ -663,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;
@@ -1097,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)
@@ -1106,6 +1107,7 @@ lookup_uid_data (uid_t uid)
            *comma = 0;
          data->real_name = convert_pwd_string_to_utf8 (gecos);
        }
+#endif
     }
 
   /* Default fallbacks */
@@ -1260,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);
@@ -1275,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;
@@ -1288,8 +1292,6 @@ 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);
@@ -1299,7 +1301,11 @@ get_thumbnail_attributes (const char *path,
                                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);
@@ -1308,7 +1314,11 @@ get_thumbnail_attributes (const char *path,
                                    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);
@@ -1319,11 +1329,16 @@ get_thumbnail_attributes (const char *path,
                                        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_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
@@ -1436,35 +1451,30 @@ remove_from_hidden_cache (gpointer user_data)
 static GHashTable *
 read_hidden_file (const gchar *dirname)
 {
+  gchar *contents = NULL;
   gchar *filename;
-  FILE *hidden;
 
   filename = g_build_path ("/", dirname, ".hidden", NULL);
-  hidden = fopen (filename, "r");
+  g_file_get_contents (filename, &contents, NULL, NULL);
   g_free (filename);
 
-  if (hidden != NULL)
+  if (contents != NULL)
     {
-      gchar buffer[PATH_MAX + 2]; /* \n\0 */
       GHashTable *table;
+      gchar **lines;
+      gint i;
 
       table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
-      while (fgets (buffer, sizeof buffer, hidden))
-        {
-          gchar *newline;
-
-          if ((newline = strchr (buffer, '\n')) != NULL)
-            {
-              *newline++ = '\0';
+      lines = g_strsplit (contents, "\n", 0);
+      g_free (contents);
 
-              g_hash_table_insert (table,
-                                   g_memdup (buffer, newline - buffer),
-                                   GINT_TO_POINTER (TRUE));
-            }
-        }
+      for (i = 0; lines[i]; i++)
+        /* hash table takes the individual strings... */
+        g_hash_table_add (table, lines[i]);
 
-      fclose (hidden);
+      /* ... so we only free the container. */
+      g_free (lines);
 
       return table;
     }
@@ -1516,8 +1526,7 @@ file_is_hidden (const gchar *path,
       g_source_unref (remove_from_cache_source);
     }
 
-  result = table != NULL &&
-           GPOINTER_TO_INT (g_hash_table_lookup (table, basename));
+  result = table != NULL && g_hash_table_contains (table, basename);
 
   G_UNLOCK (hidden_cache);
 
@@ -1572,6 +1581,7 @@ _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)
 {
@@ -1616,6 +1626,10 @@ get_icon_name (const char *path,
     {
       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;
@@ -1630,14 +1644,13 @@ get_icon_name (const char *path,
 static GIcon *
 get_icon (const char *path,
           const char *content_type,
-          gboolean    is_folder,
           gboolean    use_symbolic)
 {
   GIcon *icon = NULL;
   const char *icon_name;
   gboolean with_fallbacks;
 
-  icon_name = get_icon_name (path, use_symbolic, &with_fallbacks);
+  icon_name = get_icon_name (path, content_type, use_symbolic, &with_fallbacks);
   if (icon_name != NULL)
     {
       if (with_fallbacks)
@@ -1651,11 +1664,6 @@ get_icon (const char *path,
         icon = g_content_type_get_symbolic_icon (content_type);
       else
         icon = g_content_type_get_icon (content_type);
-
-      if (G_IS_THEMED_ICON (icon) && is_folder)
-        {
-          g_themed_icon_append_name (G_THEMED_ICON (icon), use_symbolic ? "folder-symbolic" : "folder");
-        }
     }
 
   return icon;
@@ -1782,11 +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] == '.' ||
-       file_is_hidden (path, basename)))
+#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)))
@@ -1834,7 +1851,7 @@ _g_local_file_info_get (const char             *basename,
              GIcon *icon;
 
               /* non symbolic icon */
-              icon = get_icon (path, content_type, S_ISDIR (statbuf.st_mode), FALSE);
+              icon = get_icon (path, content_type, FALSE);
               if (icon != NULL)
                 {
                   g_file_info_set_icon (info, icon);
@@ -1842,7 +1859,7 @@ _g_local_file_info_get (const char             *basename,
                 }
 
               /* symbolic icon */
-              icon = get_icon (path, content_type, S_ISDIR (statbuf.st_mode), TRUE);
+              icon = get_icon (path, content_type, TRUE);
               if (icon != NULL)
                 {
                   g_file_info_set_symbolic_icon (info, icon);
@@ -1929,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);
@@ -2132,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,
@@ -2416,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)
@@ -2493,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;
@@ -2529,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)