summaryrefslogtreecommitdiff
path: root/liblogfs/groupset.c
blob: 91b18c9e4013d00c5e542f07f1289e0b7bd3f602 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "lib9.h"
#include "logfs.h"
#include "local.h"

struct GroupSet {
	int maxentries;
	int nentries;
	Group **entry;
};

char *
logfsgroupsetnew(GroupSet **gsp)
{
	GroupSet *gs = logfsrealloc(nil, sizeof(*gs));
	if(gs == nil)
		return Enomem;
	gs->entry = logfsrealloc(nil, sizeof(Group *));
	if(gs->entry == nil) {
		logfsfreemem(gs);
		return Enomem;
	}
	gs->maxentries = 1;		/* most groups have one member */
	gs->nentries = 0;
	*gsp = gs;
	return nil;
}

void
logfsgroupsetfree(GroupSet **gsp)
{
	GroupSet *gs = *gsp;
	if(gs) {
		logfsfreemem(gs->entry);
		logfsfreemem(gs);
		*gsp = nil;
	}
}

int
logfsgroupsetadd(GroupSet *gs, Group *g)
{
	int x;
	for(x = 0; x < gs->nentries; x++)
		if(gs->entry[x] == g)
			return 1;
	if(gs->nentries >= gs->maxentries) {
		Group **ne = logfsrealloc(gs->entry, sizeof(Group *) + (gs->maxentries * 2));
		if(ne)
			return 0;
		gs->entry = ne;
		gs->maxentries *= 2;
	}
	gs->entry[gs->nentries++] = g;
	return 1;
}

int
logfsgroupsetremove(GroupSet *gs, Group *g)
{
	int x;
	for(x = 0; x < gs->nentries; x++)
		if(gs->entry[x] == g)
			break;
	if(x == gs->nentries)
		return 0;
	gs->nentries--;
	memmove(&gs->entry[x], &gs->entry[x + 1], sizeof(Group *) * (gs->nentries - x));
	return 1;
}

int
logfsgroupsetwalk(GroupSet *gs, LOGFSGROUPSETWALKFN *func, void *magic)
{
	int x;
	for(x = 0; x < gs->nentries; x++) {
		int rv = (*func)(magic, gs->entry[x]);
		if(rv <= 0)
			return rv;
	}
	return 1;
}

int
logfsgroupsetismember(GroupSet *gs, Group *g)
{
	int x;
	for(x = 0; x < gs->nentries; x++)
		if(gs->entry[x] == g)
			return 1;
	return 0;
}