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