[Xfce4-commits] r29758 - in thunar/branches/migration-to-gio: . thunar

Jannis Pohlmann jannis at xfce.org
Sat Apr 11 00:00:48 CEST 2009


Author: jannis
Date: 2009-04-10 22:00:47 +0000 (Fri, 10 Apr 2009)
New Revision: 29758

Added:
   thunar/branches/migration-to-gio/thunar/thunar-user.c
   thunar/branches/migration-to-gio/thunar/thunar-user.h
Modified:
   thunar/branches/migration-to-gio/ChangeLog
   thunar/branches/migration-to-gio/thunar/Makefile.am
   thunar/branches/migration-to-gio/thunar/thunar-file.c
   thunar/branches/migration-to-gio/thunar/thunar-file.h
   thunar/branches/migration-to-gio/thunar/thunar-list-model.c
   thunar/branches/migration-to-gio/thunar/thunar-permissions-chooser.c
Log:
	* thunar/Makefile.am, thunar/thunar-file.{c,h},
	  thunar/thunar-list-model.c, thunar/thunar-permissions-chooser.c,
	  thunar/thunar-user.{c,h}: Move ThunarVfsUserManager, ThunarVfsUser
	  and ThunarVfsGroup into Thunar, renaming them to ThunarUserManager,
	  ThunarUser and ThunarGroup. Update the Thunar code to reflect this
	  change.

Modified: thunar/branches/migration-to-gio/ChangeLog
===================================================================
--- thunar/branches/migration-to-gio/ChangeLog	2009-04-10 21:14:07 UTC (rev 29757)
+++ thunar/branches/migration-to-gio/ChangeLog	2009-04-10 22:00:47 UTC (rev 29758)
@@ -1,5 +1,14 @@
 2009-04-10	Jannis Pohlmann <jannis at xfce.org>
 
+	* thunar/Makefile.am, thunar/thunar-file.{c,h},
+	  thunar/thunar-list-model.c, thunar/thunar-permissions-chooser.c, 
+	  thunar/thunar-user.{c,h}: Move ThunarVfsUserManager, ThunarVfsUser
+	  and ThunarVfsGroup into Thunar, renaming them to ThunarUserManager,
+	  ThunarUser and ThunarGroup. Update the Thunar code to reflect this
+	  change.
+
+2009-04-10	Jannis Pohlmann <jannis at xfce.org>
+
 	* thunar/thunar-file.{c,h}: Use GFile in thunar_file_atexit_foreach().
 	  When finalizing, creating or loading a ThunarFile, check whether the
 	  GFileInfo is NULL before unref'ing it. Use the GFile member instead

Modified: thunar/branches/migration-to-gio/thunar/Makefile.am
===================================================================
--- thunar/branches/migration-to-gio/thunar/Makefile.am	2009-04-10 21:14:07 UTC (rev 29757)
+++ thunar/branches/migration-to-gio/thunar/Makefile.am	2009-04-10 22:00:47 UTC (rev 29758)
@@ -182,6 +182,8 @@
 	thunar-tree-pane.h						\
 	thunar-tree-view.c						\
 	thunar-tree-view.h						\
+	thunar-user.c							\
+	thunar-user.h							\
 	thunar-util.c							\
 	thunar-util.h							\
 	thunar-view.c							\

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-04-10 21:14:07 UTC (rev 29757)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-04-10 22:00:47 UTC (rev 29758)
@@ -53,6 +53,7 @@
 #include <thunar/thunar-gio-extensions.h>
 #include <thunar/thunar-gobject-extensions.h>
 #include <thunar/thunar-private.h>
+#include <thunar/thunar-user.h>
 #include <thunar/thunar-util.h>
 
 
@@ -122,17 +123,17 @@
 
 
 
-static ThunarVfsUserManager *user_manager;
-static ThunarVfsMonitor     *monitor;
-static ThunarVfsUserId       effective_user_id;
-static ThunarMetafile       *metafile;
-static GObjectClass         *thunar_file_parent_class;
-static GHashTable           *file_cache;
-static GQuark                thunar_file_thumb_path_quark;
-static GQuark                thunar_file_watch_count_quark;
-static GQuark                thunar_file_watch_handle_quark;
-static GQuark                thunar_file_emblem_names_quark;
-static guint                 file_signals[LAST_SIGNAL];
+static ThunarUserManager *user_manager;
+static ThunarVfsMonitor  *monitor;
+static guint32            effective_user_id;
+static ThunarMetafile    *metafile;
+static GObjectClass      *thunar_file_parent_class;
+static GHashTable        *file_cache;
+static GQuark             thunar_file_thumb_path_quark;
+static GQuark             thunar_file_watch_count_quark;
+static GQuark             thunar_file_watch_handle_quark;
+static GQuark             thunar_file_emblem_names_quark;
+static guint              file_signals[LAST_SIGNAL];
 
 
 
@@ -228,7 +229,7 @@
   thunar_file_parent_class = g_type_class_peek_parent (klass);
 
   /* grab a reference on the user manager */
-  user_manager = thunar_vfs_user_manager_get_default ();
+  user_manager = thunar_user_manager_get_default ();
 
   /* determine the effective user id of the process */
   effective_user_id = geteuid ();
