home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright 1989 BBN Systems and Technologies Corporation.
- ** All Rights Reserved.
- ** This is free software, and may be distributed under the terms of the
- ** GNU Public License; see the file COPYING for more details.
- **
- ** Data abstractions for CODA server.
- */
- #include "server.h"
- #include <sys/stat.h>
- #ifdef RCSID
- static char RCS[] =
- "$Header: adt.c,v 2.0 90/03/23 14:40:58 rsalz Exp $";
- #endif /* RCSID */
-
-
- /*
- ** A class maps a name to a list of strings. It's like a recursive
- ** definition of a collection. We keep a linked list of all our maps.
- */
- typedef struct _CLASS {
- struct _CLASS *Next; /* Next one */
- char *Name; /* The name */
- int NumHosts; /* Number of hosts in the class */
- int MaxHosts; /* Amount of space allocated */
- char **Hosts; /* List of hosts */
- int NumClasses; /* Number of classes */
- int MaxClasses; /* Amount of space allocated */
- char **Classes; /* List of classes in the class */
- } CLASS;
-
-
- STATIC CLASS BaseClass; /* Our linked list of classes */
- STATIC STRLIST BaseHost; /* List of hosts in Codafile */
- STATIC int MaxItem; /* Size of "Item" array */
-
-
-
- /*
- ** Remove all defined blocks, classes, and hosts. This is not likely to
- ** be called too often, so just flush memory -- the Add...() routines
- ** share pointers so a free'ing would be a bit of work. We use shared
- ** pointers not to save space, but to make string compares fast.
- */
- void
- ResetStorage()
- {
- BaseBlock.Next = NULL;
- BaseClass.Next = NULL;
- BaseHost.Next = NULL;
- ResetItem();
- }
-
-
- void
- ResetItem()
- {
- register ITEM *I;
- register ITEM *Iend;
-
- NumItem = 0;
- if (BaseItem == NULL) {
- /* Since we can't trust realloc(NULL, ...) yet... */
- MaxItem = ITEM_DELTA;
- BaseItem = NEW(ITEM, MaxItem);
- }
- else
- /* Free old strings. */
- for (I = BaseItem, Iend = &BaseItem[NumItem]; I < Iend; I++)
- free(I->Name);
- }
-
-
-
- /*
- ** Guarantee an instantiation of a class.
- */
- STATIC CLASS *
- FindOrCreateClass(Name)
- register char *Name;
- {
- register CLASS *C;
-
- /* Rummage through the list. */
- for (C = BaseClass.Next; C; C = C->Next)
- if (EQ(C->Name, Name))
- return C;
-
- /* Create a new class, add it to the list. */
- C = NEW(CLASS, 1);
- C->Next = BaseClass.Next;
- C->Name = Name;
- C->NumHosts = 0;
- C->MaxHosts = HOST_DELTA;
- C->Hosts = NEW(char*, C->MaxHosts);
- C->NumClasses = 0;
- C->MaxClasses = CLASS_DELTA;
- C->Classes = NEW(char*, C->MaxClasses);
- BaseClass.Next = C;
- return C;
- }
-
-
- /*
- ** Add a host to a class.
- */
- void
- AddHostToClass(Name, Host)
- register char *Name;
- register char *Host;
- {
- register char **str;
- register CLASS *C;
- register int i;
-
- C = FindOrCreateClass(Name);
-
- /* Look through list of hosts, see if it's already there. */
- for (i = C->NumHosts, str = C->Hosts; --i >= 0; str++)
- if (EQ(Host, *str))
- return;
-
- /* Have to add it; do we need more room? */
- if (C->NumHosts == C->MaxHosts - 1) {
- C->MaxHosts += HOST_DELTA;
- C->Hosts = GROW(C->Hosts, char*, C->MaxHosts);
- }
-
- /* Add it. */
- C->Hosts[C->NumHosts++] = Host;
- }
-
-
- /*
- ** Add a class to a class.
- */
- STATIC void
- AddClassToClass(C, Name)
- register CLASS *C;
- register char *Name;
- {
- register char **str;
- register int i;
-
- /* Look through list of classes, see if it's already there. */
- for (i = C->NumClasses, str = C->Classes; --i >= 0; str++)
- if (EQ(Name, *str))
- return;
-
- /* Have to add it; do we need more room? */
- if (C->NumClasses == C->MaxClasses - 1) {
- C->MaxClasses += CLASS_DELTA;
- C->Classes = GROW(C->Classes, char*, C->MaxClasses);
- }
-
- /* Add it. */
- C->Classes[C->NumClasses++] = Name;
- }
-
-
-
- /*
- ** Add a list of classes to a class.
- */
- void
- AddClassesToClass(Name, L)
- register char *Name;
- register STRLIST *L;
- {
- register CLASS *C;
-
- for (C = FindOrCreateClass(Name); L; L = L->Next)
- AddClassToClass(C, L->Value);
- }
-
-
-
- /*
- ** Return TRUE if the host is a member of the specified class.
- */
- int
- HostIsInClass(Host, Class)
- register char *Host;
- register char *Class;
- {
- static char Everyone[] = ALL;
- register char **str;
- register CLASS *C;
- register int i;
-
- /* Almost everyone is in the built-in class. */
- if (EQ(Class, Everyone))
- return !EQ(Host, UnknownHost) && HostWasDeclared(Host);
-
- /* Nobody is in undefined classes. */
- for (C = BaseClass.Next; C; C = C->Next)
- if (EQ(C->Name, Class))
- break;
- if (C == NULL)
- return FALSE;
-
- /* Look through list of hosts, see if it's already there. */
- for (i = C->NumHosts, str = C->Hosts; --i >= 0; str++)
- if (EQ(Host, *str))
- return TRUE;
-
- /* Recursively look through list of classes. */
- for (i = C->NumClasses, str = C->Classes; --i >= 0; str++)
- if (HostIsInClass(Host, *str))
- return TRUE;
-
- /* Not there. */
- return FALSE;
- }
-
-
- /*
- ** Look through the list of hosts, see if we've got that one.
- */
- int
- HostWasDeclared(Name)
- register char *Name;
- {
- register STRLIST *S;
-
- /* Rummage through the list. */
- for (S = BaseHost.Next; S; S = S->Next)
- if (EQ(S->Value, Name))
- return TRUE;
-
- return FALSE;
- }
-
-
- /*
- ** Add a host to our list of known hosts.
- */
- void
- DefineHost(Host, Class)
- char *Host;
- char *Class;
- {
- STRLIST *S;
-
- S = NEW(STRLIST, 1);
- S->Value = Host;
- S->Next = BaseHost.Next;
- BaseHost.Next = S;
- AddHostToClass(Class, Host);
- }
-
-
-
- /*
- ** Look through the list of blocks, see if we've got that one.
- */
- BLOCK *
- FindBlock(Name)
- register char *Name;
- {
- register BLOCK *B;
-
- /* Rummage through the list. */
- for (B = BaseBlock.Next; B; B = B->Next)
- if (EQ(B->Name, Name))
- return B;
- return NULL;
- }
-
-
-
- /*
- ** Add to the list of things sent.
- */
- void
- AddItemToList(Name, Sb)
- char *Name;
- struct stat *Sb;
- {
- ITEM *I;
-
- /* Need more room? */
- if (NumItem == MaxItem - 1) {
- MaxItem += ITEM_DELTA;
- BaseItem = GROW(BaseItem, ITEM, MaxItem);
- }
-
- I = &BaseItem[NumItem++];
- I->Name = COPY(Name);
- I->Uid = Sb->st_uid;
- I->Gid = Sb->st_gid;
- I->Directory= (Sb->st_mode & S_IFMT) == S_IFDIR;
- I->Size = Sb->st_size;
- I->Time = Sb->st_mtime;
- I->Mode = Sb->st_mode & 0777;
- }
-
-
- STATIC int
- ItemCompare(I1, I2)
- ITEM *I1;
- ITEM *I2;
- {
- return strcmp(I1->Name, I2->Name);
- }
-
-
- /*
- ** Sort our array.
- */
- void
- SortItem()
- {
- qsort((char *)BaseItem, NumItem, sizeof *BaseItem, ItemCompare);
- }
-
-
- /*
- ** Use the bsearch() routine to find the item.
- */
- ITEM *
- FindItem(Name)
- char *Name;
- {
- ITEM *I;
- ITEM Key;
-
- Key.Name = Name;
- I = (ITEM *)bsearch((char *)&Key, (char *)BaseItem,
- (unsigned int)NumItem, sizeof *BaseItem, ItemCompare);
- return I;
- }
-