]> andersk Git - moira.git/blame_incremental - afssync/utils.c
Backed out "special" features here (no longer needed)
[moira.git] / afssync / utils.c
... / ...
CommitLineData
1/* Copyright (C) 1989 Transarc Corporation - All rights reserved */
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
8#ifndef lint
9static char rcsid[] = "$Header$";
10#endif
11
12/*
13 Sherri Nichols
14 Information Technology Center
15 November, 1988
16
17
18 Modified May, 1989 by Jeff Schiller to keep disk file in
19 network byte order
20
21*/
22
23#include <afs/param.h>
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>
30#include "ptserver.h"
31#include "pterror.h"
32
33long IDHash(x)
34long x;
35{
36 /* returns hash bucket for x */
37 return ((abs(x)) % HASHSIZE);
38}
39
40long NameHash(aname)
41register 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
53long pr_Write(tt,afd,pos,buff,len)
54struct ubik_trans *tt;
55long afd;
56long pos;
57char *buff;
58long len;
59{
60 /* package up seek and write into one procedure for ease of use */
61 long code;
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 }
66 code = ubik_Seek(tt,afd,pos);
67 if (code) return code;
68 code = ubik_Write(tt,buff,len);
69 return code;
70}
71
72long pr_Read(tt,afd,pos,buff,len)
73struct ubik_trans *tt;
74long afd;
75long pos;
76char *buff;
77long 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
87pr_WriteEntry(tt, afd, pos, tentry)
88struct ubik_trans *tt;
89long afd;
90long pos;
91struct prentry *tentry;
92{
93 long code;
94 register long i;
95 struct prentry nentry;
96
97 if (ntohl(1) != 1) { /* Need to swap bytes. */
98 bzero (&nentry, sizeof(nentry)); /* make sure reseved fields are zero */
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);
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
123 for (i = 0; i < PRSIZE; i++)
124 nentry.entries[i] = htonl(tentry->entries[i]);
125 tentry = &nentry;
126 }
127 code = pr_Write (tt, afd, pos, (char *)tentry, sizeof(struct prentry));
128 return(code);
129}
130
131pr_ReadEntry(tt, afd, pos, tentry)
132struct ubik_trans *tt;
133long afd;
134long pos;
135struct 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);
148 bzero (tentry, sizeof(*tentry)); /* make sure reseved fields are zero */
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);
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
173 for (i = 0; i < PRSIZE; i++)
174 tentry->entries[i] = ntohl(nentry.entries[i]);
175 return(code);
176}
177
178pr_WriteCoEntry(tt, afd, pos, tentry)
179 struct ubik_trans *tt;
180 long afd;
181 long pos;
182 struct contentry *tentry;
183{
184 long code;
185 register long i;
186 struct contentry nentry;
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;
197 }
198 code = pr_Write (tt, afd, pos, (char *)tentry, sizeof(struct contentry));
199 return(code);
200}
201
202pr_ReadCoEntry(tt, afd, pos, tentry)
203struct ubik_trans *tt;
204long afd;
205long pos;
206struct 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);
219 bzero (tentry, sizeof(*tentry)); /* make reseved fields zero */
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
229/* AllocBloc - allocate a free block of storage for entry, returning address of
230 * new entry */
231
232long AllocBlock(at)
233 register struct ubik_trans *at;
234{
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
259long FreeBlock(at, pos)
260register struct ubik_trans *at;
261long 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
278long FindByID(at,aid)
279register struct ubik_trans *at;
280long 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
288 if ((aid == PRBADID) || (aid == 0)) return 0;
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
309long FindByName(at,aname)
310register struct ubik_trans *at;
311char 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
337long AllocID(at,flag,aid)
338register struct ubik_trans *at;
339long flag;
340long *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
388long 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
405long NameToID(at, aname, aid)
406register struct ubik_trans *at;
407char aname[PR_MAXNAMELEN];
408long *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
422long IDCmp(a,b)
423long *a;
424long *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
432long RemoveFromIDHash(tt,aid,loc)
433struct ubik_trans *tt;
434long aid;
435long *loc; /* ??? in case ID hashed twice ??? */
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
443 if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT;
444 i = IDHash(aid);
445 current = ntohl(cheader.idHash[i]);
446 bzero(&tentry,sizeof(tentry));
447 bzero(&bentry,sizeof(bentry));
448 trail = 0;
449 if (current == NULL) return PRSUCCESS; /* already gone */
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 }
459 if (current == NULL) return PRSUCCESS; /* we didn't find him, so he's already gone */
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
476long AddToIDHash(tt, aid, loc)
477struct ubik_trans *tt;
478long aid;
479long loc; /* ??? */
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
486 if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT;
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
500long RemoveFromNameHash(tt,aname,loc)
501struct ubik_trans *tt;
502char *aname;
503long *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;
516 if (current == NULL) return PRSUCCESS; /* already gone */
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 }
526 if (current == NULL) return PRSUCCESS; /* we didn't find him, already gone */
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
543long AddToNameHash(tt, aname, loc)
544struct ubik_trans *tt;
545char *aname;
546long 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
566long AddToOwnerChain(at,gid,oid)
567 struct ubik_trans *at;
568 long gid;
569 long oid;
570{
571 /* add entry designated by gid to owner chain of entry designated by oid */
572 register long code;
573 long loc;
574 struct prentry tentry;
575 struct prentry gentry;
576 long gloc;
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;
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 }
594 code = pr_WriteEntry(at,0,loc,&tentry);
595 if (code != 0) return PRDBFAIL;
596 return PRSUCCESS;
597}
598
599/* RemoveFromOwnerChain - remove gid from owner chain for oid */
600
601long RemoveFromOwnerChain(at,gid,oid)
602 struct ubik_trans *at;
603 long gid;
604 long oid;
605{
606 register long code;
607 long nptr;
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;
613
614 loc = FindByID(at,oid);
615 if (!loc) return PRNOENT;
616 code = pr_ReadEntry (at, 0, loc, &thisEntry);
617 if (code != 0) return PRDBFAIL;
618 le = &thisEntry;
619 lastLoc = 0;
620 nptr = thisEntry.owned;
621 while (nptr != NULL) {
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);
627 if (code != 0) return PRDBFAIL;
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);
642 if (code != 0) return PRDBFAIL;
643 return PRSUCCESS;
644 }
645 lastLoc = nptr;
646 le = te;
647 nptr = te->nextOwned;
648 }
649 return PRSUCCESS; /* already removed? */
650}
651
652/* AddToOrphan - add gid to orphan list, as it's owner has died */
653
654long AddToOrphan(at,gid)
655 struct ubik_trans *at;
656 long gid;
657{
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);
667 code = set_header_word (at, orphan, htonl(loc));
668 if (code != 0) return PRDBFAIL;
669 tentry.owner = 0; /* so there's no confusion later */
670 code = pr_WriteEntry(at,0,loc,&tentry);
671 if (code != 0) return PRDBFAIL;
672 return PRSUCCESS;
673}
674
675long RemoveFromOrphan(at,gid)
676struct ubik_trans *at;
677long 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;
717 bcopy(&tentry,&bentry, sizeof(tentry));
718 }
719 return PRSUCCESS;
720}
721
722long IsOwnerOf(at,aid,gid)
723struct ubik_trans *at;
724long aid;
725long 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
740long OwnerOf(at,gid)
741struct ubik_trans *at;
742long 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
757long IsAMemberOf(at,aid,gid)
758struct ubik_trans *at;
759long aid;
760long 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
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;
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++) {
780 if (tentry.entries[i] == 0) return 0;
781 if (tentry.entries[i] == aid) return 1;
782 }
783 if (tentry.next) {
784 loc = tentry.next;
785 while (loc) {
786 bzero(&centry,sizeof(centry));
787 code = pr_ReadCoEntry(at,0,loc,&centry);
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}
This page took 0.076642 seconds and 5 git commands to generate.