Replacing selfmade structures with GLib ones.

Timur I. Bakeyev mc at listserv.bat.ru
Sat Sep 1 14:01:35 UTC 2001


Hi!

This is my first patch in attempt to replace some of the MC data structures 
with GLib ones. The reason of doing this because some of the structures have
their equivalents in GLib, lookup and access methods in GLib implemented in
a better way, and also, a wish just to use all the staff from GLib, as soon 
as we are linking it anyhow :)

This particular patch replaces single linked list with the list of gids, to 
which user belongs so we can highlight the permission string properly.

The lookup was done a s a simple iteration throw the list, so, in average, it
is quite slow. The replacement is done via GTree, which implements binary tree
lookup, which much more quick(OK, this isn't the case where significant incre-
ase will occur, due to the limit of the groups, to which user can belong(16)).

Anyhow, this works and a bit quicker :)

Patch already applied to CVS.

Regards,
	Timur


-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/mc/src/ChangeLog,v
retrieving revision 1.595
diff -u -w -r1.595 ChangeLog
--- ChangeLog	2001/09/01 07:51:14	1.595
+++ ChangeLog	2001/09/01 13:44:51
@@ -1,3 +1,21 @@
+2001-08-31 23:14:21  Timur Bakeyev <mc at bat.ru>
+	
+	* utilunix.c: init_groups(), destroy_groups(), get_user_permissions()
+	rewritten to use GTree structure and functions. Add new static helper
+	functions mc_gid_compare() and mc_gid_destroy().
+	
+	* util.h: Removed deprecated structure user_in_groups.
+	
+	* screen.c: Fixed typo in format report error string.
+
+2001-08-31 23:14:21  Timur Bakeyev <mc at bat.ru>
+	
+	* utilunix.c: get_user_rights() renamed into get_user_permissions().
+	delete_groups() renamed into destroy_groups().
+	* util.h: Likewise.
+	* screen.c: Likewise.
+	* main.c: Likewise.
+	
 2001-08-27  Pavel Roskin  <proski at gnu.org>
 
 	* cmd.c (dirsizes_cmd): Don't cast st_size to long - use off_t
Index: main.c
===================================================================
RCS file: /cvs/gnome/mc/src/main.c,v
retrieving revision 1.161
diff -u -w -r1.161 main.c
--- main.c	2001/08/20 05:39:21	1.161
+++ main.c	2001/09/01 13:44:58
@@ -3178,7 +3178,7 @@
     vfs_shut ();
 
     /* Delete list of all user groups*/
-    delete_groups ();
+    destroy_groups ();
 
     flush_extension_file (); /* does only free memory */
 
Index: screen.c
===================================================================
RCS file: /cvs/gnome/mc/src/screen.c,v
retrieving revision 1.97
diff -u -w -r1.97 screen.c
--- screen.c	2001/08/30 16:41:08	1.97
+++ screen.c	2001/09/01 13:45:01
@@ -72,10 +72,6 @@
 /* If 1 - then add per file type hilighting */
 int filetype_mode = 1;
 
-/* This gives abilitiy to determine colored user priveleges */
-extern user_in_groups *current_user_gid;
-extern uid_t current_user_uid;
-
 /* If we have an info panel, this points to it */
 WPanel *the_info_panel = 0;
 
