gnome-commander r2479 - in branches/gcmd-1-3: . doc/C src
- From: epiotr svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-commander r2479 - in branches/gcmd-1-3: . doc/C src
- Date: Tue, 24 Feb 2009 18:07:57 +0000 (UTC)
Author: epiotr
Date: Tue Feb 24 18:07:57 2009
New Revision: 2479
URL: http://svn.gnome.org/viewvc/gnome-commander?rev=2479&view=rev
Log:
Fixed problem #567506 (slow startup for systems with many users)
Modified:
branches/gcmd-1-3/ChangeLog
branches/gcmd-1-3/NEWS
branches/gcmd-1-3/doc/C/gnome-commander.xml
branches/gcmd-1-3/src/gnome-cmd-chown-component.cc
branches/gcmd-1-3/src/gnome-cmd-chown-dialog.cc
branches/gcmd-1-3/src/gnome-cmd-file.cc
branches/gcmd-1-3/src/gnome-cmd-main-win.cc
branches/gcmd-1-3/src/main.cc
branches/gcmd-1-3/src/owner.cc
branches/gcmd-1-3/src/owner.h
Modified: branches/gcmd-1-3/NEWS
==============================================================================
--- branches/gcmd-1-3/NEWS (original)
+++ branches/gcmd-1-3/NEWS Tue Feb 24 18:07:57 2009
@@ -11,6 +11,7 @@
* Fixed problem #554598 (GNOME Goal: LINGUAS)
* Fixed problem #556664 (bookmarks can not be saved for mounted devices)
* Fixed problem #567404 (crash when INSERT pressed over subdir)
+ * Fixed problem #567506 (slow startup for systems with many users)
* Fixed problem #570727 (usage of deprecated gnome_url_show)
* Fixed problem #571239 (replacing obsoleted GnomeColorPicker with GtkColorButton)
* Fixed problem #571247 (replacing obsoleted GnomePixmap with GtkImage)
Modified: branches/gcmd-1-3/doc/C/gnome-commander.xml
==============================================================================
--- branches/gcmd-1-3/doc/C/gnome-commander.xml (original)
+++ branches/gcmd-1-3/doc/C/gnome-commander.xml Tue Feb 24 18:07:57 2009
@@ -5894,6 +5894,9 @@
<para>Fixed problem #567404 (crash when INSERT pressed over subdir)</para>
</listitem>
<listitem>
+ <para>Fixed problem #567506 (slow startup for systems with many users)</para>
+ </listitem>
+ <listitem>
<para>Fixed problem #570727 (usage of deprecated gnome_url_show)</para>
</listitem>
<listitem>
Modified: branches/gcmd-1-3/src/gnome-cmd-chown-component.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-chown-component.cc (original)
+++ branches/gcmd-1-3/src/gnome-cmd-chown-component.cc Tue Feb 24 18:07:57 2009
@@ -32,7 +32,6 @@
struct _GnomeCmdChownComponentPrivate
{
GtkWidget *user_combo, *group_combo;
- GList *user_strings, *group_strings;
};
@@ -100,36 +99,19 @@
* Public functions
***********************************/
-static void load_users_and_groups (GnomeCmdChownComponent *comp)
+inline void load_users_and_groups (GnomeCmdChownComponent *comp)
{
- user_t *prog_user = OWNER_get_program_user ();
-
- g_return_if_fail (prog_user != NULL);
-
// disable user combo if user is not root, else fill the combo with all users in the system
- if (prog_user->uid != 0)
- gtk_widget_set_sensitive (comp->priv->user_combo, FALSE);
+ if (gcmd_owner.is_root())
+ gtk_combo_set_popdown_strings (GTK_COMBO (comp->priv->user_combo), gcmd_owner.users.get_names());
else
- {
- for (GList *tmp = OWNER_get_all_users (); tmp; tmp = tmp->next)
- {
- user_t *user = (user_t *) tmp->data;
-
- comp->priv->user_strings = g_list_append (comp->priv->user_strings, g_strdup (user->name));
- }
-
- gtk_combo_set_popdown_strings (GTK_COMBO (comp->priv->user_combo), comp->priv->user_strings);
- }
-
- // fill the groups combo with all groups that the user is part of if ordinary user or all groups if root
-
- for (GList *tmp = prog_user->uid != 0 ? prog_user->groups : OWNER_get_all_groups (); tmp; tmp = tmp->next)
- {
- group_t *group = (group_t *) tmp->data;
- comp->priv->group_strings = g_list_append (comp->priv->group_strings, g_strdup (group->name));
- }
+ gtk_widget_set_sensitive (comp->priv->user_combo, FALSE);
- gtk_combo_set_popdown_strings (GTK_COMBO (comp->priv->group_combo), comp->priv->group_strings);
+ if (gcmd_owner.get_group_names())
+ gtk_combo_set_popdown_strings (GTK_COMBO (comp->priv->group_combo), gcmd_owner.get_group_names()); // fill the groups combo with all groups that the user is part of
+ // if ordinary user or all groups if root
+ else
+ gtk_widget_set_sensitive (comp->priv->group_combo, FALSE); // disable group combo if yet not loaded
}
@@ -167,27 +149,24 @@
}
-void gnome_cmd_chown_component_set (GnomeCmdChownComponent *comp, uid_t owner, gid_t group)
+void gnome_cmd_chown_component_set (GnomeCmdChownComponent *comp, uid_t uid, gid_t gid)
{
- const gchar *s_owner = OWNER_get_name_by_uid (owner);
- const gchar *s_group = OWNER_get_name_by_gid (group);
-
- gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (comp->priv->user_combo)->entry), s_owner);
- gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (comp->priv->group_combo)->entry), s_group);
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (comp->priv->user_combo)->entry), gcmd_owner.users[uid]);
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (comp->priv->group_combo)->entry), gcmd_owner.groups[gid]);
}
uid_t gnome_cmd_chown_component_get_owner (GnomeCmdChownComponent *component)
{
- const gchar *s_owner = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (component->priv->user_combo)->entry));
+ const gchar *owner = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (component->priv->user_combo)->entry));
- return OWNER_get_uid_by_name (s_owner);
+ return gcmd_owner.users[owner];
}
gid_t gnome_cmd_chown_component_get_group (GnomeCmdChownComponent *component)
{
- const gchar *s_group = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (component->priv->group_combo)->entry));
+ const gchar *group = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (component->priv->group_combo)->entry));
- return OWNER_get_gid_by_name (s_group);
+ return gcmd_owner.groups[group];
}
Modified: branches/gcmd-1-3/src/gnome-cmd-chown-dialog.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-chown-dialog.cc (original)
+++ branches/gcmd-1-3/src/gnome-cmd-chown-dialog.cc Tue Feb 24 18:07:57 2009
@@ -91,21 +91,17 @@
{
uid_t uid = -1;
gid_t gid = -1;
- user_t *user = OWNER_get_program_user();
- gboolean recurse;
- if (user && user->uid == 0)
+ if (gcmd_owner.is_root())
{
- uid = gnome_cmd_chown_component_get_owner (
- GNOME_CMD_CHOWN_COMPONENT (dialog->priv->chown_component));
+ uid = gnome_cmd_chown_component_get_owner (GNOME_CMD_CHOWN_COMPONENT (dialog->priv->chown_component));
g_return_if_fail (uid >= 0);
}
- gid = gnome_cmd_chown_component_get_group (
- GNOME_CMD_CHOWN_COMPONENT (dialog->priv->chown_component));
+ gid = gnome_cmd_chown_component_get_group (GNOME_CMD_CHOWN_COMPONENT (dialog->priv->chown_component));
g_return_if_fail (gid >= 0);
- recurse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->recurse_check));
+ gboolean recurse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->recurse_check));
for (GList *tmp = dialog->priv->files; tmp; tmp = tmp->next)
{
Modified: branches/gcmd-1-3/src/gnome-cmd-file.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-file.cc (original)
+++ branches/gcmd-1-3/src/gnome-cmd-file.cc Tue Feb 24 18:07:57 2009
@@ -473,7 +473,7 @@
g_return_val_if_fail (file->info != NULL, NULL);
if (GNOME_VFS_FILE_INFO_LOCAL (file->info))
- return OWNER_get_name_by_uid (file->info->uid);
+ return gcmd_owner.get_name_by_uid(file->info->uid);
else
{
static gchar owner_str[MAX_OWNER_LENGTH];
@@ -489,7 +489,7 @@
g_return_val_if_fail (file->info != NULL, NULL);
if (GNOME_VFS_FILE_INFO_LOCAL (file->info))
- return OWNER_get_name_by_gid (file->info->gid);
+ return gcmd_owner.get_name_by_gid(file->info->gid);
else
{
static gchar group_str[MAX_GROUP_LENGTH];
@@ -849,15 +849,11 @@
if (!gnome_cmd_file_is_local (f))
return FALSE;
- user_t *user = OWNER_get_program_user ();
- if (!user)
- return FALSE;
-
- if (user->uid == f->info->uid
+ if (gcmd_owner.uid() == f->info->uid
&& f->info->permissions & GNOME_VFS_PERM_USER_EXEC)
return TRUE;
- if (user->gid == f->info->gid
+ if (gcmd_owner.gid() == f->info->gid
&& f->info->permissions & GNOME_VFS_PERM_GROUP_EXEC)
return TRUE;
Modified: branches/gcmd-1-3/src/gnome-cmd-main-win.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-main-win.cc (original)
+++ branches/gcmd-1-3/src/gnome-cmd-main-win.cc Tue Feb 24 18:07:57 2009
@@ -37,6 +37,7 @@
#include "gnome-cmd-con.h"
#include "gnome-cmd-con-list.h"
#include "gnome-cmd-bookmark-dialog.h"
+#include "owner.h"
#include "utils.h"
#include "../pixmaps/copy_file_names.xpm"
@@ -771,8 +772,8 @@
mw->priv->file_selector[LEFT] = NULL;
mw->priv->file_selector[RIGHT] = NULL;
- gnome_app_construct (GNOME_APP (main_win), "gnome-commander", geteuid() ? _("GNOME Commander") :
- _("GNOME Commander - ROOT PRIVILEGES"));
+ gnome_app_construct (GNOME_APP (main_win), "gnome-commander", gcmd_owner.is_root() ? _("GNOME Commander - ROOT PRIVILEGES") :
+ _("GNOME Commander"));
gtk_object_set_data (GTK_OBJECT (main_win), "main_win", main_win);
restore_size_and_pos (mw);
gtk_window_set_policy (GTK_WINDOW (main_win), TRUE, TRUE, FALSE);
Modified: branches/gcmd-1-3/src/main.cc
==============================================================================
--- branches/gcmd-1-3/src/main.cc (original)
+++ branches/gcmd-1-3/src/main.cc Tue Feb 24 18:07:57 2009
@@ -130,12 +130,12 @@
gnome_cmd_smb_auth_init ();
gnome_cmd_style_create ();
- OWNER_init ();
gcmd_user_actions.init();
main_win_widget = gnome_cmd_main_win_new ();
main_win = GNOME_CMD_MAIN_WIN (main_win_widget);
gtk_widget_show (GTK_WIDGET (main_win));
+ gcmd_owner.load_async();
gcmd_tags_init();
plugin_manager_init ();
@@ -153,7 +153,6 @@
gcmd_user_actions.shutdown();
gnome_cmd_data.save();
gnome_vfs_shutdown ();
- OWNER_free ();
IMAGE_free ();
remove_temp_download_dir ();
Modified: branches/gcmd-1-3/src/owner.cc
==============================================================================
--- branches/gcmd-1-3/src/owner.cc (original)
+++ branches/gcmd-1-3/src/owner.cc Tue Feb 24 18:07:57 2009
@@ -18,6 +18,11 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <unistd.h>
+
+#include <map>
+#include <set>
+
#include <config.h>
#include "gnome-cmd-includes.h"
#include "owner.h"
@@ -26,302 +31,107 @@
using namespace std;
-GList *all_users;
-GList *all_groups;
+GnomeCmdOwner gcmd_owner;
-static gint compare_users (user_t *u1, user_t *u2)
+static gint compare_names (const gchar *name1, const gchar *name2)
{
- return strcmp (u1->name, u2->name);
+ return strcmp(name1, name2);
}
-static gint compare_groups (user_t *g1, user_t *g2)
+#if !GLIB_CHECK_VERSION (2, 14, 0)
+template <typename T, typename ID>
+GList *GnomeCmdOwner::HashTable<T,ID>::get_names()
{
- return strcmp (g1->name, g2->name);
-}
-
-
-inline user_t *create_user (struct passwd *pw, gboolean zombie)
-{
- if (pw)
- {
- user_t *user = g_new0 (user_t, 1);
+ GList *retval = NULL;
- user->zombie = zombie;
- user->name = g_strdup (pw->pw_name);
- user->uid = pw->pw_uid;
- user->gid = pw->pw_gid;
- user->realname = g_strdup (pw->pw_gecos);
- // user->groups = NULL; // filled in later when going through the group members
+ for (GList *l=users; l; l=l->next)
+ retval = g_list_prepend (retval, static_cast<user_t *>(l->data)->name);
- return user;
- }
-
- return NULL;
+ return g_list_sort (retval, (GCompareFunc) compare_users);
}
+#endif
-static group_t *create_group (struct group *gr, gboolean zombie)
+GnomeCmdOwner::GnomeCmdOwner()
{
- group_t *group = NULL;
+ thread = NULL;
+ stop_thread = FALSE;
+ group_names = NULL;
- if (gr)
+ if (!buff)
{
- group = g_new0 (group_t, 1);
-
- group->zombie = zombie;
- group->name = g_strdup (gr->gr_name);
- group->gid = gr->gr_gid;
- // group->members = NULL;
-
- char **members = gr->gr_mem;
-
- while (members && *members)
- {
- user_t *user = OWNER_get_user_by_name (*members);
-
- if (user)
- {
- group->members = g_list_append (group->members, user);
- user->groups = g_list_append (user->groups, group);
- }
- else
- g_printerr (_("When parsing the users and groups on this system it was found that the user %s is part of the group %s. This user can however not be found.\n"), *members, group->name);
-
- members++;
- }
+ buffsize = max(sysconf(_SC_GETPW_R_SIZE_MAX), sysconf(_SC_GETGR_R_SIZE_MAX));
+ buff = g_new0 (char, buffsize);
}
- return group;
-}
-
-
-inline void free_user (user_t *user)
-{
- g_free (user->name);
- g_free (user->realname);
- g_free (user);
-}
-
-
-inline void free_group (group_t *group)
-{
- g_free (group->name);
- g_list_free (group->members);
- g_free (group);
-}
-
-
-inline void lookup_all_users ()
-{
- struct passwd *pw;
-
- setpwent ();
-
- while ((pw = getpwent ()) != NULL)
- all_users = g_list_prepend (all_users, create_user (pw, FALSE));
-
- endpwent ();
-
- all_users = g_list_sort (all_users, (GCompareFunc) compare_users);
+ user_id = geteuid();
+ get_name_by_uid(user_id);
+ group_id = users.lookup(user_id)->data.gid;
}
-inline void lookup_all_groups ()
+gpointer GnomeCmdOwner::perform_load_operation (GnomeCmdOwner *self)
{
- struct group *gr;
+ map <uid_t, set<gid_t> > user_groups;
+ map <gid_t, set<uid_t> > group_members;
- setgrent ();
+ setpwent();
- while ((gr = getgrent ()) != NULL)
- all_groups = g_list_prepend (all_groups, create_group (gr, FALSE));
+ for (struct passwd *pwd=getpwent(); !self->stop_thread && pwd; pwd=getpwent())
+ {
+ GnomeCmdUsers::Entry *e = self->users.lookup(pwd->pw_uid);
- endgrent ();
+ if (!e)
+ e = self->new_entry(pwd);
- all_groups = g_list_sort (all_groups, (GCompareFunc) compare_groups);
-}
+ user_groups[e->id].insert(e->data.gid);
+ group_members[e->data.gid].insert(e->id);
+ }
+ endpwent();
-inline void check_user_default_groups ()
-{
- user_t *user;
- group_t *group;
+ setgrent();
- for (GList *utmp=all_users; utmp; utmp=utmp->next)
+ for (struct group *grp=getgrent(); !self->stop_thread && grp; grp=getgrent())
{
- group_t *def_group = NULL;
- user = (user_t *) utmp->data;
+ if (!self->groups.lookup(grp->gr_gid))
+ self->new_entry(grp);
- for (GList *gtmp=user->groups; gtmp; gtmp=gtmp->next)
+ for (char **mem=grp->gr_mem; *mem; ++mem)
{
- group = (group_t *) gtmp->data;
+ GnomeCmdUsers::Entry *e = self->users.lookup(*mem);
- if (group->gid == user->gid)
+ if (e)
{
- def_group = group;
- break;
+ user_groups[e->id].insert(grp->gr_gid);
+ group_members[grp->gr_gid].insert(e->id);
}
}
-
- if (!def_group)
- {
- def_group = OWNER_get_group_by_gid (user->gid);
- user->groups = g_list_append (user->groups, def_group);
-
- def_group->members = g_list_append (def_group->members, user);
- }
}
-}
-
-/************************************************************************/
-
-
-user_t *OWNER_get_user_by_uid (uid_t uid)
-{
- user_t *user;
+ endgrent();
- // try to locate the user in the list of already found users
- for (GList *tmp = all_users; tmp; tmp = tmp->next)
+ if (!self->is_root())
{
- user = (user_t *) tmp->data;
+ map <uid_t, set<gid_t> >::iterator x = user_groups.find(self->uid());
- if (uid == user->uid)
- return user;
+ if (x!=user_groups.end())
+ for (set<gid_t>::const_iterator i=x->second.begin(); i!=x->second.end(); ++i)
+ self->group_names = g_list_prepend (self->group_names, (gpointer) self->groups[*i]);
}
+ else
+ for (map <gid_t, set<uid_t> >::const_iterator i=group_members.begin(); i!=group_members.end(); ++i)
+ self->group_names = g_list_prepend (self->group_names, (gpointer) self->groups[i->first]);
- // there is no such user in the system, lets create a blank user with the specified uid
-
- struct passwd pw;
-
- pw.pw_uid = uid;
- pw.pw_name = g_strdup_printf ("%d", uid);
- pw.pw_gecos = "";
- pw.pw_dir = "";
- pw.pw_shell = "";
- pw.pw_passwd = "";
-
- user = create_user (&pw, TRUE);
- if (user)
- all_users = g_list_append (all_users, user);
-
- g_free (pw.pw_name);
-
- return user;
-}
-
-
-user_t *OWNER_get_user_by_name (const char *name)
-{
- // try to locate the user in the list of already found users
- for (GList *tmp = all_users; tmp; tmp = tmp->next)
- {
- user_t *user = (user_t *) tmp->data;
-
- if (strcmp (name, user->name) == 0)
- return user;
- }
-
- return NULL;
-}
-
-
-group_t *OWNER_get_group_by_gid (gid_t gid)
-{
- // try to locate the group in the list of already found groups
- for (GList *tmp = all_groups; tmp; tmp = tmp->next)
- {
- group_t *group = (group_t *) tmp->data;
-
- if (gid == group->gid)
- return group;
- }
-
- // there is no such group in the system, lets create a blank group with the specified gid
- struct group gr;
-
- gr.gr_gid = gid;
- gr.gr_name = g_strdup_printf ("%d", gid);
- gr.gr_passwd = "";
- gr.gr_mem = NULL;
-
- group_t *group = create_group (&gr, TRUE);
- if (group)
- all_groups = g_list_append (all_groups, group);
-
- g_free (gr.gr_name);
-
- return group;
-}
-
-
-group_t *OWNER_get_group_by_name (const char *name)
-{
- // try to locate the group in the list of already found groups
- for (GList *tmp = all_groups; tmp; tmp = tmp->next)
- {
- group_t *group = (group_t *) tmp->data;
-
- if (strcmp (name, group->name) == 0)
- return group;
- }
+ self->group_names = g_list_sort (self->group_names, (GCompareFunc) compare_names); ;
return NULL;
}
-void OWNER_init ()
-{
- all_users = NULL;
- all_groups = NULL;
-
- lookup_all_users ();
- lookup_all_groups ();
- check_user_default_groups ();
-}
-
-
-void OWNER_free ()
-{
-
- /* free users */
- for (GList *users=all_users; users; users=users->next)
- {
- user_t *user = (user_t *) users->data;
- free_user (user);
- }
-
- /* free groups */
- for (GList *groups=all_groups; groups; groups=groups->next)
- {
- group_t *group = (group_t *) groups->data;
- free_group (group);
- }
-
- g_list_free (all_users);
- g_list_free (all_groups);
-}
-
-
-user_t *OWNER_get_program_user ()
-{
- const char *name = g_get_user_name ();
- user_t *user = OWNER_get_user_by_name (name);
-
- g_assert (user);
-
- return user;
-}
-
-
-GList *OWNER_get_all_users ()
-{
- return all_users;
-}
-
-
-GList *OWNER_get_all_groups ()
+void GnomeCmdOwner::load_async()
{
- return all_groups;
+ thread = g_thread_create ((GThreadFunc) perform_load_operation, this, TRUE, NULL);
}
Modified: branches/gcmd-1-3/src/owner.h
==============================================================================
--- branches/gcmd-1-3/src/owner.h (original)
+++ branches/gcmd-1-3/src/owner.h Tue Feb 24 18:07:57 2009
@@ -24,64 +24,249 @@
#include <grp.h>
#include <pwd.h>
-struct group_t
+class GnomeCmdOwner
{
- char *name;
- gid_t gid;
- GList *members; // stores the members as char *strings
- gboolean zombie; // The gid of this group doesn't match any group in the system
+ GThread *thread;
+ gboolean stop_thread;
+ char *buff;
+ size_t buffsize;
+
+ uid_t user_id;
+ gid_t group_id;
+
+ GList *group_names;
+
+ public:
+
+ template <typename T, typename ID>
+ class HashTable
+ {
+ GHashTable *id_table;
+ GHashTable *name_table;
+
+ GList *entries;
+
+ struct Entry
+ {
+ ID id;
+ char *name;
+ T data;
+ };
+
+ Entry *lookup(ID id) { return (Entry *) g_hash_table_lookup (id_table, &id); }
+ Entry *lookup(const gchar *name) { return (Entry *) g_hash_table_lookup (name_table, name); }
+ Entry *add(ID id, const gchar *name);
+
+ public:
+
+ HashTable();
+ ~HashTable();
+
+ guint size() { return g_hash_table_size (id_table); }
+ gboolean empty() { return size()==0; }
+
+ const gchar *operator [] (ID id);
+ ID operator [] (const gchar *name);
+ GList *get_names();
+
+ friend class GnomeCmdOwner;
+ };
+
+ struct user_t
+ {
+ char *real_name;
+ gid_t gid;
+ gboolean zombie; // the uid of this user doesn't match any user in the system
+ };
+
+ struct group_t
+ {
+ gboolean zombie; // the gid of this group doesn't match any group in the system
+ };
+
+ typedef HashTable<user_t,uid_t> GnomeCmdUsers;
+ typedef HashTable<group_t,gid_t> GnomeCmdGroups;
+
+ private:
+
+ GnomeCmdUsers::Entry *new_entry(const struct passwd *pw);
+ GnomeCmdGroups::Entry *new_entry(const struct group *grp);
+
+ static gpointer perform_load_operation (GnomeCmdOwner *self);
+
+ public:
+
+ GnomeCmdUsers users;
+ GnomeCmdGroups groups;
+
+ GnomeCmdOwner();
+ ~GnomeCmdOwner();
+
+ uid_t uid() const { return user_id; }
+ gid_t gid() const { return group_id; }
+ gboolean is_root() { return uid()==0; }
+
+ GList *get_group_names() { return group_names; }
+
+ const char *get_name_by_uid(uid_t uid);
+ const char *get_name_by_gid(gid_t gid);
+
+ void load_async();
};
-struct user_t
+template <typename T, typename ID>
+inline GnomeCmdOwner::HashTable<T,ID>::HashTable()
{
- char *name;
- uid_t uid;
- gid_t gid;
- group_t *group;
- char *realname;
- GList *groups;
- gboolean zombie; // The uid of this user doesn't match any user in the system
-};
+ entries = NULL;
+ id_table = g_hash_table_new (g_int_hash, g_int_equal);
+ name_table = g_hash_table_new (g_str_hash, g_str_equal);
+}
-void OWNER_init ();
-void OWNER_free ();
-user_t *OWNER_get_program_user ();
-user_t *OWNER_get_user_by_uid (uid_t uid);
-group_t *OWNER_get_group_by_gid (gid_t gid);
-user_t *OWNER_get_user_by_name (const char *name);
-group_t *OWNER_get_group_by_name (const char *name);
-GList *OWNER_get_all_users ();
-GList *OWNER_get_all_groups ();
+template <typename T, typename ID>
+inline GnomeCmdOwner::HashTable<T,ID>::~HashTable()
+{
+ g_hash_table_destroy (id_table);
+ g_hash_table_destroy (name_table);
+ if (entries)
+ {
+ g_list_foreach (entries, (GFunc) g_free, NULL);
+ g_list_free (entries);
+ }
+}
-inline const gchar *OWNER_get_name_by_uid (uid_t uid)
+template <typename T, typename ID>
+inline typename GnomeCmdOwner::HashTable<T,ID>::Entry *GnomeCmdOwner::HashTable<T,ID>::add(ID id, const gchar *name)
{
- user_t *user = OWNER_get_user_by_uid (uid);
+ Entry *e = g_new0 (Entry, 1);
+
+ e->id = id;
+ e->name = g_strdup (name);
+
+ entries = g_list_prepend (entries, e);
- return user ? user->name : NULL;
+ g_hash_table_insert (id_table, &e->id, e);
+ g_hash_table_insert (name_table, e->name, e);
+
+ return e;
}
+template <typename T, typename ID>
+inline const gchar *GnomeCmdOwner::HashTable<T,ID>::operator [] (ID id)
+{
+ Entry *entry = lookup(id);
+
+ g_assert (entry != NULL);
-inline const gchar *OWNER_get_name_by_gid (gid_t gid)
+ return entry ? entry->name : NULL;
+}
+
+template <typename T, typename ID>
+inline ID GnomeCmdOwner::HashTable<T,ID>::operator [] (const gchar *name)
{
- group_t *group = OWNER_get_group_by_gid (gid);
+ Entry *entry = lookup(name);
+
+ g_assert (entry != NULL);
- return group ? group->name : NULL;
+ return entry ? entry->id : -1;
}
+#if GLIB_CHECK_VERSION (2, 14, 0)
+template <typename T, typename ID>
+inline GList *GnomeCmdOwner::HashTable<T,ID>::get_names()
+{
+ return g_hash_table_get_keys (name_table); // FIXME: sort ?
+}
+#endif
-inline uid_t OWNER_get_uid_by_name (const gchar *name)
+inline GnomeCmdOwner::GnomeCmdUsers::Entry *GnomeCmdOwner::new_entry(const struct passwd *pw)
{
- user_t *user = OWNER_get_user_by_name (name);
+ g_return_val_if_fail (pw!=NULL, NULL);
+
+ GnomeCmdUsers::Entry *entry = users.add(pw->pw_uid, pw->pw_name);
- return user ? user->uid : -1;
+ entry->data.gid = pw->pw_gid;
+ // entry->data.real_name = g_strdup (pw->pw_gecos); // not used at the moment
+ // entry->data.zombie = FALSE;
+
+ return entry;
}
+inline GnomeCmdOwner::GnomeCmdGroups::Entry *GnomeCmdOwner::new_entry(const struct group *grp)
+{
+ g_return_val_if_fail (grp!=NULL, NULL);
+
+ GnomeCmdGroups::Entry *entry = groups.add(grp->gr_gid, grp->gr_name);
+
+ // entry->data.zombie = FALSE;
+
+ return entry;
+}
+
+inline GnomeCmdOwner::~GnomeCmdOwner()
+{
+ stop_thread = TRUE;
+ g_thread_join (thread);
+ g_free (buff);
+ g_list_free (group_names);
+}
+
+inline const char *GnomeCmdOwner::get_name_by_uid(uid_t id)
+{
+ GnomeCmdUsers::Entry *entry = users.lookup(id);
+
+ if (entry)
+ return entry->name;
-inline gid_t OWNER_get_gid_by_name (const gchar *name)
+ struct passwd pwd, *result=NULL;
+
+ getpwuid_r(id, &pwd, buff, buffsize, &result);
+
+ if (!result) // zombie
+ {
+ char s[32];
+
+ snprintf (s, sizeof(s), "%u", id);
+ entry = users.add(id, s);
+ entry->data.zombie = TRUE;
+
+ return entry->name;
+ }
+
+ entry = new_entry(result);
+
+ if (!groups.lookup(entry->data.gid))
+ get_name_by_gid(entry->data.gid);
+
+ return entry->name;
+}
+
+inline const char *GnomeCmdOwner::get_name_by_gid(gid_t id)
{
- group_t *group = OWNER_get_group_by_name (name);
+ GnomeCmdGroups::Entry *entry = groups.lookup(id);
- return group ? group->gid : -1;
+ if (entry)
+ return entry->name;
+
+ struct group grp, *result=NULL;
+
+ getgrgid_r(id, &grp, buff, buffsize, &result);
+
+ if (!result) // zombie
+ {
+ char s[32];
+
+ snprintf (s, sizeof(s), "%u", id);
+ entry = groups.add(id, s);
+ entry->data.zombie = TRUE;
+
+ return entry->name;
+ }
+
+ entry = new_entry(result);
+
+ return entry->name;
}
+extern GnomeCmdOwner gcmd_owner;
+
#endif // __OWNER_H__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]