]>
Commit | Line | Data |
---|---|---|
41fab122 | 1 | |
2 | #include <stdio.h> | |
2ce085d2 | 3 | #include <moira.h> |
41fab122 | 4 | |
5 | struct mem { | |
6 | int parent; | |
7 | int child; | |
8 | short ref; | |
9 | char direct; | |
10 | char ctype; | |
11 | }; | |
12 | ||
13 | ||
14 | main() | |
15 | { | |
16 | struct save_queue *sq, *load_members(); | |
17 | ||
18 | ## ingres sms | |
19 | printf("Loading LIST members...\n"); | |
20 | sq = load_members(); | |
21 | printf("Computing LIST memberships...\n"); | |
22 | do_members(sq); | |
23 | printf("Computing full memberships...\n"); | |
24 | do_all_members(sq); | |
25 | printf("Done\n"); | |
26 | exit(0); | |
27 | } | |
28 | ||
29 | struct save_queue *load_members() | |
30 | ##{ | |
31 | register struct mem *m; | |
32 | struct mem *new_mem(); | |
33 | struct save_queue *sq; | |
34 | ## int lid, mid; | |
35 | ## char mtype[9]; | |
36 | ||
37 | sq = sq_create(); | |
38 | ## range of m is members | |
39 | ## retrieve (lid = m.list_id, mid = m.member_id, mtype = m.member_type) { | |
40 | m = new_mem(); | |
41 | m->parent = lid; | |
42 | m->child = mid; | |
43 | m->ref = 0; | |
44 | m->direct = 1; | |
45 | m->ctype = mtype[0]; | |
46 | sq_save_data(sq, m); | |
47 | ## } | |
48 | return(sq); | |
49 | ##} | |
50 | ||
51 | struct mem *new_mem() | |
52 | { | |
53 | static int count = 0; | |
54 | static struct mem *m = NULL; | |
55 | struct mem *ret; | |
56 | ||
57 | if (m == NULL || count <= 0) { | |
58 | m = malloc(100 * sizeof(struct mem)); | |
59 | if (m == NULL) | |
60 | printf("Out of memory!\n"); | |
61 | count = 100; | |
62 | } | |
63 | ret = m++; | |
64 | count--; | |
65 | return(ret); | |
66 | } | |
67 | ||
68 | ||
69 | #define MAXLINK 100 | |
70 | ||
71 | do_members(sq) | |
72 | struct save_queue *sq; | |
73 | ##{ | |
74 | struct mem *m; | |
75 | ## int cid, pid, id, exists; | |
76 | int descendants[MAXLINK], ancestors[MAXLINK]; | |
77 | int dcount, acount, a, d; | |
78 | ||
79 | ## range of m is imembers | |
80 | while (sq_get_data(sq, &m)) { | |
81 | if (m->ctype != 'L') | |
82 | continue; | |
83 | cid = m->child; | |
84 | pid = m->parent; | |
85 | dcount = 0; | |
86 | descendants[dcount++] = cid; | |
87 | ## repeat retrieve (id = m.member_id) | |
88 | ## where m.list_id = @cid { | |
89 | descendants[dcount++] = id; | |
90 | ## } | |
91 | acount = 0; | |
92 | ancestors[acount++] = pid; | |
93 | ## repeat retrieve (id = m.list_id) | |
94 | ## where m.member_id = @pid { | |
95 | ancestors[acount++] = id; | |
96 | ## } | |
97 | if (dcount >= MAXLINK | acount >= MAXLINK) | |
98 | printf("too many links working on %d -> %d\n", cid, pid); | |
99 | for (d = 0; d < dcount; d++) { | |
100 | for (a = 0; a < acount; a++) { | |
101 | if ((cid = descendants[d]) == (pid = ancestors[a])) | |
102 | printf("LOOP! on %d\n", cid); | |
103 | ## repeat retrieve (exists = any(m.ref_count where m.list_id = @pid | |
104 | ## and m.member_id = @cid | |
105 | ## and m.member_type = "LIST")) | |
106 | if (exists) { | |
107 | if (a == 0 && d == 0) | |
108 | ## replace m (ref_count = m.ref_count+1, direct = 1) | |
109 | ## where m.list_id = pid and m.member_id = cid | |
110 | else | |
111 | ## replace m (ref_count = m.ref_count+1) | |
112 | ## where m.list_id = pid and m.member_id = cid | |
113 | } else { | |
114 | if (a == 0 && d == 0) | |
115 | ## append imembers (list_id=pid, member_id = cid, direct = 1, | |
116 | ## member_type="LIST", ref_count = 1) | |
117 | else | |
118 | ## append imembers (list_id=pid, member_id = cid, | |
119 | ## member_type="LIST", ref_count = 1) | |
120 | } | |
121 | } | |
122 | } | |
123 | } | |
124 | ##} | |
125 | ||
126 | ||
127 | ||
128 | do_all_members(sq) | |
129 | struct save_queue *sq; | |
130 | ##{ | |
131 | struct mem *mem; | |
132 | register struct mem *m; | |
133 | ## int cid, pid, id, exists; | |
134 | ## char *ctype; | |
135 | int descendants[MAXLINK], ancestors[MAXLINK]; | |
136 | int dcount, acount, a, d; | |
137 | ||
138 | ## range of m is imembers | |
139 | sq->q_lastget = 0; /* rewind queue */ | |
140 | while (sq_get_data(sq, &mem)) { | |
141 | m = mem; | |
142 | switch (m->ctype) { | |
143 | case 'L': | |
144 | continue; | |
145 | case 'S': | |
146 | ctype = "STRING"; | |
147 | break; | |
148 | case 'U': | |
149 | ctype = "USER"; | |
150 | break; | |
151 | case 'K': | |
152 | ctype = "KERBEROS"; | |
153 | break; | |
154 | default: | |
155 | printf("bad type %c on member %d\n", m->ctype, m->child); | |
156 | } | |
157 | ||
158 | cid = m->child; | |
159 | pid = m->parent; | |
160 | acount = 0; | |
161 | ancestors[acount++] = pid; | |
162 | ## repeat retrieve (id = m.list_id) | |
163 | ## where m.member_id = @pid and m.member_type = "LIST" { | |
164 | ancestors[acount++] = id; | |
165 | ## } | |
166 | if (acount >= MAXLINK) | |
167 | printf("too many links working on %d -> %d\n", cid, pid); | |
168 | for (a = 0; a < acount; a++) { | |
169 | pid = ancestors[a]; | |
170 | ## repeat retrieve (exists = any(m.ref_count where m.list_id = @pid | |
171 | ## and m.member_id = @cid | |
172 | ## and m.member_type = @ctype)) | |
173 | if (exists) { | |
174 | if (a == 0) | |
175 | ## replace m (ref_count = m.ref_count+1, direct = 1) | |
176 | ## where m.list_id = pid and m.member_id = cid | |
177 | else | |
178 | ## replace m (ref_count = m.ref_count+1) | |
179 | ## where m.list_id = pid and m.member_id = cid | |
180 | } else { | |
181 | if (a == 0) | |
182 | ## append imembers (list_id=pid, member_id = cid, direct = 1, | |
183 | ## member_type=ctype, ref_count = 1) | |
184 | else | |
185 | ## append imembers (list_id=pid, member_id = cid, | |
186 | ## member_type=ctype, ref_count = 1) | |
187 | } | |
188 | } | |
189 | } | |
190 | ##} |