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