2
* Copyright (C) 2000-2002, 2004, 2005 Red Hat, Inc.
4
* This is free software; you can redistribute it and/or modify it under
5
* the terms of the GNU Library General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* You should have received a copy of the GNU Library General Public
15
* License along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
#ident "$Id: entity.c,v 1.30 2005/09/12 23:24:37 mitr Exp $"
22
#include "../config.h"
30
#include "user_private.h"
33
/* Create and return a new entity object. */
37
struct lu_ent *ent = NULL;
38
ent = g_malloc0(sizeof(struct lu_ent));
39
ent->magic = LU_ENT_MAGIC;
40
ent->cache = lu_string_cache_new(TRUE);
41
ent->current = g_array_new(FALSE, TRUE, sizeof(struct lu_attribute));
42
ent->pending = g_array_new(FALSE, TRUE, sizeof(struct lu_attribute));
43
ent->modules = g_value_array_new(1);
48
lu_ent_new_typed(enum lu_entity_type entity_type)
52
ret->type = entity_type;
56
/* Free an entity object. */
58
lu_ent_free(struct lu_ent *ent)
61
struct lu_attribute *attr;
62
g_return_if_fail(ent != NULL);
63
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
65
ent->cache->free(ent->cache);
66
/* Free each current attribute. */
67
for (i = 0; i < ent->current->len; i++) {
68
attr = &g_array_index(ent->current, struct lu_attribute, i);
69
/* Free the values array in this attribute; the array free
70
* will get the rest. */
71
g_value_array_free(attr->values);
75
g_array_free(ent->current, TRUE);
76
/* Free each pending attribute. */
77
for (i = 0; i < ent->pending->len; i++) {
78
attr = &g_array_index(ent->pending, struct lu_attribute, i);
79
/* Free the values array in this attribute; the array free
80
* will get the rest. */
81
g_value_array_free(attr->values);
85
g_array_free(ent->pending, TRUE);
86
/* Free the module list. */
87
g_value_array_free(ent->modules);
88
memset(ent, 0, sizeof(struct lu_ent));
92
/* Dump the contents of an entity structure. This is primarily for
95
lu_ent_dump(struct lu_ent *ent, FILE *fp)
98
struct lu_attribute *attribute;
100
g_return_if_fail(ent != NULL);
101
fprintf(fp, "dump of struct lu_ent at %p:\n", ent);
102
fprintf(fp, " magic = %08x\n", ent->magic);
103
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
104
g_return_if_fail((ent->type == lu_user) || (ent->type == lu_group));
107
fprintf(fp, " type = invalid\n");
110
fprintf(fp, " type = user\n");
113
fprintf(fp, " type = group\n");
116
fprintf(fp, " type = UNKNOWN\n");
119
/* Print the module list. */
120
fprintf(fp, " modules = (");
121
for (i = 0; i < ent->modules->n_values; i++) {
122
value = g_value_array_get_nth(ent->modules, i);
126
if (G_VALUE_HOLDS_STRING(value))
127
fprintf(fp, "`%s'", g_value_get_string(value));
128
else if (G_VALUE_HOLDS_LONG(value))
129
fprintf(fp, "%ld", g_value_get_long(value));
130
else if (G_VALUE_HOLDS_INT64(value))
132
(long long)g_value_get_int64(value));
137
/* Print the current data values. */
138
for (i = 0; i < ent->current->len; i++) {
139
attribute = &g_array_index(ent->current,
142
for (j = 0; j < attribute->values->n_values; j++) {
143
value = g_value_array_get_nth(attribute->values, j);
144
if (G_VALUE_HOLDS_STRING(value))
145
fprintf(fp, " %s = `%s'\n",
146
g_quark_to_string(attribute->name),
147
g_value_get_string(value));
148
else if (G_VALUE_HOLDS_LONG(value))
149
fprintf(fp, " %s = %ld\n",
150
g_quark_to_string(attribute->name),
151
g_value_get_long(value));
153
else if (G_VALUE_HOLDS_INT64(value))
154
fprintf(fp, " %s = %lld\n",
155
g_quark_to_string(attribute->name),
156
(long long)g_value_get_int64(value));
161
for (i = 0; i < ent->pending->len; i++) {
162
attribute = &g_array_index(ent->pending,
165
for (j = 0; j < attribute->values->n_values; j++) {
166
value = g_value_array_get_nth(attribute->values, j);
167
if (G_VALUE_HOLDS_STRING(value))
168
fprintf(fp, " %s = `%s'\n",
169
g_quark_to_string(attribute->name),
170
g_value_get_string(value));
171
else if (G_VALUE_HOLDS_LONG(value))
172
fprintf(fp, " %s = %ld\n",
173
g_quark_to_string(attribute->name),
174
g_value_get_long(value));
175
else if (G_VALUE_HOLDS_INT64(value))
176
fprintf(fp, " %s = %lld\n",
177
g_quark_to_string(attribute->name),
178
(long long)g_value_get_int64(value));
183
/* Add a module to the list of modules kept for this entity. */
185
lu_ent_add_module(struct lu_ent *ent, const char *source)
189
g_return_if_fail(ent != NULL);
190
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
191
g_return_if_fail(ent->modules != NULL);
192
/* Initialize a value with the string. */
193
memset(&value, 0, sizeof(value));
194
g_value_init(&value, G_TYPE_STRING);
195
g_value_set_string(&value, source);
196
/* Now scan the array for the value. */
197
for (i = 0; i < ent->modules->n_values; i++) {
198
val = g_value_array_get_nth(ent->modules, i);
199
/* We only add strings, so there had better be only strings
200
* in this list, otherwise someone is messing with us. */
201
g_assert(G_VALUE_HOLDS_STRING(val));
202
if (strcmp(g_value_get_string(val),
203
g_value_get_string(&value)) == 0) {
207
/* If we fell of the end of the array, then the new value is not
208
* in there, so we should add it. */
209
if (i >= ent->modules->n_values) {
210
g_value_array_append(ent->modules, &value);
212
g_value_unset(&value);
215
/* Clear the list of modules which affect this module, by freeing the array
216
* we use to keep track of them and allocating a new one. */
218
lu_ent_clear_modules(struct lu_ent *ent)
220
g_return_if_fail(ent != NULL);
221
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
222
g_value_array_free(ent->modules);
223
ent->modules = g_value_array_new(1);
226
/* Remove all attributes from an object. This function takes the address
227
* of whichever list we want cleared. */
229
clear_attribute_list(GArray *dest)
232
struct lu_attribute *attr;
233
for (i = dest->len - 1; i >= 0; i--) {
234
attr = &g_array_index(dest, struct lu_attribute, i);
235
g_value_array_free(attr->values);
237
g_array_remove_index_fast(dest, i);
241
/* Copy all attributes from source to dest, wiping out whatever was already
242
* in the destination array. */
244
copy_attributes(GArray *source, GArray *dest)
247
struct lu_attribute *attr, newattr;
248
/* First, clear the destination list of all attributes. */
249
clear_attribute_list(dest);
250
/* Now copy all of the attributes and their values. */
251
for (i = 0; i < source->len; i++) {
252
attr = &g_array_index(source, struct lu_attribute, i);
253
/* Copy the attribute name, then its values, into the holding
255
memset(&newattr, 0, sizeof(newattr));
256
newattr.name = attr->name;
257
newattr.values = g_value_array_copy(attr->values);
258
/* Now append the attribute to the array. */
259
g_array_append_val(dest, newattr);
264
lu_ent_revert(struct lu_ent *entity)
266
copy_attributes(entity->current, entity->pending);
270
lu_ent_commit(struct lu_ent *entity)
272
copy_attributes(entity->pending, entity->current);
276
lu_ent_copy(struct lu_ent *source, struct lu_ent *dest)
278
g_return_if_fail(source != NULL);
279
g_return_if_fail(dest != NULL);
280
g_return_if_fail(source->magic == LU_ENT_MAGIC);
281
g_return_if_fail(dest->magic == LU_ENT_MAGIC);
282
dest->type = source->type;
283
copy_attributes(source->current, dest->current);
284
copy_attributes(source->pending, dest->pending);
285
g_value_array_free(dest->modules);
286
dest->modules = g_value_array_copy(source->modules);
289
/* Return a GQark for lower-cased attribute */
291
quark_from_attribute(const char *attribute)
296
lower = g_ascii_strdown(attribute, -1);
297
quark = g_quark_from_string(lower);
303
lu_ent_get_int(GArray *list, const char *attribute)
305
struct lu_attribute *attr;
309
g_return_val_if_fail(list != NULL, NULL);
310
g_return_val_if_fail(attribute != NULL, NULL);
311
g_return_val_if_fail(strlen(attribute) > 0, NULL);
312
aquark = quark_from_attribute(attribute);
313
for (i = 0; i < list->len; i++) {
314
attr = &g_array_index(list, struct lu_attribute, i);
316
if (attr->name == aquark) {
317
g_assert(attr->values != NULL);
318
g_assert(attr->values->n_values > 0);
327
lu_ent_has_int(GArray *list, const char *attribute)
329
g_return_val_if_fail(list != NULL, FALSE);
330
g_return_val_if_fail(attribute != NULL, FALSE);
331
g_return_val_if_fail(strlen(attribute) > 0, FALSE);
332
return (lu_ent_get_int(list, attribute) != NULL) ? TRUE : FALSE;
336
lu_ent_clear_int(GArray *list, const char *attribute)
339
struct lu_attribute *attr = NULL;
342
g_return_if_fail(list != NULL);
343
g_return_if_fail(attribute != NULL);
344
g_return_if_fail(strlen(attribute) > 0);
345
aquark = quark_from_attribute(attribute);
346
for (i = list->len - 1; i >= 0; i--) {
347
attr = &g_array_index(list, struct lu_attribute, i);
348
if (attr->name == aquark)
352
g_value_array_free(attr->values);
354
g_array_remove_index(list, i);
359
lu_ent_set_int(GArray *list, const char *attr, const GValueArray *values)
361
GValueArray *dest, *copy;
362
struct lu_attribute newattr;
365
g_return_if_fail(list != NULL);
366
g_return_if_fail(attr != NULL);
367
g_return_if_fail(strlen(attr) > 0);
368
if (values->n_values == 0) {
369
lu_ent_clear_int(list, attr);
372
dest = lu_ent_get_int(list, attr);
374
memset(&newattr, 0, sizeof(newattr));
375
newattr.name = quark_from_attribute(attr);
376
newattr.values = g_value_array_new(0);
377
dest = newattr.values;
378
g_array_append_val(list, newattr);
380
while (dest->n_values > 0)
381
g_value_array_remove(dest, dest->n_values - 1);
382
copy = g_value_array_copy(values);
383
for (i = 0; i < copy->n_values; i++)
384
g_value_array_append(dest, g_value_array_get_nth(copy, i));
385
g_value_array_free(copy);
389
lu_ent_add_int(GArray *list, const char *attr, const GValue *value)
393
struct lu_attribute newattr;
396
g_return_if_fail(list != NULL);
397
g_return_if_fail(value != NULL);
398
g_return_if_fail(attr != NULL);
399
g_return_if_fail(strlen(attr) > 0);
400
dest = lu_ent_get_int(list, attr);
402
memset(&newattr, 0, sizeof(newattr));
403
newattr.name = quark_from_attribute(attr);
404
newattr.values = g_value_array_new(1);
405
dest = newattr.values;
406
g_array_append_val(list, newattr);
408
for (i = 0; i < dest->n_values; i++) {
409
current = g_value_array_get_nth(dest, i);
410
if (G_VALUE_TYPE(value) == G_VALUE_TYPE(current)
411
&& lu_values_equal(value, current))
414
if (i >= dest->n_values)
415
g_value_array_append(dest, value);
419
lu_ent_clear_all_int(GArray *list)
421
clear_attribute_list(list);
425
lu_ent_del_int(GArray *list, const char *attr, const GValue *value)
431
g_return_if_fail(list != NULL);
432
g_return_if_fail(value != NULL);
433
g_return_if_fail(attr != NULL);
434
g_return_if_fail(strlen(attr) > 0);
435
dest = lu_ent_get_int(list, attr);
437
svalue = g_strdup_value_contents(value);
438
for (i = 0; i < dest->n_values; i++) {
439
tvalue = g_value_array_get_nth(dest, i);
440
tmp = g_strdup_value_contents(tvalue);
441
if (strcmp(tmp, svalue) == 0) {
448
if (i < dest->n_values) {
449
g_value_array_remove(dest, i);
450
if (dest->n_values == 0)
451
lu_ent_clear_int(list, attr);
457
lu_ent_get_attributes_int(GArray *list)
459
struct lu_attribute *attr;
462
g_return_val_if_fail(list != NULL, NULL);
463
for (i = 0; i < list->len; i++) {
464
attr = &g_array_index(list, struct lu_attribute, i);
465
ret = g_list_prepend(ret, (char*)g_quark_to_string(attr->name));
467
return g_list_reverse(ret);
471
lu_ent_get(struct lu_ent *ent, const char *attribute)
473
g_return_val_if_fail(ent != NULL, NULL);
474
g_return_val_if_fail(ent->magic == LU_ENT_MAGIC, NULL);
475
g_return_val_if_fail(attribute != NULL, NULL);
476
g_return_val_if_fail(strlen(attribute) > 0, NULL);
477
return lu_ent_get_int(ent->pending, attribute);
481
lu_ent_get_current(struct lu_ent *ent, const char *attribute)
483
g_return_val_if_fail(ent != NULL, NULL);
484
g_return_val_if_fail(ent->magic == LU_ENT_MAGIC, NULL);
485
g_return_val_if_fail(attribute != NULL, NULL);
486
g_return_val_if_fail(strlen(attribute) > 0, NULL);
487
return lu_ent_get_int(ent->current, attribute);
491
lu_ent_has(struct lu_ent *ent, const char *attribute)
493
g_return_val_if_fail(ent != NULL, FALSE);
494
g_return_val_if_fail(ent->magic == LU_ENT_MAGIC, FALSE);
495
g_return_val_if_fail(attribute != NULL, FALSE);
496
g_return_val_if_fail(strlen(attribute) > 0, FALSE);
497
return lu_ent_has_int(ent->pending, attribute);
500
lu_ent_has_current(struct lu_ent *ent, const char *attribute)
502
g_return_val_if_fail(ent != NULL, FALSE);
503
g_return_val_if_fail(ent->magic == LU_ENT_MAGIC, FALSE);
504
g_return_val_if_fail(attribute != NULL, FALSE);
505
g_return_val_if_fail(strlen(attribute) > 0, FALSE);
506
return lu_ent_has_int(ent->current, attribute);
510
lu_ent_set(struct lu_ent *ent, const char *attribute, const GValueArray *values)
512
g_return_if_fail(ent != NULL);
513
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
514
g_return_if_fail(attribute != NULL);
515
g_return_if_fail(strlen(attribute) > 0);
516
lu_ent_set_int(ent->pending, attribute, values);
519
lu_ent_set_current(struct lu_ent *ent, const char *attribute,
520
const GValueArray *values)
522
g_return_if_fail(ent != NULL);
523
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
524
g_return_if_fail(attribute != NULL);
525
g_return_if_fail(strlen(attribute) > 0);
526
lu_ent_set_int(ent->current, attribute, values);
530
lu_ent_add(struct lu_ent *ent, const char *attribute, const GValue *value)
532
g_return_if_fail(ent != NULL);
533
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
534
g_return_if_fail(attribute != NULL);
535
g_return_if_fail(strlen(attribute) > 0);
536
lu_ent_add_int(ent->pending, attribute, value);
539
lu_ent_add_current(struct lu_ent *ent, const char *attribute,
542
g_return_if_fail(ent != NULL);
543
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
544
g_return_if_fail(attribute != NULL);
545
g_return_if_fail(strlen(attribute) > 0);
546
lu_ent_add_int(ent->current, attribute, value);
550
lu_ent_clear(struct lu_ent *ent, const char *attribute)
552
g_return_if_fail(ent != NULL);
553
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
554
g_return_if_fail(attribute != NULL);
555
g_return_if_fail(strlen(attribute) > 0);
556
lu_ent_clear_int(ent->pending, attribute);
559
lu_ent_clear_current(struct lu_ent *ent, const char *attribute)
561
g_return_if_fail(ent != NULL);
562
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
563
g_return_if_fail(attribute != NULL);
564
g_return_if_fail(strlen(attribute) > 0);
565
lu_ent_clear_int(ent->current, attribute);
569
lu_ent_clear_all(struct lu_ent *ent)
571
g_return_if_fail(ent != NULL);
572
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
573
lu_ent_clear_all_int(ent->pending);
576
lu_ent_clear_all_current(struct lu_ent *ent)
578
g_return_if_fail(ent != NULL);
579
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
580
lu_ent_clear_all_int(ent->current);
584
lu_ent_del(struct lu_ent *ent, const char *attribute, const GValue *value)
586
g_return_if_fail(ent != NULL);
587
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
588
g_return_if_fail(attribute != NULL);
589
g_return_if_fail(strlen(attribute) > 0);
590
g_return_if_fail(value != NULL);
591
lu_ent_del_int(ent->pending, attribute, value);
594
lu_ent_del_current(struct lu_ent *ent, const char *attribute,
597
g_return_if_fail(ent != NULL);
598
g_return_if_fail(ent->magic == LU_ENT_MAGIC);
599
g_return_if_fail(attribute != NULL);
600
g_return_if_fail(strlen(attribute) > 0);
601
g_return_if_fail(value != NULL);
602
lu_ent_del_int(ent->current, attribute, value);
606
lu_ent_get_attributes(struct lu_ent *ent)
608
g_return_val_if_fail(ent != NULL, NULL);
609
g_return_val_if_fail(ent->magic == LU_ENT_MAGIC, NULL);
610
return lu_ent_get_attributes_int(ent->pending);
614
lu_ent_get_attributes_current(struct lu_ent *ent)
616
g_return_val_if_fail(ent != NULL, NULL);
617
g_return_val_if_fail(ent->magic == LU_ENT_MAGIC, NULL);
618
return lu_ent_get_attributes_int(ent->current);