/gnome-commander-1.2.8.15/src/owner.h

# · C Header · 272 lines · 178 code · 72 blank · 22 comment · 8 complexity · d53991c53adc28a88d23270a3a0b5fce MD5 · raw file

  1. /*
  2. GNOME Commander - A GNOME based file manager
  3. Copyright (C) 2001-2006 Marcus Bjurman
  4. Copyright (C) 2007-2011 Piotr Eljasiak
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #ifndef __OWNER_H__
  18. #define __OWNER_H__
  19. #include <grp.h>
  20. #include <pwd.h>
  21. class GnomeCmdOwner
  22. {
  23. GThread *thread;
  24. gboolean stop_thread;
  25. char *buff;
  26. size_t buffsize;
  27. uid_t user_id;
  28. gid_t group_id;
  29. GList *group_names;
  30. public:
  31. template <typename T, typename ID>
  32. class HashTable
  33. {
  34. GHashTable *id_table;
  35. GHashTable *name_table;
  36. GList *entries;
  37. struct Entry
  38. {
  39. ID id;
  40. char *name;
  41. T data;
  42. };
  43. Entry *lookup(ID id) { return (Entry *) g_hash_table_lookup (id_table, &id); }
  44. Entry *lookup(const gchar *name) { return (Entry *) g_hash_table_lookup (name_table, name); }
  45. Entry *add(ID id, const gchar *name);
  46. public:
  47. HashTable();
  48. ~HashTable();
  49. guint size() { return g_hash_table_size (id_table); }
  50. gboolean empty() { return size()==0; }
  51. const gchar *operator [] (ID id);
  52. ID operator [] (const gchar *name);
  53. GList *get_names();
  54. friend class GnomeCmdOwner;
  55. };
  56. struct user_t
  57. {
  58. char *real_name;
  59. gid_t gid;
  60. gboolean zombie; // the uid of this user doesn't match any user in the system
  61. };
  62. struct group_t
  63. {
  64. gboolean zombie; // the gid of this group doesn't match any group in the system
  65. };
  66. typedef HashTable<user_t,uid_t> GnomeCmdUsers;
  67. typedef HashTable<group_t,gid_t> GnomeCmdGroups;
  68. private:
  69. GnomeCmdUsers::Entry *new_entry(const struct passwd *pw);
  70. GnomeCmdGroups::Entry *new_entry(const struct group *grp);
  71. static gpointer perform_load_operation (GnomeCmdOwner *self);
  72. public:
  73. GnomeCmdUsers users;
  74. GnomeCmdGroups groups;
  75. GnomeCmdOwner();
  76. ~GnomeCmdOwner();
  77. uid_t uid() const { return user_id; }
  78. gid_t gid() const { return group_id; }
  79. gboolean is_root() { return uid()==0; }
  80. GList *get_group_names() { return group_names; }
  81. const char *get_name_by_uid(uid_t uid);
  82. const char *get_name_by_gid(gid_t gid);
  83. void load_async();
  84. };
  85. template <typename T, typename ID>
  86. inline GnomeCmdOwner::HashTable<T,ID>::HashTable()
  87. {
  88. entries = NULL;
  89. id_table = g_hash_table_new (g_int_hash, g_int_equal);
  90. name_table = g_hash_table_new (g_str_hash, g_str_equal);
  91. }
  92. template <typename T, typename ID>
  93. inline GnomeCmdOwner::HashTable<T,ID>::~HashTable()
  94. {
  95. g_hash_table_destroy (id_table);
  96. g_hash_table_destroy (name_table);
  97. if (entries)
  98. {
  99. g_list_foreach (entries, (GFunc) g_free, NULL);
  100. g_list_free (entries);
  101. }
  102. }
  103. template <typename T, typename ID>
  104. inline typename GnomeCmdOwner::HashTable<T,ID>::Entry *GnomeCmdOwner::HashTable<T,ID>::add(ID id, const gchar *name)
  105. {
  106. Entry *e = g_new0 (Entry, 1);
  107. e->id = id;
  108. e->name = g_strdup (name);
  109. entries = g_list_prepend (entries, e);
  110. g_hash_table_insert (id_table, &e->id, e);
  111. g_hash_table_insert (name_table, e->name, e);
  112. return e;
  113. }
  114. template <typename T, typename ID>
  115. inline const gchar *GnomeCmdOwner::HashTable<T,ID>::operator [] (ID id)
  116. {
  117. Entry *entry = lookup(id);
  118. g_assert (entry != NULL);
  119. return entry ? entry->name : NULL;
  120. }
  121. template <typename T, typename ID>
  122. inline ID GnomeCmdOwner::HashTable<T,ID>::operator [] (const gchar *name)
  123. {
  124. Entry *entry = lookup(name);
  125. g_assert (entry != NULL);
  126. return entry ? entry->id : -1;
  127. }
  128. #if GLIB_CHECK_VERSION (2, 14, 0)
  129. template <typename T, typename ID>
  130. inline GList *GnomeCmdOwner::HashTable<T,ID>::get_names()
  131. {
  132. return g_hash_table_get_keys (name_table); // FIXME: sort ?
  133. }
  134. #endif
  135. inline GnomeCmdOwner::GnomeCmdUsers::Entry *GnomeCmdOwner::new_entry(const struct passwd *pw)
  136. {
  137. g_return_val_if_fail (pw!=NULL, NULL);
  138. GnomeCmdUsers::Entry *entry = users.add(pw->pw_uid, pw->pw_name);
  139. entry->data.gid = pw->pw_gid;
  140. // entry->data.real_name = g_strdup (pw->pw_gecos); // not used at the moment
  141. // entry->data.zombie = FALSE;
  142. return entry;
  143. }
  144. inline GnomeCmdOwner::GnomeCmdGroups::Entry *GnomeCmdOwner::new_entry(const struct group *grp)
  145. {
  146. g_return_val_if_fail (grp!=NULL, NULL);
  147. GnomeCmdGroups::Entry *entry = groups.add(grp->gr_gid, grp->gr_name);
  148. // entry->data.zombie = FALSE;
  149. return entry;
  150. }
  151. inline GnomeCmdOwner::~GnomeCmdOwner()
  152. {
  153. stop_thread = TRUE;
  154. g_thread_join (thread);
  155. g_free (buff);
  156. g_list_free (group_names);
  157. }
  158. inline const char *GnomeCmdOwner::get_name_by_uid(uid_t id)
  159. {
  160. GnomeCmdUsers::Entry *entry = users.lookup(id);
  161. if (entry)
  162. return entry->name;
  163. struct passwd pwd, *result=NULL;
  164. getpwuid_r(id, &pwd, buff, buffsize, &result);
  165. if (!result) // zombie
  166. {
  167. char s[32];
  168. snprintf (s, sizeof(s), "%u", id);
  169. entry = users.add(id, s);
  170. entry->data.zombie = TRUE;
  171. return entry->name;
  172. }
  173. entry = new_entry(result);
  174. if (!groups.lookup(entry->data.gid))
  175. get_name_by_gid(entry->data.gid);
  176. return entry->name;
  177. }
  178. inline const char *GnomeCmdOwner::get_name_by_gid(gid_t id)
  179. {
  180. GnomeCmdGroups::Entry *entry = groups.lookup(id);
  181. if (entry)
  182. return entry->name;
  183. struct group grp, *result=NULL;
  184. getgrgid_r(id, &grp, buff, buffsize, &result);
  185. if (!result) // zombie
  186. {
  187. char s[32];
  188. snprintf (s, sizeof(s), "%u", id);
  189. entry = groups.add(id, s);
  190. entry->data.zombie = TRUE;
  191. return entry->name;
  192. }
  193. entry = new_entry(result);
  194. return entry->name;
  195. }
  196. extern GnomeCmdOwner gcmd_owner;
  197. #endif // __OWNER_H__