source: trunk/third/moira/afssync/utils.c @ 24319

Revision 24319, 21.1 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
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[] = "$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/afssync/utils.c $ $Id: utils.c 3956 2010-01-05 20:56:56Z zacheiss $";
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 != 0) {
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 != 0) {
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 == 0) 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 == 0) break;
456        code = pr_ReadEntry(tt,0,current,&tentry);
457        if (code) return PRDBFAIL;
458    }
459    if (current == 0) return PRSUCCESS;  /* we didn't find him, so he's already gone */
460    if (trail == 0) {
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 == 0) 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 == 0) break;
523        code = pr_ReadEntry(tt,0,current,&tentry);
524        if (code) return PRDBFAIL;
525    }
526    if (current == 0) return PRSUCCESS;  /* we didn't find him, already gone */
527    if (trail == 0) {
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 != 0) {
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 != 0) {
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}
Note: See TracBrowser for help on using the repository browser.