]>
Commit | Line | Data |
---|---|---|
dba0cf81 | 1 | /* Copyright (C) 1989 Transarc Corporation - All rights reserved */ |
e1f001e5 | 2 | /* |
3 | * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988 | |
4 | * LICENSED MATERIALS - PROPERTY OF IBM | |
5 | * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083 | |
6 | */ | |
7 | ||
dba0cf81 | 8 | #ifndef lint |
9 | static char rcsid[] = "$Header$"; | |
10 | #endif | |
11 | ||
e1f001e5 | 12 | /* |
13 | Sherri Nichols | |
14 | Information Technology Center | |
15 | November, 1988 | |
16 | ||
dba0cf81 | 17 | |
e1f001e5 | 18 | Modified May, 1989 by Jeff Schiller to keep disk file in |
19 | network byte order | |
20 | ||
21 | */ | |
22 | ||
d81c5086 | 23 | #include <afs/param.h> |
e1f001e5 | 24 | #include <sys/types.h> |
25 | #include <lock.h> | |
26 | #include <ubik.h> | |
27 | #include <stdio.h> | |
28 | #include <netinet/in.h> | |
29 | #include <netdb.h> | |
dba0cf81 | 30 | #include "ptserver.h" |
31 | #include "pterror.h" | |
e1f001e5 | 32 | |
33 | long IDHash(x) | |
34 | long x; | |
35 | { | |
36 | /* returns hash bucket for x */ | |
37 | return ((abs(x)) % HASHSIZE); | |
38 | } | |
39 | ||
40 | long NameHash(aname) | |
41 | register unsigned char *aname; | |
42 | { | |
43 | /* returns hash bucket for aname */ | |
44 | register unsigned int hash=0; | |
45 | register int i; | |
46 | /* stolen directly from the HashString function in the vol package */ | |
47 | for (i=strlen(aname),aname += i-1;i--;aname--) | |
48 | hash = (hash*31) + (*aname-31); | |
49 | return(hash % HASHSIZE); | |
50 | } | |
51 | ||
52 | ||
53 | long pr_Write(tt,afd,pos,buff,len) | |
54 | struct ubik_trans *tt; | |
55 | long afd; | |
56 | long pos; | |
57 | char *buff; | |
58 | long len; | |
59 | { | |
60 | /* package up seek and write into one procedure for ease of use */ | |
61 | long code; | |
dba0cf81 | 62 | if ((pos < sizeof(cheader)) && (buff != (char *)&cheader + pos)) { |
63 | fprintf (stderr, "ptserver: dbwrite: Illegal attempt to write a location 0\n"); | |
64 | return PRDBFAIL; | |
65 | } | |
e1f001e5 | 66 | code = ubik_Seek(tt,afd,pos); |
67 | if (code) return code; | |
68 | code = ubik_Write(tt,buff,len); | |
69 | return code; | |
70 | } | |
71 | ||
72 | long pr_Read(tt,afd,pos,buff,len) | |
73 | struct ubik_trans *tt; | |
74 | long afd; | |
75 | long pos; | |
76 | char *buff; | |
77 | long len; | |
78 | { | |
79 | /* same thing for read */ | |
80 | long code; | |
81 | code = ubik_Seek(tt,afd,pos); | |
82 | if (code) return code; | |
83 | code = ubik_Read(tt,buff,len); | |
84 | return code; | |
85 | } | |
86 | ||
87 | pr_WriteEntry(tt, afd, pos, tentry) | |
88 | struct ubik_trans *tt; | |
89 | long afd; | |
90 | long pos; | |
91 | struct prentry *tentry; | |
92 | { | |
93 | long code; | |
94 | register long i; | |
95 | struct prentry nentry; | |
dba0cf81 | 96 | |
e1f001e5 | 97 | if (ntohl(1) != 1) { /* Need to swap bytes. */ |
dba0cf81 | 98 | bzero (&nentry, sizeof(nentry)); /* make sure reseved fields are zero */ |
e1f001e5 | 99 | nentry.flags = htonl(tentry->flags); |
100 | nentry.id = htonl(tentry->id); | |
101 | nentry.cellid = htonl(tentry->cellid); | |
102 | nentry.next = htonl(tentry->next); | |
103 | nentry.nextID = htonl(tentry->nextID); | |
104 | nentry.nextName = htonl(tentry->nextName); | |
105 | nentry.owner = htonl(tentry->owner); | |
106 | nentry.creator = htonl(tentry->creator); | |
107 | nentry.ngroups = htonl(tentry->ngroups); | |
108 | nentry.nusers = htonl(tentry->nusers); | |
109 | nentry.count = htonl(tentry->count); | |
110 | nentry.instance = htonl(tentry->instance); | |
111 | nentry.owned = htonl(tentry->owned); | |
112 | nentry.nextOwned = htonl(tentry->nextOwned); | |
113 | nentry.parent = htonl(tentry->parent); | |
114 | nentry.sibling = htonl(tentry->sibling); | |
115 | nentry.child = htonl(tentry->child); | |
116 | strncpy(nentry.name, tentry->name, PR_MAXNAMELEN); | |
dba0cf81 | 117 | #ifdef PR_REMEMBER_TIMES |
118 | nentry.createTime = htonl(tentry->createTime); | |
119 | nentry.addTime = htonl(tentry->addTime); | |
120 | nentry.removeTime = htonl(tentry->removeTime); | |
121 | nentry.changeTime = htonl(tentry->changeTime); | |
122 | #endif | |
e1f001e5 | 123 | for (i = 0; i < PRSIZE; i++) |
124 | nentry.entries[i] = htonl(tentry->entries[i]); | |
dba0cf81 | 125 | tentry = &nentry; |
e1f001e5 | 126 | } |
dba0cf81 | 127 | code = pr_Write (tt, afd, pos, (char *)tentry, sizeof(struct prentry)); |
128 | return(code); | |
e1f001e5 | 129 | } |
dba0cf81 | 130 | |
e1f001e5 | 131 | pr_ReadEntry(tt, afd, pos, tentry) |
132 | struct ubik_trans *tt; | |
133 | long afd; | |
134 | long pos; | |
135 | struct prentry *tentry; | |
136 | { | |
137 | long code; | |
138 | register long i; | |
139 | struct prentry nentry; | |
140 | code = ubik_Seek(tt, afd, pos); | |
141 | if (code) return (code); | |
142 | if (ntohl(1) == 1) { /* no swapping needed */ | |
143 | code = ubik_Read(tt, (char *) tentry, sizeof(struct prentry)); | |
144 | return(code); | |
145 | } | |
146 | code = ubik_Read(tt, (char *) &nentry, sizeof(struct prentry)); | |
147 | if (code) return (code); | |
dba0cf81 | 148 | bzero (tentry, sizeof(*tentry)); /* make sure reseved fields are zero */ |
e1f001e5 | 149 | tentry->flags = ntohl(nentry.flags); |
150 | tentry->id = ntohl(nentry.id); | |
151 | tentry->cellid = ntohl(nentry.cellid); | |
152 | tentry->next = ntohl(nentry.next); | |
153 | tentry->nextID = ntohl(nentry.nextID); | |
154 | tentry->nextName = ntohl(nentry.nextName); | |
155 | tentry->owner = ntohl(nentry.owner); | |
156 | tentry->creator = ntohl(nentry.creator); | |
157 | tentry->ngroups = ntohl(nentry.ngroups); | |
158 | tentry->nusers = ntohl(nentry.nusers); | |
159 | tentry->count = ntohl(nentry.count); | |
160 | tentry->instance = ntohl(nentry.instance); | |
161 | tentry->owned = ntohl(nentry.owned); | |
162 | tentry->nextOwned = ntohl(nentry.nextOwned); | |
163 | tentry->parent = ntohl(nentry.parent); | |
164 | tentry->sibling = ntohl(nentry.sibling); | |
165 | tentry->child = ntohl(nentry.child); | |
166 | strncpy(tentry->name, nentry.name, PR_MAXNAMELEN); | |
dba0cf81 | 167 | #ifdef PR_REMEMBER_TIMES |
168 | tentry->createTime = ntohl(nentry.createTime); | |
169 | tentry->addTime = ntohl(nentry.addTime); | |
170 | tentry->removeTime = ntohl(nentry.removeTime); | |
171 | tentry->changeTime = ntohl(nentry.changeTime); | |
172 | #endif | |
e1f001e5 | 173 | for (i = 0; i < PRSIZE; i++) |
174 | tentry->entries[i] = ntohl(nentry.entries[i]); | |
175 | return(code); | |
176 | } | |
177 | ||
178 | pr_WriteCoEntry(tt, afd, pos, tentry) | |
dba0cf81 | 179 | struct ubik_trans *tt; |
180 | long afd; | |
181 | long pos; | |
182 | struct contentry *tentry; | |
e1f001e5 | 183 | { |
184 | long code; | |
185 | register long i; | |
186 | struct contentry nentry; | |
dba0cf81 | 187 | |
188 | if (ntohl(1) != 1) { /* No need to swap */ | |
189 | bzero (&nentry, sizeof(nentry)); /* make reseved fields zero */ | |
190 | nentry.flags = htonl(tentry->flags); | |
191 | nentry.id = htonl(tentry->id); | |
192 | nentry.cellid = htonl(tentry->cellid); | |
193 | nentry.next = htonl(tentry->next); | |
194 | for (i = 0; i < COSIZE; i++) | |
195 | nentry.entries[i] = htonl(tentry->entries[i]); | |
196 | tentry = &nentry; | |
e1f001e5 | 197 | } |
dba0cf81 | 198 | code = pr_Write (tt, afd, pos, (char *)tentry, sizeof(struct contentry)); |
e1f001e5 | 199 | return(code); |
200 | } | |
201 | ||
202 | pr_ReadCoEntry(tt, afd, pos, tentry) | |
203 | struct ubik_trans *tt; | |
204 | long afd; | |
205 | long pos; | |
206 | struct contentry *tentry; | |
207 | { | |
208 | long code; | |
209 | register long i; | |
210 | struct contentry nentry; | |
211 | code = ubik_Seek(tt, afd, pos); | |
212 | if (code) return (code); | |
213 | if (ntohl(1) == 1) { /* No swapping needed. */ | |
214 | code = ubik_Read(tt, (char *) tentry, sizeof(struct contentry)); | |
215 | return(code); | |
216 | } | |
217 | code = ubik_Read(tt, (char *) &nentry, sizeof(struct contentry)); | |
218 | if (code) return (code); | |
dba0cf81 | 219 | bzero (tentry, sizeof(*tentry)); /* make reseved fields zero */ |
e1f001e5 | 220 | tentry->flags = ntohl(nentry.flags); |
221 | tentry->id = ntohl(nentry.id); | |
222 | tentry->cellid = ntohl(nentry.cellid); | |
223 | tentry->next = ntohl(nentry.next); | |
224 | for (i = 0; i < COSIZE; i++) | |
225 | tentry->entries[i] = ntohl(nentry.entries[i]); | |
226 | return(code); | |
227 | } | |
228 | ||
dba0cf81 | 229 | /* AllocBloc - allocate a free block of storage for entry, returning address of |
230 | * new entry */ | |
231 | ||
e1f001e5 | 232 | long AllocBlock(at) |
dba0cf81 | 233 | register struct ubik_trans *at; |
e1f001e5 | 234 | { |
e1f001e5 | 235 | register long code; |
236 | long temp; | |
237 | struct prentry tentry; | |
238 | ||
239 | if (cheader.freePtr) { | |
240 | /* allocate this dude */ | |
241 | temp = ntohl(cheader.freePtr); | |
242 | code = pr_ReadEntry(at, 0, temp, &tentry); | |
243 | if (code) return 0; | |
244 | cheader.freePtr = htonl(tentry.next); | |
245 | code = pr_Write(at, 0, 8, (char *)&cheader.freePtr, sizeof(cheader.freePtr)); | |
246 | if (code != 0) return 0; | |
247 | return temp; | |
248 | } | |
249 | else { | |
250 | /* hosed, nothing on free list, grow file */ | |
251 | temp = ntohl(cheader.eofPtr); /* remember this guy */ | |
252 | cheader.eofPtr = htonl(temp + ENTRYSIZE); | |
253 | code = pr_Write(at, 0, 12,(char *) &cheader.eofPtr, sizeof(cheader.eofPtr)); | |
254 | if (code != 0) return 0; | |
255 | return temp; | |
256 | } | |
257 | } | |
258 | ||
259 | long FreeBlock(at, pos) | |
260 | register struct ubik_trans *at; | |
261 | long pos; | |
262 | { | |
263 | /* add a block of storage to the free list */ | |
264 | register long code; | |
265 | struct prentry tentry; | |
266 | ||
267 | bzero(&tentry,sizeof(tentry)); | |
268 | tentry.next = ntohl(cheader.freePtr); | |
269 | tentry.flags |= PRFREE; | |
270 | cheader.freePtr = htonl(pos); | |
271 | code = pr_Write(at,0,8, (char *) &cheader.freePtr,sizeof(cheader.freePtr)); | |
272 | if (code != 0) return code; | |
273 | code = pr_WriteEntry(at,0,pos,&tentry); | |
274 | if (code != 0) return code; | |
275 | return PRSUCCESS; | |
276 | } | |
277 | ||
278 | long FindByID(at,aid) | |
279 | register struct ubik_trans *at; | |
280 | long aid; | |
281 | { | |
282 | /* returns address of entry if found, 0 otherwise */ | |
283 | register long code; | |
284 | long i; | |
285 | struct prentry tentry; | |
286 | long entry; | |
287 | ||
dba0cf81 | 288 | if ((aid == PRBADID) || (aid == 0)) return 0; |
e1f001e5 | 289 | i = IDHash(aid); |
290 | entry = ntohl(cheader.idHash[i]); | |
291 | if (entry == 0) return entry; | |
292 | bzero(&tentry,sizeof(tentry)); | |
293 | code = pr_ReadEntry(at, 0, entry, &tentry); | |
294 | if (code != 0) return 0; | |
295 | if (aid == tentry.id) return entry; | |
296 | entry = tentry.nextID; | |
297 | while (entry != NULL) { | |
298 | bzero(&tentry,sizeof(tentry)); | |
299 | code = pr_ReadEntry(at,0,entry,&tentry); | |
300 | if (code != 0) return 0; | |
301 | if (aid == tentry.id) return entry; | |
302 | entry = tentry.nextID; | |
303 | } | |
304 | return 0; | |
305 | } | |
306 | ||
307 | ||
308 | ||
309 | long FindByName(at,aname) | |
310 | register struct ubik_trans *at; | |
311 | char aname[PR_MAXNAMELEN]; | |
312 | { | |
313 | /* ditto */ | |
314 | register long code; | |
315 | long i; | |
316 | struct prentry tentry; | |
317 | long entry; | |
318 | ||
319 | i = NameHash(aname); | |
320 | entry = ntohl(cheader.nameHash[i]); | |
321 | if (entry == 0) return entry; | |
322 | bzero(&tentry,sizeof(tentry)); | |
323 | code = pr_ReadEntry(at, 0, entry,&tentry); | |
324 | if (code != 0) return 0; | |
325 | if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry; | |
326 | entry = tentry.nextName; | |
327 | while (entry != NULL) { | |
328 | bzero(&tentry,sizeof(tentry)); | |
329 | code = pr_ReadEntry(at,0,entry,&tentry); | |
330 | if (code != 0) return 0; | |
331 | if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry; | |
332 | entry = tentry.nextName; | |
333 | } | |
334 | return 0; | |
335 | } | |
336 | ||
337 | long AllocID(at,flag,aid) | |
338 | register struct ubik_trans *at; | |
339 | long flag; | |
340 | long *aid; | |
341 | { | |
342 | /* allocs an id from the proper area of address space, based on flag */ | |
343 | register long code = 1; | |
344 | register long i = 0; | |
345 | register maxcount = 50; /* to prevent infinite loops */ | |
346 | ||
347 | if (flag & PRGRP) { | |
348 | *aid = ntohl(cheader.maxGroup); | |
349 | while (code && i<maxcount) { | |
350 | --(*aid); | |
351 | code = FindByID(at,*aid); | |
352 | i++; | |
353 | } | |
354 | if (code) return PRNOIDS; | |
355 | cheader.maxGroup = htonl(*aid); | |
356 | code = pr_Write(at,0,16,(char *)&cheader.maxGroup,sizeof(cheader.maxGroup)); | |
357 | if (code) return PRDBFAIL; | |
358 | return PRSUCCESS; | |
359 | } | |
360 | else if (flag & PRFOREIGN) { | |
361 | *aid = ntohl(cheader.maxForeign); | |
362 | while (code && i<maxcount) { | |
363 | ++(*aid); | |
364 | code = FindByID(at,*aid); | |
365 | i++; | |
366 | } | |
367 | if (code) return PRNOIDS; | |
368 | cheader.maxForeign = htonl(*aid); | |
369 | code = pr_Write(at,0,24,(char *)&cheader.maxForeign,sizeof(cheader.maxForeign)); | |
370 | if (code) return PRDBFAIL; | |
371 | return PRSUCCESS; | |
372 | } | |
373 | else { | |
374 | *aid = ntohl(cheader.maxID); | |
375 | while (code && i<maxcount) { | |
376 | ++(*aid); | |
377 | code = FindByID(at,*aid); | |
378 | i++; | |
379 | } | |
380 | if (code) return PRNOIDS; | |
381 | cheader.maxID = htonl(*aid); | |
382 | code = pr_Write(at,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID)); | |
383 | if (code) return PRDBFAIL; | |
384 | return PRSUCCESS; | |
385 | } | |
386 | } | |
387 | ||
dba0cf81 | 388 | long IDToName(at, aid, aname) |
389 | register struct ubik_trans *at; | |
390 | long aid; | |
391 | char aname[PR_MAXNAMELEN]; | |
392 | { | |
393 | long temp; | |
394 | struct prentry tentry; | |
395 | register long code; | |
396 | ||
397 | temp = FindByID(at,aid); | |
398 | if (temp == 0) return PRNOENT; | |
399 | code = pr_Read (at, 0, temp, (char *)&tentry, sizeof(tentry)); | |
400 | if (code) return code; | |
401 | strncpy (aname, tentry.name, PR_MAXNAMELEN); | |
402 | return PRSUCCESS; | |
403 | } | |
404 | ||
405 | long NameToID(at, aname, aid) | |
406 | register struct ubik_trans *at; | |
407 | char aname[PR_MAXNAMELEN]; | |
408 | long *aid; | |
409 | { | |
410 | register long code; | |
411 | long temp; | |
412 | struct prentry tentry; | |
413 | ||
414 | temp = FindByName(at,aname); | |
415 | if (!temp) return PRNOENT; | |
416 | code = pr_ReadEntry(at, 0, temp, &tentry); | |
417 | if (code != 0) return code; | |
418 | *aid = tentry.id; | |
419 | return PRSUCCESS; | |
420 | } | |
421 | ||
e1f001e5 | 422 | long IDCmp(a,b) |
423 | long *a; | |
424 | long *b; | |
425 | { | |
426 | /* used to sort CPS's so that comparison with acl's is easier */ | |
427 | if (*a > *b) return 1; | |
428 | if (*a == *b) return 0; | |
429 | if (*a < *b) return -1; | |
430 | } | |
431 | ||
432 | long RemoveFromIDHash(tt,aid,loc) | |
433 | struct ubik_trans *tt; | |
434 | long aid; | |
dba0cf81 | 435 | long *loc; /* ??? in case ID hashed twice ??? */ |
e1f001e5 | 436 | { |
437 | /* remove entry designated by aid from id hash table */ | |
438 | register long code; | |
439 | long current, trail, i; | |
440 | struct prentry tentry; | |
441 | struct prentry bentry; | |
442 | ||
dba0cf81 | 443 | if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT; |
e1f001e5 | 444 | i = IDHash(aid); |
445 | current = ntohl(cheader.idHash[i]); | |
446 | bzero(&tentry,sizeof(tentry)); | |
447 | bzero(&bentry,sizeof(bentry)); | |
448 | trail = 0; | |
dba0cf81 | 449 | if (current == NULL) return PRSUCCESS; /* already gone */ |
e1f001e5 | 450 | code = pr_ReadEntry(tt,0,current,&tentry); |
451 | if (code) return PRDBFAIL; | |
452 | while (aid != tentry.id) { | |
453 | trail = current; | |
454 | current = tentry.nextID; | |
455 | if (current == NULL) break; | |
456 | code = pr_ReadEntry(tt,0,current,&tentry); | |
457 | if (code) return PRDBFAIL; | |
458 | } | |
dba0cf81 | 459 | if (current == NULL) return PRSUCCESS; /* we didn't find him, so he's already gone */ |
e1f001e5 | 460 | if (trail == NULL) { |
461 | /* it's the first entry! */ | |
462 | cheader.idHash[i] = htonl(tentry.nextID); | |
463 | code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i])); | |
464 | if (code) return PRDBFAIL; | |
465 | } | |
466 | else { | |
467 | code = pr_ReadEntry(tt,0,trail, &bentry); | |
468 | if (code) return PRDBFAIL; | |
469 | bentry.nextID = tentry.nextID; | |
470 | code = pr_WriteEntry(tt,0,trail,&bentry); | |
471 | } | |
472 | *loc = current; | |
473 | return PRSUCCESS; | |
474 | } | |
475 | ||
476 | long AddToIDHash(tt, aid, loc) | |
477 | struct ubik_trans *tt; | |
478 | long aid; | |
dba0cf81 | 479 | long loc; /* ??? */ |
e1f001e5 | 480 | { |
481 | /* add entry at loc designated by aid to id hash table */ | |
482 | register long code; | |
483 | long i; | |
484 | struct prentry tentry; | |
485 | ||
dba0cf81 | 486 | if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT; |
e1f001e5 | 487 | i = IDHash(aid); |
488 | bzero(&tentry,sizeof(tentry)); | |
489 | code = pr_ReadEntry(tt,0,loc,&tentry); | |
490 | if (code) return PRDBFAIL; | |
491 | tentry.nextID = ntohl(cheader.idHash[i]); | |
492 | cheader.idHash[i] = htonl(loc); | |
493 | code = pr_WriteEntry(tt,0,loc,&tentry); | |
494 | if (code) return PRDBFAIL; | |
495 | code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i])); | |
496 | if (code) return PRDBFAIL; | |
497 | return PRSUCCESS; | |
498 | } | |
499 | ||
500 | long RemoveFromNameHash(tt,aname,loc) | |
501 | struct ubik_trans *tt; | |
502 | char *aname; | |
503 | long *loc; | |
504 | { | |
505 | /* remove from name hash */ | |
506 | register long code; | |
507 | long current, trail, i; | |
508 | struct prentry tentry; | |
509 | struct prentry bentry; | |
510 | ||
511 | i = NameHash(aname); | |
512 | current = ntohl(cheader.nameHash[i]); | |
513 | bzero(&tentry,sizeof(tentry)); | |
514 | bzero(&bentry,sizeof(bentry)); | |
515 | trail = 0; | |
dba0cf81 | 516 | if (current == NULL) return PRSUCCESS; /* already gone */ |
e1f001e5 | 517 | code = pr_ReadEntry(tt,0,current,&tentry); |
518 | if (code) return PRDBFAIL; | |
519 | while (strcmp(aname,tentry.name)) { | |
520 | trail = current; | |
521 | current = tentry.nextName; | |
522 | if (current == NULL) break; | |
523 | code = pr_ReadEntry(tt,0,current,&tentry); | |
524 | if (code) return PRDBFAIL; | |
525 | } | |
dba0cf81 | 526 | if (current == NULL) return PRSUCCESS; /* we didn't find him, already gone */ |
e1f001e5 | 527 | if (trail == NULL) { |
528 | /* it's the first entry! */ | |
529 | cheader.nameHash[i] = htonl(tentry.nextName); | |
530 | code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i])); | |
531 | if (code) return PRDBFAIL; | |
532 | } | |
533 | else { | |
534 | code = pr_ReadEntry(tt,0,trail, &bentry); | |
535 | if (code) return PRDBFAIL; | |
536 | bentry.nextName = tentry.nextName; | |
537 | code = pr_WriteEntry(tt,0,trail,&bentry); | |
538 | } | |
539 | *loc = current; | |
540 | return PRSUCCESS; | |
541 | } | |
542 | ||
543 | long AddToNameHash(tt, aname, loc) | |
544 | struct ubik_trans *tt; | |
545 | char *aname; | |
546 | long loc; | |
547 | { | |
548 | /* add to name hash */ | |
549 | register long code; | |
550 | long i; | |
551 | struct prentry tentry; | |
552 | ||
553 | i = NameHash(aname); | |
554 | bzero(&tentry,sizeof(tentry)); | |
555 | code = pr_ReadEntry(tt,0,loc,&tentry); | |
556 | if (code) return PRDBFAIL; | |
557 | tentry.nextName = ntohl(cheader.nameHash[i]); | |
558 | cheader.nameHash[i] = htonl(loc); | |
559 | code = pr_WriteEntry(tt,0,loc,&tentry); | |
560 | if (code) return PRDBFAIL; | |
561 | code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i])); | |
562 | if (code) return PRDBFAIL; | |
563 | return PRSUCCESS; | |
564 | } | |
565 | ||
566 | long AddToOwnerChain(at,gid,oid) | |
dba0cf81 | 567 | struct ubik_trans *at; |
568 | long gid; | |
569 | long oid; | |
e1f001e5 | 570 | { |
571 | /* add entry designated by gid to owner chain of entry designated by oid */ | |
572 | register long code; | |
573 | long loc; | |
e1f001e5 | 574 | struct prentry tentry; |
575 | struct prentry gentry; | |
dba0cf81 | 576 | long gloc; |
e1f001e5 | 577 | |
578 | loc = FindByID(at,oid); | |
579 | if (!loc) return PRNOENT; | |
580 | code = pr_ReadEntry(at,0,loc,&tentry); | |
581 | if (code != 0) return PRDBFAIL; | |
dba0cf81 | 582 | if (oid == gid) { /* added it to its own chain */ |
583 | tentry.nextOwned = tentry.owned; | |
584 | tentry.owned = loc; | |
585 | } else { | |
586 | gloc = FindByID(at,gid); | |
587 | code = pr_ReadEntry(at,0,gloc,&gentry); | |
588 | if (code != 0) return PRDBFAIL; | |
589 | gentry.nextOwned = tentry.owned; | |
590 | tentry.owned = gloc; | |
591 | code = pr_WriteEntry(at,0,gloc,&gentry); | |
592 | if (code != 0) return PRDBFAIL; | |
593 | } | |
e1f001e5 | 594 | code = pr_WriteEntry(at,0,loc,&tentry); |
595 | if (code != 0) return PRDBFAIL; | |
e1f001e5 | 596 | return PRSUCCESS; |
597 | } | |
598 | ||
dba0cf81 | 599 | /* RemoveFromOwnerChain - remove gid from owner chain for oid */ |
600 | ||
e1f001e5 | 601 | long RemoveFromOwnerChain(at,gid,oid) |
dba0cf81 | 602 | struct ubik_trans *at; |
603 | long gid; | |
604 | long oid; | |
e1f001e5 | 605 | { |
e1f001e5 | 606 | register long code; |
607 | long nptr; | |
dba0cf81 | 608 | struct prentry thisEntry; |
609 | struct prentry thatEntry; | |
610 | struct prentry *te; /* pointer to current (this) entry */ | |
611 | struct prentry *le; /* pointer to previous (last) entry */ | |
612 | long loc, lastLoc; | |
e1f001e5 | 613 | |
614 | loc = FindByID(at,oid); | |
615 | if (!loc) return PRNOENT; | |
dba0cf81 | 616 | code = pr_ReadEntry (at, 0, loc, &thisEntry); |
e1f001e5 | 617 | if (code != 0) return PRDBFAIL; |
dba0cf81 | 618 | le = &thisEntry; |
619 | lastLoc = 0; | |
620 | nptr = thisEntry.owned; | |
e1f001e5 | 621 | while (nptr != NULL) { |
dba0cf81 | 622 | if (nptr == lastLoc) te = le; |
623 | else { | |
624 | if (&thisEntry == le) te = &thatEntry; | |
625 | else te = &thisEntry; | |
626 | code = pr_ReadEntry (at, 0, nptr, te); | |
e1f001e5 | 627 | if (code != 0) return PRDBFAIL; |
dba0cf81 | 628 | } |
629 | if (te->id == gid) { | |
630 | /* found it */ | |
631 | if (lastLoc == 0) { /* modifying first of chain */ | |
632 | le->owned = te->nextOwned; | |
633 | lastLoc = loc; /* so we write to correct location */ | |
634 | } | |
635 | else le->nextOwned = te->nextOwned; | |
636 | te->nextOwned = 0; | |
637 | if (te != le) { | |
638 | code = pr_WriteEntry (at, 0, nptr, te); | |
639 | if (code != 0) return PRDBFAIL; | |
640 | } | |
641 | code = pr_WriteEntry (at, 0, lastLoc, le); | |
e1f001e5 | 642 | if (code != 0) return PRDBFAIL; |
643 | return PRSUCCESS; | |
644 | } | |
dba0cf81 | 645 | lastLoc = nptr; |
646 | le = te; | |
647 | nptr = te->nextOwned; | |
e1f001e5 | 648 | } |
dba0cf81 | 649 | return PRSUCCESS; /* already removed? */ |
e1f001e5 | 650 | } |
651 | ||
dba0cf81 | 652 | /* AddToOrphan - add gid to orphan list, as it's owner has died */ |
653 | ||
e1f001e5 | 654 | long AddToOrphan(at,gid) |
dba0cf81 | 655 | struct ubik_trans *at; |
656 | long gid; | |
e1f001e5 | 657 | { |
e1f001e5 | 658 | register long code; |
659 | long loc; | |
660 | struct prentry tentry; | |
661 | ||
662 | loc = FindByID(at,gid); | |
663 | if (!loc) return PRNOENT; | |
664 | code = pr_ReadEntry(at,0,loc,&tentry); | |
665 | if (code != 0) return PRDBFAIL; | |
666 | tentry.nextOwned = ntohl(cheader.orphan); | |
dba0cf81 | 667 | code = set_header_word (at, orphan, htonl(loc)); |
e1f001e5 | 668 | if (code != 0) return PRDBFAIL; |
dba0cf81 | 669 | tentry.owner = 0; /* so there's no confusion later */ |
670 | code = pr_WriteEntry(at,0,loc,&tentry); | |
e1f001e5 | 671 | if (code != 0) return PRDBFAIL; |
672 | return PRSUCCESS; | |
673 | } | |
674 | ||
675 | long RemoveFromOrphan(at,gid) | |
676 | struct ubik_trans *at; | |
677 | long gid; | |
678 | { | |
679 | /* remove gid from the orphan list */ | |
680 | register long code; | |
681 | long loc; | |
682 | long nptr; | |
683 | struct prentry tentry; | |
684 | struct prentry bentry; | |
685 | ||
686 | loc = FindByID(at,gid); | |
687 | if (!loc) return PRNOENT; | |
688 | code = pr_ReadEntry(at,0,loc,&tentry); | |
689 | if (code != 0) return PRDBFAIL; | |
690 | if (cheader.orphan == htonl(loc)) { | |
691 | cheader.orphan = htonl(tentry.nextOwned); | |
692 | tentry.nextOwned = 0; | |
693 | code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan)); | |
694 | if (code != 0) return PRDBFAIL; | |
695 | code = pr_WriteEntry(at,0,loc,&tentry); | |
696 | if (code != 0) return PRDBFAIL; | |
697 | return PRSUCCESS; | |
698 | } | |
699 | nptr = ntohl(cheader.orphan); | |
700 | bzero(&bentry,sizeof(bentry)); | |
701 | loc = 0; | |
702 | while (nptr != NULL) { | |
703 | code = pr_ReadEntry(at,0,nptr,&tentry); | |
704 | if (code != 0) return PRDBFAIL; | |
705 | if (gid == tentry.id) { | |
706 | /* found it */ | |
707 | bentry.nextOwned = tentry.nextOwned; | |
708 | tentry.nextOwned = 0; | |
709 | code = pr_WriteEntry(at,0,loc,&bentry); | |
710 | if (code != 0) return PRDBFAIL; | |
711 | code = pr_WriteEntry(at,0,nptr,&tentry); | |
712 | if (code != 0) return PRDBFAIL; | |
713 | return PRSUCCESS; | |
714 | } | |
715 | loc = nptr; | |
716 | nptr = tentry.nextOwned; | |
dba0cf81 | 717 | bcopy(&tentry,&bentry, sizeof(tentry)); |
e1f001e5 | 718 | } |
dba0cf81 | 719 | return PRSUCCESS; |
e1f001e5 | 720 | } |
721 | ||
722 | long IsOwnerOf(at,aid,gid) | |
723 | struct ubik_trans *at; | |
724 | long aid; | |
725 | long gid; | |
726 | { | |
727 | /* returns 1 if aid is the owner of gid, 0 otherwise */ | |
728 | register long code; | |
729 | struct prentry tentry; | |
730 | long loc; | |
731 | ||
732 | loc = FindByID(at,gid); | |
733 | if (!loc) return 0; | |
734 | code = pr_ReadEntry(at,0,loc,&tentry); | |
735 | if (code != 0) return 0; | |
736 | if (tentry.owner == aid) return 1; | |
737 | return 0; | |
738 | } | |
739 | ||
740 | long OwnerOf(at,gid) | |
741 | struct ubik_trans *at; | |
742 | long gid; | |
743 | { | |
744 | /* returns the owner of gid */ | |
745 | register long code; | |
746 | long loc; | |
747 | struct prentry tentry; | |
748 | ||
749 | loc = FindByID(at,gid); | |
750 | if (!loc) return 0; | |
751 | code = pr_ReadEntry(at,0,loc,&tentry); | |
752 | if (code != 0) return 0; | |
753 | return tentry.owner; | |
754 | } | |
755 | ||
756 | ||
e1f001e5 | 757 | long IsAMemberOf(at,aid,gid) |
758 | struct ubik_trans *at; | |
759 | long aid; | |
760 | long gid; | |
761 | { | |
762 | /* returns true if aid is a member of gid */ | |
763 | struct prentry tentry; | |
764 | struct contentry centry; | |
765 | register long code; | |
766 | long i; | |
767 | long loc; | |
768 | ||
dba0cf81 | 769 | /* special case anyuser and authuser */ |
770 | if (gid == ANYUSERID) return 1; | |
771 | if (gid == AUTHUSERID && aid != ANONYMOUSID) return 1; | |
772 | if ((gid == 0) || (aid == 0)) return 0; | |
e1f001e5 | 773 | loc = FindByID(at,gid); |
774 | if (!loc) return 0; | |
775 | bzero(&tentry,sizeof(tentry)); | |
776 | code = pr_ReadEntry(at, 0, loc,&tentry); | |
777 | if (code) return 0; | |
778 | if (!(tentry.flags & PRGRP)) return 0; | |
779 | for (i= 0;i<PRSIZE;i++) { | |
e1f001e5 | 780 | if (tentry.entries[i] == 0) return 0; |
dba0cf81 | 781 | if (tentry.entries[i] == aid) return 1; |
e1f001e5 | 782 | } |
783 | if (tentry.next) { | |
784 | loc = tentry.next; | |
785 | while (loc) { | |
786 | bzero(¢ry,sizeof(centry)); | |
787 | code = pr_ReadCoEntry(at,0,loc,¢ry); | |
788 | if (code) return 0; | |
789 | for (i=0;i<COSIZE;i++) { | |
790 | if (centry.entries[i] == aid) return 1; | |
791 | if (centry.entries[i] == 0) return 0; | |
792 | } | |
793 | loc = centry.next; | |
794 | } | |
795 | } | |
796 | return 0; /* actually, should never get here */ | |
797 | } |