@@ -158,7 +154,7 @@
 {
     int i, r, l;
 
-    l = get_user_rights (&fe->buf);
+    l = get_user_permissions (&fe->buf);
 
     if (is_octal){
 	/* Place of the access bit in octal mode */
@@ -1307,7 +1303,7 @@
 	    delete_format (home);
 	    old_char = format [pos];
 	    format [pos] = 0;
-	    *error = g_strconcat (_("Unknow tag on display format: "), format, NULL);
+	    *error = g_strconcat (_("Unknown tag on display format: "), format, NULL);
 	    format [pos] = old_char;
 	    return 0;
 	}
Index: util.h
===================================================================
RCS file: /cvs/gnome/mc/src/util.h,v
retrieving revision 1.28
diff -u -w -r1.28 util.h
--- util.h	2001/08/30 16:41:08	1.28
+++ util.h	2001/09/01 13:45:02
@@ -63,14 +63,9 @@
 #endif
 
 /* uid/gid managing */
-typedef struct user_in_groups{
-    struct user_in_groups *next;
-    int gid;
-} user_in_groups;
-
 void init_groups (void);
-void delete_groups (void);
-int get_user_rights (struct stat *buf);
+void destroy_groups (void);
+int get_user_permissions (struct stat *buf);
 
 void init_uid_gid_cache (void);
 char *get_group (int);
Index: utilunix.c
===================================================================
RCS file: /cvs/gnome/mc/src/utilunix.c,v
retrieving revision 1.29
diff -u -w -r1.29 utilunix.c
--- utilunix.c	2001/08/14 00:55:38	1.29
+++ utilunix.c	2001/09/01 13:45:04
@@ -70,9 +70,6 @@
 
 struct sigaction startup_handler;
 
-uid_t current_user_uid;
-user_in_groups *current_user_gid;
-
 int
 max_open_files (void)
 {
@@ -94,63 +91,92 @@
 }
 
 #ifndef VFS_STANDALONE
+/* uid of the MC user */
+uid_t current_user_uid = -1;
+/* List of the gids of the user */
+GTree *current_user_gid = NULL;
+
+/* Helper function to compare 2 gids */
+static gint
+mc_gid_compare (gconstpointer v, gconstpointer v2)
+{
+    return ((GPOINTER_TO_UINT(v) > GPOINTER_TO_UINT(v2)) ? 1 :
+	    (GPOINTER_TO_UINT(v) < GPOINTER_TO_UINT(v2)) ? -1 : 0);
+}
+
+/* Helper function to delete keys of the gids tree */
+static gint
+mc_gid_destroy (gpointer key, gpointer value, gpointer data)
+{
+    g_free (value);
+    
+    return FALSE;
+}
+
+/* This function initialize global GTree with the gids of groups,
+   to which user belongs. Tree also store corresponding string 
+   with the name of the group.
+   FIXME: Do we need this names at all? If not, we can simplify
+   initialization by eliminating g_strdup's.
+*/
 void init_groups (void)
 {
     int i;
     struct passwd *pwd;
     struct group *grp;
-    user_in_groups *cug, *pug;
+    
+    current_user_uid = getuid ();
+
+    pwd = getpwuid (current_user_uid);
+    
+    g_return_if_fail (pwd != NULL);
 
-    pwd = getpwuid (current_user_uid=getuid ());
+    grp = getgrgid (pwd->pw_gid);
 
-    current_user_gid = (pug = g_new (user_in_groups, 1));
-    current_user_gid->gid = getgid (); 
-    current_user_gid->next = NULL;
+    g_return_if_fail (grp != NULL);
 
-    if (pwd == NULL)
-       return;
+    current_user_gid = g_tree_new (mc_gid_compare);
     
+    g_tree_insert (current_user_gid, 
+      GUINT_TO_POINTER(grp->gr_gid), g_strdup(grp->gr_name));
+    
     setgrent ();
+    
     while ((grp = getgrent ()))
+    {
        for (i = 0; grp->gr_mem[i]; i++)
-           if (!strcmp (pwd->pw_name,grp->gr_mem[i]))
                {
-               cug = g_new (user_in_groups, 1);
-               cug->gid  = grp->gr_gid;
-               pug->next = cug;
-               cug->next = NULL;
-               pug = cug;
+    	    if (!strcmp (pwd->pw_name, grp->gr_mem[i]) &&
+	      !g_tree_lookup (current_user_gid, GUINT_TO_POINTER(grp->gr_gid)))
+	    {
+		g_tree_insert (current_user_gid, 
+		  GUINT_TO_POINTER(grp->gr_gid), g_strdup(grp->gr_name));
                break;
                }
+	}
+    }
     endgrent ();
 }
 
-/* Return the index of permission triplet */
+/* Return the index of the permissions triplet */
 int
-get_user_rights (struct stat *buf)
-{
-    user_in_groups *cug;
+get_user_permissions (struct stat *buf) {
 
     if (buf->st_uid == current_user_uid || current_user_uid == 0)
        return 0;
 
-    for (cug = current_user_gid; cug; cug = cug->next)
-       if (cug->gid == buf->st_gid) return 1;
+    if(current_user_gid && g_tree_lookup (current_user_gid, GUINT_TO_POINTER(buf->st_gid)))
+       return 1;
 
     return 2;
 }
-
 
+/* Completely destroys the gids tree */
 void
-delete_groups (void)
+destroy_groups (void)
 {
-    user_in_groups *pug, *cug = current_user_gid;
-
-    while (cug){
-       pug = cug->next;
-       g_free (cug);
-       cug = pug;
-    }
+    g_tree_traverse (current_user_gid, mc_gid_destroy, G_POST_ORDER, NULL);
+    g_tree_destroy (current_user_gid);
 }
 
 #define UID_CACHE_SIZE 200


More information about the mc-devel mailing list