home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / coda / part02 / adt.c next >
C/C++ Source or Header  |  1990-04-08  |  7KB  |  333 lines

  1. /*
  2. **  Copyright 1989 BBN Systems and Technologies Corporation.
  3. **  All Rights Reserved.
  4. **  This is free software, and may be distributed under the terms of the
  5. **  GNU Public License; see the file COPYING for more details.
  6. **
  7. **  Data abstractions for CODA server.
  8. */
  9. #include "server.h"
  10. #include <sys/stat.h>
  11. #ifdef    RCSID
  12. static char RCS[] =
  13.     "$Header: adt.c,v 2.0 90/03/23 14:40:58 rsalz Exp $";
  14. #endif    /* RCSID */
  15.  
  16.  
  17. /*
  18. **  A class maps a name to a list of strings.  It's like a recursive
  19. **  definition of a collection.  We keep a linked list of all our maps.
  20. */
  21. typedef struct _CLASS {
  22.     struct _CLASS    *Next;        /* Next one            */
  23.     char        *Name;        /* The name            */
  24.     int            NumHosts;    /* Number of hosts in the class    */
  25.     int            MaxHosts;    /* Amount of space allocated    */
  26.     char        **Hosts;    /* List of hosts        */
  27.     int            NumClasses;    /* Number of classes        */
  28.     int            MaxClasses;    /* Amount of space allocated    */
  29.     char        **Classes;    /* List of classes in the class    */
  30. } CLASS;
  31.  
  32.  
  33. STATIC CLASS    BaseClass;        /* Our linked list of classes    */
  34. STATIC STRLIST    BaseHost;        /* List of hosts in Codafile    */
  35. STATIC int    MaxItem;        /* Size of "Item" array        */
  36.  
  37.  
  38.  
  39. /*
  40. **  Remove all defined blocks, classes, and hosts.  This is not likely to
  41. **  be called too often, so just flush memory -- the Add...() routines
  42. **  share pointers so a free'ing would be a bit of work.  We use shared
  43. **  pointers not to save space, but to make string compares fast.
  44. */
  45. void
  46. ResetStorage()
  47. {
  48.     BaseBlock.Next = NULL;
  49.     BaseClass.Next = NULL;
  50.     BaseHost.Next = NULL;
  51.     ResetItem();
  52. }
  53.  
  54.  
  55. void
  56. ResetItem()
  57. {
  58.     register ITEM    *I;
  59.     register ITEM    *Iend;
  60.  
  61.     NumItem = 0;
  62.     if (BaseItem == NULL) {
  63.     /* Since we can't trust realloc(NULL, ...) yet... */
  64.     MaxItem = ITEM_DELTA;
  65.     BaseItem = NEW(ITEM, MaxItem);
  66.     }
  67.     else
  68.     /* Free old strings. */
  69.     for (I = BaseItem, Iend = &BaseItem[NumItem]; I < Iend; I++)
  70.         free(I->Name);
  71. }
  72.  
  73.  
  74.  
  75. /*
  76. **  Guarantee an instantiation of a class.
  77. */
  78. STATIC CLASS *
  79. FindOrCreateClass(Name)
  80.     register char    *Name;
  81. {
  82.     register CLASS    *C;
  83.  
  84.     /* Rummage through the list. */
  85.     for (C = BaseClass.Next; C; C = C->Next)
  86.     if (EQ(C->Name, Name))
  87.         return C;
  88.  
  89.     /* Create a new class, add it to the list. */
  90.     C = NEW(CLASS, 1);
  91.     C->Next = BaseClass.Next;
  92.     C->Name = Name;
  93.     C->NumHosts = 0;
  94.     C->MaxHosts = HOST_DELTA;
  95.     C->Hosts = NEW(char*, C->MaxHosts);
  96.     C->NumClasses = 0;
  97.     C->MaxClasses = CLASS_DELTA;
  98.     C->Classes = NEW(char*, C->MaxClasses);
  99.     BaseClass.Next = C;
  100.     return C;
  101. }
  102.  
  103.  
  104. /*
  105. **  Add a host to a class.
  106. */
  107. void
  108. AddHostToClass(Name, Host)
  109.     register char    *Name;
  110.     register char    *Host;
  111. {
  112.     register char    **str;
  113.     register CLASS    *C;
  114.     register int    i;
  115.  
  116.     C = FindOrCreateClass(Name);
  117.  
  118.     /* Look through list of hosts, see if it's already there. */
  119.     for (i = C->NumHosts, str = C->Hosts; --i >= 0; str++)
  120.     if (EQ(Host, *str))
  121.         return;
  122.  
  123.     /* Have to add it; do we need more room? */
  124.     if (C->NumHosts == C->MaxHosts - 1) {
  125.     C->MaxHosts += HOST_DELTA;
  126.     C->Hosts = GROW(C->Hosts, char*, C->MaxHosts);
  127.     }
  128.  
  129.     /* Add it. */
  130.     C->Hosts[C->NumHosts++] = Host;
  131. }
  132.  
  133.  
  134. /*
  135. **  Add a class to a class.
  136. */
  137. STATIC void
  138. AddClassToClass(C, Name)
  139.     register CLASS    *C;
  140.     register char    *Name;
  141. {
  142.     register char    **str;
  143.     register int    i;
  144.  
  145.     /* Look through list of classes, see if it's already there. */
  146.     for (i = C->NumClasses, str = C->Classes; --i >= 0; str++)
  147.     if (EQ(Name, *str))
  148.         return;
  149.  
  150.     /* Have to add it; do we need more room? */
  151.     if (C->NumClasses == C->MaxClasses - 1) {
  152.     C->MaxClasses += CLASS_DELTA;
  153.     C->Classes = GROW(C->Classes, char*, C->MaxClasses);
  154.     }
  155.  
  156.     /* Add it. */
  157.     C->Classes[C->NumClasses++] = Name;
  158. }
  159.  
  160.  
  161.  
  162. /*
  163. **  Add a list of classes to a class.
  164. */
  165. void
  166. AddClassesToClass(Name, L)
  167.     register char    *Name;
  168.     register STRLIST    *L;
  169. {
  170.     register CLASS    *C;
  171.  
  172.     for (C = FindOrCreateClass(Name); L; L = L->Next)
  173.     AddClassToClass(C, L->Value);
  174. }
  175.  
  176.  
  177.  
  178. /*
  179. **  Return TRUE if the host is a member of the specified class.
  180. */
  181. int
  182. HostIsInClass(Host, Class)
  183.     register char    *Host;
  184.     register char    *Class;
  185. {
  186.     static char        Everyone[] = ALL;
  187.     register char    **str;
  188.     register CLASS    *C;
  189.     register int    i;
  190.  
  191.     /* Almost everyone is in the built-in class. */
  192.     if (EQ(Class, Everyone))
  193.     return !EQ(Host, UnknownHost) && HostWasDeclared(Host);
  194.  
  195.     /* Nobody is in undefined classes. */
  196.     for (C = BaseClass.Next; C; C = C->Next)
  197.     if (EQ(C->Name, Class))
  198.         break;
  199.     if (C == NULL)
  200.     return FALSE;
  201.  
  202.     /* Look through list of hosts, see if it's already there. */
  203.     for (i = C->NumHosts, str = C->Hosts; --i >= 0; str++)
  204.     if (EQ(Host, *str))
  205.         return TRUE;
  206.  
  207.     /* Recursively look through list of classes. */
  208.     for (i = C->NumClasses, str = C->Classes; --i >= 0; str++)
  209.     if (HostIsInClass(Host, *str))
  210.         return TRUE;
  211.  
  212.     /* Not there. */
  213.     return FALSE;
  214. }
  215.  
  216.  
  217. /*
  218. **  Look through the list of hosts, see if we've got that one.
  219. */
  220. int
  221. HostWasDeclared(Name)
  222.     register char    *Name;
  223. {
  224.     register STRLIST    *S;
  225.  
  226.     /* Rummage through the list. */
  227.     for (S = BaseHost.Next; S; S = S->Next)
  228.     if (EQ(S->Value, Name))
  229.         return TRUE;
  230.  
  231.     return FALSE;
  232. }
  233.  
  234.  
  235. /*
  236. **  Add a host to our list of known hosts.
  237. */
  238. void
  239. DefineHost(Host, Class)
  240.     char    *Host;
  241.     char    *Class;
  242. {
  243.     STRLIST    *S;
  244.  
  245.     S = NEW(STRLIST, 1);
  246.     S->Value = Host;
  247.     S->Next = BaseHost.Next;
  248.     BaseHost.Next = S;
  249.     AddHostToClass(Class, Host);
  250. }
  251.  
  252.  
  253.  
  254. /*
  255. **  Look through the list of blocks, see if we've got that one.
  256. */
  257. BLOCK *
  258. FindBlock(Name)
  259.     register char    *Name;
  260. {
  261.     register BLOCK    *B;
  262.  
  263.     /* Rummage through the list. */
  264.     for (B = BaseBlock.Next; B; B = B->Next)
  265.     if (EQ(B->Name, Name))
  266.         return B;
  267.     return NULL;
  268. }
  269.  
  270.  
  271.  
  272. /*
  273. **  Add to the list of things sent.
  274. */
  275. void
  276. AddItemToList(Name, Sb)
  277.     char    *Name;
  278.     struct stat    *Sb;
  279. {
  280.     ITEM    *I;
  281.  
  282.     /* Need more room? */
  283.     if (NumItem == MaxItem - 1) {
  284.     MaxItem += ITEM_DELTA;
  285.     BaseItem = GROW(BaseItem, ITEM, MaxItem);
  286.     }
  287.  
  288.     I = &BaseItem[NumItem++];
  289.     I->Name    = COPY(Name);
  290.     I->Uid    = Sb->st_uid;
  291.     I->Gid    = Sb->st_gid;
  292.     I->Directory= (Sb->st_mode & S_IFMT) == S_IFDIR;
  293.     I->Size    = Sb->st_size;
  294.     I->Time    = Sb->st_mtime;
  295.     I->Mode    = Sb->st_mode & 0777;
  296. }
  297.  
  298.  
  299. STATIC int
  300. ItemCompare(I1, I2)
  301.     ITEM    *I1;
  302.     ITEM    *I2;
  303. {
  304.     return strcmp(I1->Name, I2->Name);
  305. }
  306.  
  307.  
  308. /*
  309. **  Sort our array.
  310. */
  311. void
  312. SortItem()
  313. {
  314.     qsort((char *)BaseItem, NumItem, sizeof *BaseItem, ItemCompare);
  315. }
  316.  
  317.  
  318. /*
  319. **  Use the bsearch() routine to find the item.
  320. */
  321. ITEM *
  322. FindItem(Name)
  323.     char    *Name;
  324. {
  325.     ITEM    *I;
  326.     ITEM    Key;
  327.  
  328.     Key.Name = Name;
  329.     I = (ITEM *)bsearch((char *)&Key, (char *)BaseItem,
  330.             (unsigned int)NumItem, sizeof *BaseItem, ItemCompare);
  331.     return I;
  332. }
  333.