@@ -455,8 +456,8 @@
                                       ThunarVfsFileMode oth_permissions)
 {
   ThunarVfsFileMode mode;
-  ThunarVfsGroup   *group;
-  ThunarVfsUser    *user;
+  ThunarGroup   *group;
+  ThunarUser    *user;
   gboolean          result;
   GList            *groups;
   GList            *lp;
@@ -476,7 +477,7 @@
   if (G_UNLIKELY (effective_user_id == 0))
     return FALSE;
 
-  if (thunar_vfs_user_is_me (user))
+  if (thunar_user_is_me (user))
     {
       /* we're the owner, so the usr permissions must be granted */
       result = ((mode & usr_permissions) == 0);
@@ -493,13 +494,13 @@
           g_object_unref (G_OBJECT (user));
 
           /* determine the effective user */
-          user = thunar_vfs_user_manager_get_user_by_id (user_manager, effective_user_id);
+          user = thunar_user_manager_get_user_by_id (user_manager, effective_user_id);
           if (G_LIKELY (user != NULL))
             {
               /* check the group permissions */
-              groups = thunar_vfs_user_get_groups (user);
+              groups = thunar_user_get_groups (user);
               for (lp = groups; lp != NULL; lp = lp->next)
-                if (THUNAR_VFS_GROUP (lp->data) == group)
+                if (THUNAR_GROUP (lp->data) == group)
                   {
                     g_object_unref (G_OBJECT (user));
                     g_object_unref (G_OBJECT (group));
@@ -1360,20 +1361,20 @@
  * thunar_file_get_group:
  * @file : a #ThunarFile instance.
  *
- * Determines the #ThunarVfsGroup for @file. If there's no
+ * Determines the #ThunarGroup for @file. If there's no
  * group associated with @file or if the system is unable to
  * determine the group, %NULL will be returned.
  *
  * The caller is responsible for freeing the returned object
  * using g_object_unref().
  *
- * Return value: the #ThunarVfsGroup for @file or %NULL.
+ * Return value: the #ThunarGroup for @file or %NULL.
  **/
-ThunarVfsGroup*
+ThunarGroup*
 thunar_file_get_group (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  return thunar_vfs_user_manager_get_group_by_id (user_manager, file->info->gid);
+  return thunar_user_manager_get_group_by_id (user_manager, file->info->gid);
 }
 
 
@@ -1382,20 +1383,20 @@
  * thunar_file_get_user:
  * @file : a #ThunarFile instance.
  *
- * Determines the #ThunarVfsUser for @file. If there's no
+ * Determines the #ThunarUser for @file. If there's no
  * user associated with @file or if the system is unable
  * to determine the user, %NULL will be returned.
  *
  * The caller is responsible for freeing the returned object
  * using g_object_unref().
  *
- * Return value: the #ThunarVfsUser for @file or %NULL.
+ * Return value: the #ThunarUser for @file or %NULL.
  **/
-ThunarVfsUser*
+ThunarUser*
 thunar_file_get_user (const ThunarFile *file)
 {
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
-  return thunar_vfs_user_manager_get_user_by_id (user_manager, file->info->uid);
+  return thunar_user_manager_get_user_by_id (user_manager, file->info->uid);
 }
 
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.h	2009-04-10 21:14:07 UTC (rev 29757)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.h	2009-04-10 22:00:47 UTC (rev 29758)
@@ -22,6 +22,7 @@
 
 #include <thunar/thunar-enum-types.h>
 #include <thunar/thunar-metafile.h>
+#include <thunar/thunar-user.h>
 #include <thunarx/thunarx.h>
 
 #include <glib.h>
@@ -161,8 +162,8 @@
 ThunarVfsVolume  *thunar_file_get_volume           (const ThunarFile       *file,
                                                     ThunarVfsVolumeManager *volume_manager);
 
-ThunarVfsGroup   *thunar_file_get_group            (const ThunarFile       *file);
-ThunarVfsUser    *thunar_file_get_user             (const ThunarFile       *file);
+ThunarGroup      *thunar_file_get_group            (const ThunarFile       *file);
+ThunarUser       *thunar_file_get_user             (const ThunarFile       *file);
 
 gchar            *thunar_file_get_deletion_date    (const ThunarFile       *file,
                                                     ThunarDateStyle         date_style) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;

Modified: thunar/branches/migration-to-gio/thunar/thunar-list-model.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-list-model.c	2009-04-10 21:14:07 UTC (rev 29757)
+++ thunar/branches/migration-to-gio/thunar/thunar-list-model.c	2009-04-10 22:00:47 UTC (rev 29758)
@@ -32,6 +32,7 @@
 #include <thunar/thunar-gobject-extensions.h>
 #include <thunar/thunar-list-model.h>
 #include <thunar/thunar-private.h>
+#include <thunar/thunar-user.h>
 
 
 
@@ -698,8 +699,8 @@
                              GValue       *value)
 {
   ThunarVfsMimeInfo *mime_info;
-  ThunarVfsGroup    *group;
-  ThunarVfsUser     *user;
+  ThunarGroup       *group;
+  ThunarUser        *user;
   const gchar       *name;
   const gchar       *real_name;
   ThunarFile        *file;
@@ -729,7 +730,7 @@
       group = thunar_file_get_group (file);
       if (G_LIKELY (group != NULL))
         {
-          g_value_set_string (value, thunar_vfs_group_get_name (group));
+          g_value_set_string (value, thunar_group_get_name (group));
           g_object_unref (G_OBJECT (group));
         }
       else
@@ -755,8 +756,8 @@
       if (G_LIKELY (user != NULL))
         {
           /* determine sane display name for the owner */
-          name = thunar_vfs_user_get_name (user);
-          real_name = thunar_vfs_user_get_real_name (user);
+          name = thunar_user_get_name (user);
+          real_name = thunar_user_get_real_name (user);
           str = G_LIKELY (real_name != NULL) ? g_strdup_printf ("%s (%s)", real_name, name) : g_strdup (name);
           g_value_take_string (value, str);
           g_object_unref (G_OBJECT (user));

Modified: thunar/branches/migration-to-gio/thunar/thunar-permissions-chooser.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-permissions-chooser.c	2009-04-10 21:14:07 UTC (rev 29757)
+++ thunar/branches/migration-to-gio/thunar/thunar-permissions-chooser.c	2009-04-10 22:00:47 UTC (rev 29758)
@@ -39,6 +39,7 @@
 #include <thunar/thunar-permissions-chooser.h>
 #include <thunar/thunar-preferences.h>
 #include <thunar/thunar-private.h>
+#include <thunar/thunar-user.h>
 
 
 
@@ -80,7 +81,7 @@
                                                                          GParamSpec                     *pspec);
 static gint                 thunar_permissions_chooser_ask_recursive    (ThunarPermissionsChooser       *chooser);
 static void                 thunar_permissions_chooser_change_group     (ThunarPermissionsChooser       *chooser,
-                                                                         ThunarVfsGroupId                gid);
+                                                                         guint32                         gid);
 static void                 thunar_permissions_chooser_change_mode      (ThunarPermissionsChooser       *chooser,
                                                                          ThunarVfsFileMode               dir_mask,
                                                                          ThunarVfsFileMode               dir_mode,
@@ -628,7 +629,7 @@
 
 static void
 thunar_permissions_chooser_change_group (ThunarPermissionsChooser *chooser,
-                                         ThunarVfsGroupId          gid)
+                                         guint32                   gid)
 {
   ThunarVfsJob *job;
   gboolean      recursive = FALSE;
@@ -771,9 +772,9 @@
                gconstpointer group_b,
                gpointer      group_primary)
 {
-  ThunarVfsGroupId group_primary_id = thunar_vfs_group_get_id (THUNAR_VFS_GROUP (group_primary));
-  ThunarVfsGroupId group_a_id = thunar_vfs_group_get_id (THUNAR_VFS_GROUP (group_a));
-  ThunarVfsGroupId group_b_id = thunar_vfs_group_get_id (THUNAR_VFS_GROUP (group_b));
+  guint32 group_primary_id = thunar_group_get_id (THUNAR_GROUP (group_primary));
+  guint32 group_a_id = thunar_group_get_id (THUNAR_GROUP (group_a));
+  guint32 group_b_id = thunar_group_get_id (THUNAR_GROUP (group_b));
 
   /* check if the groups are equal */
   if (group_a_id == group_b_id)
@@ -792,7 +793,8 @@
     return -1;
 
   /* otherwise just sort by name */
-  return g_ascii_strcasecmp (thunar_vfs_group_get_name (THUNAR_VFS_GROUP (group_a)), thunar_vfs_group_get_name (THUNAR_VFS_GROUP (group_b)));
+  return g_ascii_strcasecmp (thunar_group_get_name (THUNAR_GROUP (group_a)), 
+                             thunar_group_get_name (THUNAR_GROUP (group_b)));
 }
 
 
@@ -801,18 +803,18 @@
 thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser,
                                          ThunarFile               *file)
 {
-  ThunarVfsUserManager *user_manager;
-  ThunarVfsFileMode     mode;
-  ThunarVfsGroup       *group;
-  ThunarVfsUser        *user;
-  GtkListStore         *store;
-  GtkTreeIter           iter;
-  const gchar          *user_name;
-  const gchar          *real_name;
-  GList                *groups;
-  GList                *lp;
-  gchar                 buffer[1024];
-  guint                 n;
+  ThunarUserManager *user_manager;
+  ThunarVfsFileMode  mode;
+  ThunarGroup       *group;
+  ThunarUser        *user;
+  GtkListStore      *store;
+  GtkTreeIter        iter;
+  const gchar       *user_name;
+  const gchar       *real_name;
+  GList             *groups;
+  GList             *lp;
+  gchar              buffer[1024];
+  guint              n;
 
   _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser));
   _thunar_return_if_fail (THUNAR_IS_FILE (file));
@@ -835,14 +837,14 @@
           if (G_UNLIKELY (geteuid () == 0))
             {
               /* determine all groups in the system */
-              user_manager = thunar_vfs_user_manager_get_default ();
-              groups = thunar_vfs_user_manager_get_all_groups (user_manager);
+              user_manager = thunar_user_manager_get_default ();
+              groups = thunar_user_manager_get_all_groups (user_manager);
               g_object_unref (G_OBJECT (user_manager));
             }
           else
             {
               /* determine the groups for the user and take a copy */
-              groups = g_list_copy (thunar_vfs_user_get_groups (user));
+              groups = g_list_copy (thunar_user_get_groups (user));
               g_list_foreach (groups, (GFunc) g_object_ref, NULL);
             }
 
@@ -857,12 +859,13 @@
           for (lp = groups, n = 0; lp != NULL; lp = lp->next)
             {
               /* append a separator after the primary group and after the user-groups (not system groups) */
-              if (thunar_vfs_group_get_id (groups->data) == thunar_vfs_group_get_id (group) && lp != groups && n == 0)
+              if (thunar_group_get_id (groups->data) == thunar_group_get_id (group) 
+                  && lp != groups && n == 0)
                 {
                   gtk_list_store_append (store, &iter);
                   n += 1;
                 }
-              else if (lp != groups && thunar_vfs_group_get_id (lp->data) < 100 && n == 1)
+              else if (lp != groups && thunar_group_get_id (lp->data) < 100 && n == 1)
                 {
                   gtk_list_store_append (store, &iter);
                   n += 1;
@@ -871,8 +874,8 @@
               /* append a new item for the group */
               gtk_list_store_append (store, &iter);
               gtk_list_store_set (store, &iter,
-                                  THUNAR_PERMISSIONS_STORE_COLUMN_NAME, thunar_vfs_group_get_name (lp->data),
-                                  THUNAR_PERMISSIONS_STORE_COLUMN_GID, thunar_vfs_group_get_id (lp->data),
+                                  THUNAR_PERMISSIONS_STORE_COLUMN_NAME, thunar_group_get_name (lp->data),
+                                  THUNAR_PERMISSIONS_STORE_COLUMN_GID, thunar_group_get_id (lp->data),
                                   -1);
 
               /* set the active iter for the combo box if this group is the primary group */
@@ -887,8 +890,8 @@
         }
 
       /* determine sane display name for the owner */
-      user_name = thunar_vfs_user_get_name (user);
-      real_name = thunar_vfs_user_get_real_name (user);
+      user_name = thunar_user_get_name (user);
+      real_name = thunar_user_get_real_name (user);
       if (G_LIKELY (real_name != NULL))
         g_snprintf (buffer, sizeof (buffer), "%s (%s)", real_name, user_name);
       else
@@ -948,9 +951,9 @@
 thunar_permissions_chooser_group_changed (ThunarPermissionsChooser *chooser,
                                           GtkWidget                *combo)
 {
-  ThunarVfsGroupId gid;
-  GtkTreeModel    *model;
-  GtkTreeIter      iter;
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  guint32       gid;
 
   _thunar_return_if_fail (THUNAR_IS_PERMISSIONS_CHOOSER (chooser));
   _thunar_return_if_fail (chooser->group_combo == combo);

Added: thunar/branches/migration-to-gio/thunar/thunar-user.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-user.c	                        (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-user.c	2009-04-10 22:00:47 UTC (rev 29758)
@@ -0,0 +1,832 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <glib-object.h>
+
+#include <exo/exo.h>
+
+#include <thunar/thunar-user.h>
+
+
+
+/* the interval in which the user/group cache is flushed (in ms) */
+#define THUNAR_USER_MANAGER_FLUSH_INTERVAL (10 * 60 * 1000)
+
+
+
+
+static void         thunar_group_class_init (ThunarGroupClass *klass);
+static void         thunar_group_finalize   (GObject          *object);
+static ThunarGroup *thunar_group_new        (guint32           id);
+
+
+
+struct _ThunarGroupClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarGroup
+{
+  GObject __parent__;
+
+  guint32 id;
+  gchar  *name;
+};
+
+
+
+static GObjectClass *thunar_group_parent_class;
+
+
+
+GType
+thunar_group_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (G_TYPE_OBJECT,
+                                            "ThunarGroup",
+                                            sizeof (ThunarGroupClass),
+                                            (GClassInitFunc) thunar_group_class_init,
+                                            sizeof (ThunarGroup),
+                                            NULL,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+thunar_group_class_init (ThunarGroupClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* determine the parent class */
+  thunar_group_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_group_finalize;
+}
+
+
+
+static void
+thunar_group_finalize (GObject *object)
+{
+  ThunarGroup *group = THUNAR_GROUP (object);
+
+  /* release the group's name */
+  g_free (group->name);
+
+  (*G_OBJECT_CLASS (thunar_group_parent_class)->finalize) (object);
+}
+
+
+
+static ThunarGroup*
+thunar_group_new (guint32 id)
+{
+  ThunarGroup *group;
+
+  group = g_object_new (THUNAR_TYPE_GROUP, NULL);
+  group->id = id;
+
+  return group;
+}
+
+
+
+/**
+ * thunar_group_get_id:
+ * @group : a #ThunarGroup.
+ *
+ * Returns the unique id of the given @group.
+ *
+ * Return value: the unique id of @group.
+ **/
+guint32
+thunar_group_get_id (ThunarGroup *group)
+{
+  g_return_val_if_fail (THUNAR_IS_GROUP (group), 0);
+  return group->id;
+}
+
+
+
+/**
+ * thunar_group_get_name:
+ * @group : a #ThunarGroup.
+ *
+ * Returns the name of the @group. If the system is
+ * unable to determine the name of @group, it'll
+ * return the group id as string.
+ *
+ * Return value: the name of @group.
+ **/
+const gchar*
+thunar_group_get_name (ThunarGroup *group)
+{
+  struct group *grp;
+
+  g_return_val_if_fail (THUNAR_IS_GROUP (group), NULL);
+
+  /* determine the name on-demand */
+  if (G_UNLIKELY (group->name == NULL))
+    {
+      grp = getgrgid (group->id);
+      if (G_LIKELY (grp != NULL))
+        group->name = g_strdup (grp->gr_name);
+      else
+        group->name = g_strdup_printf ("%u", (guint) group->id);
+    }
+
+  return group->name;
+}
+
+
+
+
+static void        thunar_user_class_init (ThunarUserClass *klass);
+static void        thunar_user_finalize   (GObject         *object);
+static void        thunar_user_load       (ThunarUser      *user);
+static ThunarUser *thunar_user_new        (guint32          id);
+
+
+
+struct _ThunarUserClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarUser
+{
+  GObject __parent__;
+
+  GList       *groups;
+  ThunarGroup *primary_group;
+  guint32      id;
+  gchar       *name;
+  gchar       *real_name;
+};
+
+
+
+static guint32       thunar_user_effective_uid;
+static GObjectClass *thunar_user_parent_class;
+
+
+
+GType
+thunar_user_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (G_TYPE_OBJECT,
+                                            "ThunarUser",
+                                            sizeof (ThunarUserClass),
+                                            (GClassInitFunc) thunar_user_class_init,
+                                            sizeof (ThunarUser),
+                                            NULL,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+thunar_user_class_init (ThunarUserClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* determine the parent class */
+  thunar_user_parent_class = g_type_class_peek_parent (klass);
+
+  /* determine the current process' effective user id, we do
+   * this only once to avoid the syscall overhead on every
+   * is_me() invokation.
+   */
+  thunar_user_effective_uid = geteuid ();
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_user_finalize;
+}
+
+
+
+static void
+thunar_user_finalize (GObject *object)
+{
+  ThunarUser *user = THUNAR_USER (object);
+
+  /* unref the associated groups */
+  g_list_foreach (user->groups, (GFunc) g_object_unref, NULL);
+  g_list_free (user->groups);
+
+  /* drop the reference on the primary group */
+  if (G_LIKELY (user->primary_group != NULL))
+    g_object_unref (G_OBJECT (user->primary_group));
+
+  /* release the names */
+  g_free (user->real_name);
+  g_free (user->name);
+
+  (*G_OBJECT_CLASS (thunar_user_parent_class)->finalize) (object);
+}
+
+
+
+static void
+thunar_user_load (ThunarUser *user)
+{
+  ThunarUserManager *manager;
+  struct passwd     *pw;
+  const gchar       *s;
+  gchar             *name;
+  gchar             *t;
+
+  g_return_if_fail (user->name == NULL);
+
+  pw = getpwuid (user->id);
+  if (G_LIKELY (pw != NULL))
+    {
+      manager = thunar_user_manager_get_default ();
+
+      /* query name and primary group */
+      user->name = g_strdup (pw->pw_name);
+      user->primary_group = thunar_user_manager_get_group_by_id (manager, pw->pw_gid);
+
+      /* try to figure out the real name */
+      s = strchr (pw->pw_gecos, ',');
+      if (s != NULL)
+        user->real_name = g_strndup (pw->pw_gecos, s - pw->pw_gecos);
+      else if (pw->pw_gecos[0] != '\0')
+        user->real_name = g_strdup (pw->pw_gecos);
+
+      /* substitute '&' in the real_name with the account name */
+      if (G_LIKELY (user->real_name != NULL && strchr (user->real_name, '&') != NULL))
+        {
+          /* generate a version of the username with the first char upper'd */
+          name = g_strdup (user->name);
+          name[0] = g_ascii_toupper (name[0]);
+
+          /* replace all occurances of '&' */
+          t = exo_str_replace (user->real_name, "&", name);
+          g_free (user->real_name);
+          user->real_name = t;
+
+          /* clean up */
+          g_free (name);
+        }
+
+      g_object_unref (G_OBJECT (manager));
+    }
+  else
+    {
+      user->name = g_strdup_printf ("%u", (guint) user->id);
+    }
+}
+
+
+
+static ThunarUser*
+thunar_user_new (guint32 id)
+{
+  ThunarUser *user;
+
+  user = g_object_new (THUNAR_TYPE_USER, NULL);
+  user->id = id;
+
+  return user;
+}
+
+
+
+/**
+ * thunar_user_get_groups:
+ * @user : a #ThunarUser.
+ *
+ * Returns all #ThunarGroup<!---->s that @user
+ * belongs to. The returned list and the #ThunarGroup<!---->s
+ * contained within the list are owned by @user and must not be
+ * freed or altered by the caller.
+ *
+ * Note that if @user has a primary group, this group will
+ * also be contained in the returned list.
+ *
+ * Return value: the groups that @user belongs to.
+ **/
+GList*
+thunar_user_get_groups (ThunarUser *user)
+{
+  ThunarUserManager *manager;
+  ThunarGroup       *primary_group;
+  ThunarGroup       *group;
+  gid_t              gidset[NGROUPS_MAX];
+  gint               gidsetlen;
+  gint               n;
+
+  g_return_val_if_fail (THUNAR_IS_USER (user), NULL);
+
+  /* load the groups on-demand */
+  if (G_UNLIKELY (user->groups == NULL))
+    {
+      primary_group = thunar_user_get_primary_group (user);
+
+      /* we can only determine the groups list for the current
+       * process owner in a portable fashion, and in fact, we
+       * only need the list for the current user.
+       */
+      if (thunar_user_is_me (user))
+        {
+          manager = thunar_user_manager_get_default ();
+
+          /* add all supplementary groups */
+          gidsetlen = getgroups (G_N_ELEMENTS (gidset), gidset);
+          for (n = 0; n < gidsetlen; ++n)
+            if (primary_group == NULL || thunar_group_get_id (primary_group) != gidset[n])
+              {
+                group = thunar_user_manager_get_group_by_id (manager, gidset[n]);
+                if (G_LIKELY (group != NULL))
+                  user->groups = g_list_append (user->groups, group);
+              }
+
+          g_object_unref (G_OBJECT (manager));
+        }
+
+      /* prepend the primary group (if any) */
+      if (G_LIKELY (primary_group != NULL))
+        {
+          user->groups = g_list_prepend (user->groups, primary_group);
+          g_object_ref (G_OBJECT (primary_group));
+        }
+    }
+
+  return user->groups;
+}
+
+
+
+/**
+ * thunar_user_get_primary_group:
+ * @user : a #ThunarUser.
+ *
+ * Returns the primary group of @user or %NULL if @user
+ * has no primary group.
+ *
+ * No reference is taken for the caller, so you must
+ * not call g_object_unref() on the returned object.
+ *
+ * Return value: the primary group of @user or %NULL.
+ **/
+ThunarGroup*
+thunar_user_get_primary_group (ThunarUser *user)
+{
+  g_return_val_if_fail (THUNAR_IS_USER (user), NULL);
+
+  /* load the user data on-demand */
+  if (G_UNLIKELY (user->name == NULL))
+    thunar_user_load (user);
+
+  return user->primary_group;
+}
+
+
+
+/**
+ * thunar_user_get_id:
+ * @user : a #ThunarUser.
+ *
+ * Returns the unique id of @user.
+ *
+ * Return value: the unique id of @user.
+ **/
+guint32
+thunar_user_get_id (ThunarUser *user)
+{
+  g_return_val_if_fail (THUNAR_IS_USER (user), 0);
+  return user->id;
+}
+
+
+
+/**
+ * thunar_user_get_name:
+ * @user : a #ThunarUser.
+ *
+ * Returns the name of @user. If the system is
+ * unable to determine the account name of @user,
+ * it'll return the user id as string.
+ *
+ * Return value: the name of @user.
+ **/
+const gchar*
+thunar_user_get_name (ThunarUser *user)
+{
+  g_return_val_if_fail (THUNAR_IS_USER (user), 0);
+
+  /* load the user's data on-demand */
+  if (G_UNLIKELY (user->name == NULL))
+    thunar_user_load (user);
+
+  return user->name;
+}
+
+
+
+/**
+ * thunar_user_get_real_name:
+ * @user : a #ThunarUser.
+ *
+ * Returns the real name of @user or %NULL if the
+ * real name for @user is not known to the underlying
+ * system.
+ *
+ * Return value: the real name for @user or %NULL.
+ **/
+const gchar*
+thunar_user_get_real_name (ThunarUser *user)
+{
+  g_return_val_if_fail (THUNAR_IS_USER (user), 0);
+
+  /* load the user's data on-demand */
+  if (G_UNLIKELY (user->name == NULL))
+    thunar_user_load (user);
+
+  return user->real_name;
+}
+
+
+
+/**
+ * thunar_user_is_me:
+ * @user : a #ThunarUser.
+ *
+ * Checks whether the owner of the current process is
+ * described by @user.
+ *
+ * Return value: %TRUE if @user is the owner of the current
+ *               process, else %FALSE.
+ **/
+gboolean
+thunar_user_is_me (ThunarUser *user)
+{
+  g_return_val_if_fail (THUNAR_IS_USER (user), FALSE);
+  return (user->id == thunar_user_effective_uid);
+}
+
+
+
+
+static void     thunar_user_manager_class_init          (ThunarUserManagerClass *klass);
+static void     thunar_user_manager_init                (ThunarUserManager      *manager);
+static void     thunar_user_manager_finalize            (GObject                *object);
+static gboolean thunar_user_manager_flush_timer         (gpointer                user_data);
+static void     thunar_user_manager_flush_timer_destroy (gpointer                user_data);
+
+
+
+struct _ThunarUserManagerClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarUserManager
+{
+  GObject __parent__;
+
+  GHashTable *groups;
+  GHashTable *users;
+
+  gint        flush_timer_id;
+};
+
+
+
+static GObjectClass *thunar_user_manager_parent_class;
+
+
+
+GType
+thunar_user_manager_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (G_TYPE_OBJECT,
+                                            "ThunarUserManager",
+                                            sizeof (ThunarUserManagerClass),
+                                            (GClassInitFunc) thunar_user_manager_class_init,
+                                            sizeof (ThunarUserManager),
+                                            (GInstanceInitFunc) thunar_user_manager_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+thunar_user_manager_class_init (ThunarUserManagerClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* determine the parent type class */
+  thunar_user_manager_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_user_manager_finalize;
+}
+
+
+
+static void
+thunar_user_manager_init (ThunarUserManager *manager)
+{
+  manager->groups = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+  manager->users = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+
+  /* keep the groups file in memory if possible */
+#ifdef HAVE_SETGROUPENT
+  setgroupent (TRUE);
+#endif
+
+  /* keep the passwd file in memory if possible */
+#ifdef HAVE_SETPASSENT
+  setpassent (TRUE);
+#endif
+
+  /* start the flush timer */
+  manager->flush_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_USER_MANAGER_FLUSH_INTERVAL,
+                                                thunar_user_manager_flush_timer, manager,
+                                                thunar_user_manager_flush_timer_destroy);
+}
+
+
+
+static void
+thunar_user_manager_finalize (GObject *object)
+{
+  ThunarUserManager *manager = THUNAR_USER_MANAGER (object);
+
+  /* stop the flush timer */
+  if (G_LIKELY (manager->flush_timer_id >= 0))
+    g_source_remove (manager->flush_timer_id);
+
+  /* destroy the hash tables */
+  g_hash_table_destroy (manager->groups);
+  g_hash_table_destroy (manager->users);
+
+  /* unload the groups file */
+  endgrent ();
+
+  /* unload the passwd file */
+  endpwent ();
+
+  (*G_OBJECT_CLASS (thunar_user_manager_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+thunar_user_manager_flush_timer (gpointer user_data)
+{
+  ThunarUserManager *manager = THUNAR_USER_MANAGER (user_data);
+  guint              size = 0;
+
+  GDK_THREADS_ENTER ();
+
+  /* drop all cached groups */
+  size += g_hash_table_foreach_remove (manager->groups, (GHRFunc) gtk_true, NULL);
+
+  /* drop all cached users */
+  size += g_hash_table_foreach_remove (manager->users, (GHRFunc) gtk_true, NULL);
+
+  /* reload groups and passwd files if we had cached entities */
+  if (G_LIKELY (size > 0))
+    {
+      endgrent ();
+      endpwent ();
+
+#ifdef HAVE_SETGROUPENT
+      setgroupent (TRUE);
+#endif
+
+#ifdef HAVE_SETPASSENT
+      setpassent (TRUE);
+#endif
+    }
+
+  GDK_THREADS_LEAVE ();
+
+  return TRUE;
+}
+
+
+
+static void
+thunar_user_manager_flush_timer_destroy (gpointer user_data)
+{
+  THUNAR_USER_MANAGER (user_data)->flush_timer_id = -1;
+}
+
+
+
+/**
+ * thunar_user_manager_get_default:
+ *
+ * Returns the default #ThunarUserManager instance, which is shared
+ * by all modules using the user module. Call g_object_unref() on the
+ * returned object when you are done with it.
+ *
+ * Return value: the default #ThunarUserManager instance.
+ **/
+ThunarUserManager*
+thunar_user_manager_get_default (void)
+{
+  static ThunarUserManager *manager = NULL;
+
+  if (G_UNLIKELY (manager == NULL))
+    {
+      manager = g_object_new (THUNAR_TYPE_USER_MANAGER, NULL);
+      g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager);
+    }
+  else
+    {
+      g_object_ref (G_OBJECT (manager));
+    }
+
+  return manager;
+}
+
+
+
+/**
+ * thunar_user_manager_get_group_by_id:
+ * @manager : a #ThunarUserManager.
+ * @id      : the group id.
+ *
+ * Looks up the #ThunarGroup corresponding to @id in @manager. Returns
+ * %NULL if @manager is unable to determine the #ThunarGroup for @id,
+ * else a pointer to the corresponding #ThunarGroup. The caller is
+ * responsible for freeing the returned object using g_object_unref().
+ *
+ * Return value: the #ThunarGroup corresponding to @id or %NULL.
+ **/
+ThunarGroup*
+thunar_user_manager_get_group_by_id (ThunarUserManager *manager,
+                                     guint32            id)
+{
+  ThunarGroup *group;
+
+  g_return_val_if_fail (THUNAR_IS_USER_MANAGER (manager), NULL);
+
+  /* lookup/load the group corresponding to id */
+  group = g_hash_table_lookup (manager->groups, GINT_TO_POINTER (id));
+  if (group == NULL)
+    {
+      group = thunar_group_new (id);
+      g_hash_table_insert (manager->groups, GINT_TO_POINTER (id), group);
+    }
+
+  /* take a reference for the caller */
+  g_object_ref (G_OBJECT (group));
+
+  return group;
+}
+
+
+
+/**
+ * thunar_user_manager_get_user_by_id:
+ * @manager : a #ThunarUserManager.
+ * @id      : the user id.
+ *
+ * Looks up the #ThunarUser corresponding to @id in @manager. Returns
+ * %NULL if @manager is unable to determine the #ThunarUser for @id,
+ * else a pointer to the corresponding #ThunarUser. The caller is
+ * responsible for freeing the returned object using g_object_unref().
+ *
+ * Return value: the #ThunarUser corresponding to @id or %NULL.
+ **/
+ThunarUser*
+thunar_user_manager_get_user_by_id (ThunarUserManager *manager,
+                                    guint32            id)
+{
+  ThunarUser *user;
+
+  g_return_val_if_fail (THUNAR_IS_USER_MANAGER (manager), NULL);
+
+  /* lookup/load the user corresponding to id */
+  user = g_hash_table_lookup (manager->users, GINT_TO_POINTER (id));
+  if (user == NULL)
+    {
+      user = thunar_user_new (id);
+      g_hash_table_insert (manager->users, GINT_TO_POINTER (id), user);
+    }
+
+  /* take a reference for the caller */
+  g_object_ref (G_OBJECT (user));
+
+  return user;
+}
+
+
+
+/**
+ * thunar_user_manager_get_all_groups:
+ * @manager : a #ThunarUserManager.
+ *
+ * Returns the list of all #ThunarGroup<!---->s in the system
+ * that are known to the @manager.
+ *
+ * The caller is responsible to free the returned list using:
+ * <informalexample><programlisting>
+ * g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ * g_list_free (list);
+ * </programlisting></informalexample>
+ *
+ * Return value: the list of all groups known to the @manager.
+ **/
+GList*
+thunar_user_manager_get_all_groups (ThunarUserManager *manager)
+{
+  ThunarGroup  *group;
+  struct group *grp;
+  GList        *groups = NULL;
+
+  g_return_val_if_fail (THUNAR_IS_USER_MANAGER (manager), NULL);
+
+  /* make sure we reload the groups list */
+  endgrent ();
+
+  /* iterate through all groups in the system */
+  for (;;)
+    {
+      /* lookup the next group */
+      grp = getgrent ();
+      if (G_UNLIKELY (grp == NULL))
+        break;
+
+      /* lookup our version of the group */
+      group = thunar_user_manager_get_group_by_id (manager, grp->gr_gid);
+      if (G_LIKELY (group != NULL))
+        groups = g_list_append (groups, group);
+    }
+
+  return groups;
+}

Added: thunar/branches/migration-to-gio/thunar/thunar-user.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-user.h	                        (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-user.h	2009-04-10 22:00:47 UTC (rev 29758)
@@ -0,0 +1,88 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#ifndef __THUNAR_USER_H__
+#define __THUNAR_USER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _ThunarGroupClass ThunarGroupClass;
+typedef struct _ThunarGroup      ThunarGroup;
+
+#define THUNAR_TYPE_GROUP            (thunar_group_get_type ())
+#define THUNAR_GROUP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_GROUP, ThunarGroup))
+#define THUNAR_GROUP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_GROUP, ThunarGroupClass))
+#define THUNAR_IS_GROUP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_GROUP))
+#define THUNAR_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_GROUP))
+#define THUNAR_GROUP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_GROUP, ThunarGroupClass))
+
+GType         thunar_group_get_type  (void) G_GNUC_CONST;
+
+guint32       thunar_group_get_id    (ThunarGroup *group);
+const gchar  *thunar_group_get_name  (ThunarGroup *group);
+
+
+typedef struct _ThunarUserClass ThunarUserClass;
+typedef struct _ThunarUser      ThunarUser;
+
+#define THUNAR_TYPE_USER            (thunar_user_get_type ())
+#define THUNAR_USER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_USER, ThunarUser))
+#define THUNAR_USER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_USER, ThunarUserClass))
+#define THUNAR_IS_USER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_USER))
+#define THUNAR_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_USER))
+#define THUNAR_USER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_USER, ThunarUserClass))
+
+GType         thunar_user_get_type          (void) G_GNUC_CONST;
+
+GList        *thunar_user_get_groups        (ThunarUser *user);
+ThunarGroup  *thunar_user_get_primary_group (ThunarUser *user);
+guint32       thunar_user_get_id            (ThunarUser *user);
+const gchar  *thunar_user_get_name          (ThunarUser *user);
+const gchar  *thunar_user_get_real_name     (ThunarUser *user);
+gboolean      thunar_user_is_me             (ThunarUser *user);
+
+
+typedef struct _ThunarUserManagerClass ThunarUserManagerClass;
+typedef struct _ThunarUserManager      ThunarUserManager;
+
+#define THUNAR_TYPE_USER_MANAGER            (thunar_user_manager_get_type ())
+#define THUNAR_USER_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_USER_MANAGER, ThunarUserManager))
+#define THUNAR_USER_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_USER_MANAGER, ThunarUserManagerClass))
+#define THUNAR_IS_USER_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_USER_MANAGER))
+#define THUNAR_IS_USER_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_USER_MANAGER))
+#define THUNAR_USER_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_USER_MANAGER, ThunarUserManagerClass))
+
+GType              thunar_user_manager_get_type        (void) G_GNUC_CONST;
+
+ThunarUserManager *thunar_user_manager_get_default     (void) G_GNUC_WARN_UNUSED_RESULT;
+
+ThunarGroup       *thunar_user_manager_get_group_by_id (ThunarUserManager *manager,
+                                                        guint32            id) G_GNUC_WARN_UNUSED_RESULT;
+ThunarUser        *thunar_user_manager_get_user_by_id  (ThunarUserManager *manager,
+                                                        guint32            id) G_GNUC_WARN_UNUSED_RESULT;
+
+GList             *thunar_user_manager_get_all_groups  (ThunarUserManager *manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+G_END_DECLS;
+
+#endif /* !__THUNAR_USER_H__ */




More information about the Xfce4-commits mailing list