Initial revision
[become] / src / name.c
1 /* -*-c-*-
2 *
3 * $Id: name.c,v 1.1 1997/07/21 13:47:46 mdw Exp $
4 *
5 * Looking up of names in symbol tables
6 *
7 * (c) 1997 EBI
8 */
9
10 /*----- Licencing notice --------------------------------------------------*
11 *
12 * This file is part of `become'
13 *
14 * `Become' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * `Become' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with `become'; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29 /*----- Revision history --------------------------------------------------*
30 *
31 * $Log: name.c,v $
32 * Revision 1.1 1997/07/21 13:47:46 mdw
33 * Initial revision
34 *
35 */
36
37 /*----- Header files ------------------------------------------------------*/
38
39 /* --- ANSI headers --- */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 /* --- Unix headers --- */
46
47 #include <grp.h>
48 #include <pwd.h>
49
50 /* --- Local headers --- */
51
52 #include "class.h"
53 #include "name.h"
54 #include "sym.h"
55 #include "userdb.h"
56 #include "utils.h"
57
58 /*----- Static variables --------------------------------------------------*/
59
60 static sym_table name__table; /* Symbol table for everything */
61
62 /*----- Main code ---------------------------------------------------------*/
63
64 /* --- @name_init@ --- *
65 *
66 * Arguments: ---
67 *
68 * Returns: ---
69 *
70 * Use: Initialises the name table. Requires the user database to
71 * be populated (see @userdb_local@ and @userdb_yp@).
72 */
73
74 void name_init(void)
75 {
76 /* --- Initialise the name table --- */
77
78 sym_createTable(&name__table);
79
80 /* --- Insert all the users and groups into the table --- */
81
82 {
83 struct passwd *pw;
84 struct group *gr;
85
86 userdb_iterateUsers();
87 while ((pw = userdb_nextUser()) != 0) {
88 unsigned f;
89 name *n;
90 int u;
91
92 /* --- First, add the user to the table --- */
93
94 n = sym_find(&name__table, pw->pw_name, -1, sizeof(name), &f);
95 if (!f) {
96 sym_table *t = xmalloc(sizeof(*t));
97 sym_createTable(t);
98 n->c = class_create(clType_user, t);
99 }
100 u = pw->pw_uid;
101 sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
102
103 /* --- Now handle the user's default group --- */
104
105 if ((gr = userdb_groupById(pw->pw_gid)) != 0) {
106 n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
107 if (!f) {
108 sym_table *t = xmalloc(sizeof(*t));
109 sym_createTable(t);
110 n->c = class_create(clType_user, t);
111 }
112 sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
113 }
114 }
115 }
116
117 /* --- Now get the subsidiary groups --- */
118
119 {
120 struct group *gr;
121 struct passwd *pw;
122 char **p;
123
124 userdb_iterateGroups();
125 while ((gr = userdb_nextGroup()) != 0) {
126 unsigned f;
127 name *n;
128 int u;
129
130 n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
131 if (!f) {
132 sym_table *t = xmalloc(sizeof(*t));
133 sym_createTable(t);
134 n->c = class_create(clType_user, t);
135 }
136
137 for (p = gr->gr_mem; *p; p++) {
138 if ((pw = userdb_userByName(*p)) != 0) {
139 u = pw->pw_uid;
140 sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
141 }
142 }
143 }
144 }
145
146 /* --- Finally add in the `all' class --- *
147 *
148 * Do that now, to prevent it being overwritten by the above.
149 */
150
151 {
152 name *n;
153 unsigned f;
154
155 n = sym_find(&name__table, "all", -1, sizeof(name), &f);
156 if (f)
157 class_dec(n->c);
158 n->c = class_all;
159 }
160 }
161
162 /* --- @name_reinit@ --- *
163 *
164 * Arguments: ---
165 *
166 * Returns: ---
167 *
168 * Use: Reinitialises the names table. It's cleared and then
169 * initialised with the current user and group ids as for
170 * @name_init@ above.
171 */
172
173 void name_reinit(void)
174 {
175 /* --- Empty the symbol table --- */
176
177 {
178 sym_iter i;
179 name *n;
180
181 for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) {
182 if (n->c)
183 class_dec(n->c);
184 }
185 }
186
187 /* --- Destroy and recreate the table --- */
188
189 sym_destroyTable(&name__table);
190 name_init();
191 }
192
193 /* --- @name_find@ --- *
194 *
195 * Arguments: @const char *p@ = pointer to name to look up
196 * @unsigned create@ = whether to create the item
197 * @unsigned *f@ = whether the item was created
198 *
199 * Returns: Pointer to a @name@ block containing the symbol, or
200 * zero if it wasn't found and we didn't want to create a
201 * new one.
202 *
203 * Use: Looks up a name in the symbol table and returns the
204 * item so located.
205 */
206
207 name *name_find(const char *p, unsigned create, unsigned *f)
208 {
209 /* --- This is a trivial veneer onto @sym_find@ --- */
210
211 return (sym_find(&name__table, p, -1, create ? sizeof(name) : 0, f));
212 }
213
214 /* --- @name_dump@ --- *
215 *
216 * Arguments: @FILE *fp@ = stream to dump on
217 *
218 * Returns: ---
219 *
220 * Use: Dumps a complete listing of the symbol table.
221 */
222
223 void name_dump(FILE *fp)
224 {
225 sym_iter i;
226 name *n;
227
228 for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) {
229 fprintf(fp, "\n--- name `%s'\n", n->base.name);
230 class_dump(n->c, fp);
231 }
232 }
233
234 /*----- Test driver -------------------------------------------------------*/
235
236 #ifdef TEST_RIG
237
238 int main(void)
239 {
240 userdb_init();
241 userdb_local();
242 userdb_yp();
243 name_init();
244 name_dump(stdout);
245 return (0);
246 }
247
248 #endif