home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d832 / term.lha / Term / term-3.1-Source.lha / termPhone.c < prev    next >
C/C++ Source or Header  |  1993-02-19  |  16KB  |  718 lines

  1. /*
  2. **    termPhone.c
  3. **
  4. **    Phonebook support routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* RemoveDialEntry(LONG Entry):
  13.      *
  14.      *    Remove a phone book entry from the dial list.
  15.      */
  16.  
  17. VOID
  18. RemoveDialEntry(LONG Entry)
  19. {
  20.     LONG Count = Phonebook[Entry] -> Count,i;
  21.  
  22.     for(i = 0 ; i < NumPhoneEntries ; i++)
  23.     {
  24.         if(Phonebook[i] -> Count > Count)
  25.             SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Header -> Name);
  26.     }
  27.  
  28.     Phonebook[Entry] -> Count = -1;
  29.  
  30.     SPrintf(Phonebook[Entry] -> Node -> LocalName,"      %s",Phonebook[Entry] -> Header -> Name);
  31. }
  32.  
  33.     /* RemoveDialNode(struct PhoneNode *Node):
  34.      *
  35.      *    Remove a node from the dialing list.
  36.      */
  37.  
  38. VOID
  39. RemoveDialNode(struct PhoneNode *Node)
  40. {
  41.     if(Node -> VanillaNode . ln_Name[0])
  42.     {
  43.         LONG Count = Node -> Entry -> Count,i;
  44.  
  45.         for(i = 0 ; i < NumPhoneEntries ; i++)
  46.         {
  47.             if(Phonebook[i] -> Count > Count)
  48.                 SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Header -> Name);
  49.         }
  50.  
  51.         Node -> Entry -> Count = -1;
  52.  
  53.         SPrintf(Node -> LocalName,"      %s",Node -> Entry -> Header -> Name);
  54.     }
  55. }
  56.  
  57.     /* SortToList(struct PhoneNode *PhoneNode):
  58.      *
  59.      *    Add a node to the dial list.
  60.      */
  61.  
  62. VOID
  63. SortToList(struct PhoneNode *PhoneNode)
  64. {
  65.     if(!DialList)
  66.     {
  67.         if(DialList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY))
  68.             NewList(DialList);
  69.     }
  70.  
  71.     if(DialList)
  72.     {
  73.         struct PhoneNode *Node = (struct PhoneNode *)DialList -> lh_Head,*NewNode;
  74.  
  75.         if(NewNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode),MEMF_ANY))
  76.         {
  77.             CopyMem(PhoneNode,NewNode,sizeof(struct PhoneNode));
  78.  
  79.             while(Node -> VanillaNode . ln_Succ)
  80.             {
  81.                 if(Node -> Entry -> Count > NewNode -> Entry -> Count)
  82.                 {
  83.                     if(Node == (struct PhoneNode *)DialList -> lh_Head)
  84.                         AddHead(DialList,&NewNode -> VanillaNode);
  85.                     else
  86.                         Insert(DialList,&NewNode -> VanillaNode,Node -> VanillaNode . ln_Pred);
  87.  
  88.                     return;
  89.                 }
  90.  
  91.                 Node = (struct PhoneNode *)Node -> VanillaNode . ln_Succ;
  92.             }
  93.  
  94.             AddTail(DialList,&NewNode -> VanillaNode);
  95.         }
  96.     }
  97. }
  98.  
  99.     /* FreeDialList(BYTE ClearAll):
  100.      *
  101.      *    Release the contents of the dial list.
  102.      */
  103.  
  104. VOID
  105. FreeDialList(BYTE ClearAll)
  106. {
  107.     if(DialList)
  108.     {
  109.         struct PhoneNode    *NextNode,
  110.                     *SubNode;
  111.  
  112.         SubNode = (struct PhoneNode *)DialList -> lh_Head;
  113.  
  114.         while(NextNode = (struct PhoneNode *)SubNode -> VanillaNode . ln_Succ)
  115.         {
  116.             if(ClearAll || !SubNode -> VanillaNode . ln_Name[0])
  117.                 FreeVec(SubNode);
  118.  
  119.             SubNode = NextNode;
  120.         }
  121.  
  122.         FreeVec(DialList);
  123.  
  124.         DialList = NULL;
  125.     }
  126. }
  127.  
  128.     /* CreatePhoneList():
  129.      *
  130.      *    Turn the array of pointers to phonebook entries into
  131.      *    a linked standard Amiga List (gadtools needs this).
  132.      */
  133.  
  134. struct List *
  135. CreatePhoneList()
  136. {
  137.     struct List        *PhoneList;
  138.     struct PhoneNode    *PhoneNode;
  139.     LONG             i;
  140.  
  141.     if(Phonebook && NumPhoneEntries)
  142.     {
  143.         if(PhoneList = (struct List *)AllocVec(sizeof(struct List) + NumPhoneEntries * sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  144.         {
  145.             NewList(PhoneList);
  146.  
  147.             PhoneNode = (struct PhoneNode *)(PhoneList + 1);
  148.  
  149.             for(i = 0 ; i < NumPhoneEntries ; i++)
  150.             {
  151.                 if(Phonebook[i] -> Count != -1)
  152.                     SPrintf(PhoneNode[i] . LocalName,"%3ld - %s",Phonebook[i] -> Count + 1,Phonebook[i] -> Header -> Name);
  153.                 else
  154.                     SPrintf(PhoneNode[i] . LocalName,"      %s",Phonebook[i] -> Header -> Name);
  155.  
  156.                 PhoneNode[i] . VanillaNode . ln_Name = PhoneNode[i] . LocalName;
  157.  
  158.                 Phonebook[i] -> Node = &PhoneNode[i];
  159.  
  160.                 PhoneNode[i] . Entry = Phonebook[i];
  161.  
  162.                 AddTail(PhoneList,&PhoneNode[i]);
  163.             }
  164.  
  165.             return(PhoneList);
  166.         }
  167.     }
  168.     else
  169.     {
  170.         if(PhoneList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY | MEMF_CLEAR))
  171.         {
  172.             NewList(PhoneList);
  173.  
  174.             return(PhoneList);
  175.         }
  176.     }
  177.  
  178.     return(NULL);
  179. }
  180.  
  181.     /* DeletePhoneList(struct List *PhoneList):
  182.      *
  183.      *    Delete the entries listed in the Amiga List
  184.      *    created by the routine above.
  185.      */
  186.  
  187. VOID
  188. DeletePhoneList(struct List *PhoneList)
  189. {
  190.     if(PhoneList)
  191.         FreeVec(PhoneList);
  192. }
  193.  
  194.     /* Compare(struct PhoneEntry **A,struct PhoneEntry **B):
  195.      *
  196.      *    Comparison subroutine required by the QuickSort
  197.      *    call below.
  198.      */
  199.  
  200. STATIC int __stdargs
  201. Compare(struct PhoneEntry **A,struct PhoneEntry **B)
  202. {
  203.         /* Has entry A been selected? */
  204.  
  205.     if((*A) -> Count == -1)
  206.     {
  207.             /* If entry B isn't selected either, compare the
  208.              * names lexically, else entry B is supposed
  209.              * to be `smaller' than entry A.
  210.              */
  211.  
  212.         if((*B) -> Count == -1)
  213.             return(Stricmp((*A) -> Header -> Name,(*B) -> Header -> Name));
  214.         else
  215.             return(1);
  216.     }
  217.     else
  218.     {
  219.             /* If entry B isn't selected, entry A is supposed
  220.              * to be `smaller' than entry B, else return
  221.              * the difference between both entries.
  222.              */
  223.  
  224.         if((*B) -> Count == -1)
  225.             return(-1);
  226.         else
  227.             return((*A) -> Count - (*B) -> Count);
  228.     }
  229. }
  230.  
  231.     /* SortPhoneEntries():
  232.      *
  233.      *    Sorts the current phone list array in ascending order.
  234.      */
  235.  
  236. VOID
  237. SortPhoneEntries()
  238. {
  239.     qsort((APTR)Phonebook,NumPhoneEntries,sizeof(struct PhoneEntry *),Compare);
  240. }
  241.  
  242.     /* FreeTimeDateNode(struct TimeDateNode *Node):
  243.      *
  244.      *    Free the memory allocated for a TimeDateNode and
  245.      *    the associated data table.
  246.      */
  247.  
  248. VOID __regargs
  249. FreeTimeDateNode(struct TimeDateNode *Node)
  250. {
  251.     FreeVec(Node -> Table);
  252.  
  253.     FreeVec(Node);
  254. }
  255.  
  256.     /* FreeTimeDateList(struct List *List):
  257.      *
  258.      *    Free a list of TimeDateNodes.
  259.      */
  260.  
  261. VOID
  262. FreeTimeDateList(struct List *List)
  263. {
  264.     struct Node *Node,*NextNode;
  265.  
  266.     Node = List -> lh_Head;
  267.  
  268.     while(NextNode = Node -> ln_Succ)
  269.     {
  270.         Remove(Node);
  271.  
  272.         FreeTimeDateNode((struct TimeDateNode *)Node);
  273.  
  274.         Node = NextNode;
  275.     }
  276. }
  277.  
  278.     /* CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst):
  279.      *
  280.      *    Copies the TimeDateNode list from one location into
  281.      *    another.
  282.      */
  283.  
  284. VOID
  285. CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst)
  286. {
  287.     struct TimeDateNode *FromNode,*ToNode;
  288.  
  289.     FromNode = (struct TimeDateNode *)From -> lh_Head;
  290.  
  291.     if(SkipFirst)
  292.         FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
  293.  
  294.     while(FromNode -> VanillaNode . ln_Succ)
  295.     {
  296.         if(ToNode = (struct TimeDateNode *)AllocVec(sizeof(struct TimeDateNode),MEMF_ANY))
  297.         {
  298.             CopyMem(FromNode,ToNode,sizeof(struct TimeDateNode));
  299.  
  300.             ToNode -> VanillaNode . ln_Name = ToNode -> Buffer;
  301.  
  302.             if(ToNode -> Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * FromNode -> Table[0] . Count,MEMF_ANY))
  303.             {
  304.                 CopyMem(FromNode -> Table,ToNode -> Table,sizeof(struct TimeDate) * FromNode -> Table[0] . Count);
  305.  
  306.                 AddTail(To,&ToNode -> VanillaNode);
  307.             }
  308.             else
  309.                 FreeVec(ToNode);
  310.         }
  311.  
  312.         FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
  313.     }
  314. }
  315.  
  316.     /* AdaptTimeDateNode(struct TimeDateNode *Node):
  317.      *
  318.      *    Adapt the title and comment of a TimeDateNode.
  319.      */
  320.  
  321. VOID
  322. AdaptTimeDateNode(struct TimeDateNode *Node)
  323. {
  324.     STRPTR Comment = Node -> Header . Comment[0] ? Node -> Header . Comment : LocaleString(MSG_TERMPHONE_NO_COMMENT_TXT);
  325.  
  326.     if(Node -> Header . Month == -1)
  327.     {
  328.         if(Node -> Header . Day == -1)
  329.             strcpy(Node -> Buffer,LocaleString(MSG_TERMPHONE_STANDARD_SETTINGS_TXT));
  330.         else
  331.             SPrintf(Node -> Buffer,LocaleString(MSG_TERMPHONE_DAYS_TXT),Comment);
  332.     }
  333.     else
  334.         SPrintf(Node -> Buffer,"%2ld %s » %s",Node -> Header . Day,LocaleString(MSG_TERMPHONE_JAN_TXT + Node -> Header . Month),Comment);
  335. }
  336.  
  337.     /* TimeCompare(struct TimeDate *A,struct TimeDate *B):
  338.      *
  339.      *    Comparison routine required by SortTimeTable().
  340.      */
  341.  
  342. STATIC int __stdargs
  343. TimeCompare(struct TimeDate *A,struct TimeDate *B)
  344. {
  345.     return(((LONG)A -> Time) - ((LONG)B -> Time));
  346. }
  347.  
  348.     /* SortTimeTable(struct TimeDateNode *Node):
  349.      *
  350.      *    Sort the time table associated with a
  351.      *    TimeDateNode in ascending order.
  352.      */
  353.  
  354. VOID
  355. SortTimeTable(struct TimeDateNode *Node)
  356. {
  357.     qsort((APTR)Node -> Table,Node -> Table[0] . Count,sizeof(struct TimeDate),TimeCompare);
  358. }
  359.  
  360.     /* BuildTimeList(struct TimeDateNode *Node):
  361.      *
  362.      *    Build a read-to-display time table list from a TimeDateNode.
  363.      */
  364.  
  365. struct List *
  366. BuildTimeList(struct TimeDateNode *Node)
  367. {
  368.     struct List *List;
  369.  
  370.     if(List = (struct List *)AllocVec(sizeof(struct List) + Node -> Table[0] . Count * sizeof(struct TimeNode),MEMF_ANY | MEMF_CLEAR))
  371.     {
  372.         struct TimeNode    *Time = (struct TimeNode *)(List + 1);
  373.         LONG         i;
  374.  
  375.         NewList(List);
  376.  
  377.         for(i = 0 ; i < Node -> Table[0] . Count ; i++)
  378.         {
  379.             Time[i] . VanillaNode . ln_Name    = Time[i] . Name;
  380.             Time[i] . Time            = Node -> Table[i] . Time;
  381.  
  382.             SPrintf(Time[i] . Name,"%2ld:%ld0",Time[i] . Time / 6,Time[i] . Time % 6);
  383.  
  384.             AddTail(List,&Time[i]);
  385.         }
  386.     }
  387.  
  388.     return(List);
  389. }
  390.  
  391.     /* ResizeTimeDateNode(struct TimeDateNode *Node,LONG Count,UBYTE Time):
  392.      *
  393.      *    Resize the time table associated with a TimeDateNode.
  394.      */
  395.  
  396. BYTE
  397. ResizeTimeDateNode(struct TimeDateNode *Node,LONG Count,UBYTE Time)
  398. {
  399.     if(Count != Node -> Table[0] . Count)
  400.     {
  401.         struct TimeDate *Table;
  402.  
  403.         if(Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * Count,MEMF_ANY | MEMF_CLEAR))
  404.         {
  405.             LONG i;
  406.  
  407.             CopyMem(Node -> Table,Table,sizeof(struct TimeDate) * Count);
  408.  
  409.             if(Count > Node -> Table[0] . Count)
  410.             {
  411.                 for(i = Node -> Table[0] . Count ; i < Count ; i++)
  412.                 {
  413.                     CopyMem(&Node -> Table[0],&Table[i],sizeof(struct TimeDate));
  414.  
  415.                     Table[i] . Time = Time;
  416.                 }
  417.             }
  418.  
  419.             for(i = 0 ; i < Count ; i++)
  420.                 Table[i] . Count = Count;
  421.  
  422.             FreeVec(Node -> Table);
  423.  
  424.             Node -> Table = Table;
  425.  
  426.             return(TRUE);
  427.         }
  428.         else
  429.             return(FALSE);
  430.     }
  431.     else
  432.         return(TRUE);
  433. }
  434.  
  435.     /* DeleteTimeDateNode(struct TimeDateNode *Node,LONG Index):
  436.      *
  437.      *    Delete a single timetable entry from a TimeDateNode.
  438.      */
  439.  
  440. BYTE
  441. DeleteTimeDateNode(struct TimeDateNode *Node,LONG Index)
  442. {
  443.     struct TimeDate    *Table;
  444.     LONG         Count = Node -> Table[0] . Count - 1;
  445.  
  446.     if(Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * Count,MEMF_ANY | MEMF_CLEAR))
  447.     {
  448.         LONG i,j;
  449.  
  450.         for(i = j = 0 ; i < Node -> Table[0] . Count ; i++)
  451.         {
  452.             if(i != Index)
  453.             {
  454.                 CopyMem(&Node -> Table[i],&Table[j],sizeof(struct TimeDate));
  455.  
  456.                 Table[j++] . Count = Count;
  457.             }
  458.         }
  459.  
  460.         FreeVec(Node -> Table);
  461.  
  462.         Node -> Table = Table;
  463.  
  464.         return(TRUE);
  465.     }
  466.     else
  467.         return(FALSE);
  468. }
  469.  
  470.     /* CreateTimeDateNode(BYTE Month,BYTE Day,STRPTR Comment,LONG Count):
  471.      *
  472.      *    Create a new TimeDateNode including time table entries.
  473.      */
  474.  
  475. struct TimeDateNode *
  476. CreateTimeDateNode(BYTE Month,BYTE Day,STRPTR Comment,LONG Count)
  477. {
  478.     struct TimeDateNode *Node;
  479.  
  480.     if(Node = (struct TimeDateNode *)AllocVec(sizeof(struct TimeDateNode),MEMF_ANY | MEMF_CLEAR))
  481.     {
  482.         if(Node -> Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * Count,MEMF_ANY | MEMF_CLEAR))
  483.         {
  484.             Node -> VanillaNode . ln_Name            = Node -> Buffer;
  485.  
  486.             Node -> Header . Month                = Month;
  487.             Node -> Header . Day                = Day;
  488.  
  489.             Node -> Table[0] . PayPerUnit[DT_FIRST_UNIT]    = 23;
  490.             Node -> Table[0] . SecPerUnit[DT_FIRST_UNIT]    =  6 * 60;
  491.             Node -> Table[0] . PayPerUnit[DT_NEXT_UNIT]    = 23;
  492.             Node -> Table[0] . SecPerUnit[DT_NEXT_UNIT]    =  6 * 60;
  493.             Node -> Table[0] . Time                = DT_GET_TIME( 8,0);
  494.             Node -> Table[0] . Count            = Count;
  495.  
  496.             if(Count > 1)
  497.             {
  498.                 Node -> Table[1] . PayPerUnit[DT_FIRST_UNIT]    = 23;
  499.                 Node -> Table[1] . SecPerUnit[DT_FIRST_UNIT]    = 12 * 60;
  500.                 Node -> Table[1] . PayPerUnit[DT_NEXT_UNIT]    = 23;
  501.                 Node -> Table[1] . SecPerUnit[DT_NEXT_UNIT]    = 12 * 60;
  502.                 Node -> Table[1] . Time                = DT_GET_TIME(18,0);
  503.                 Node -> Table[1] . Count            = Count;
  504.             }
  505.  
  506.             strcpy(Node -> Header . Comment,Comment);
  507.  
  508.             AdaptTimeDateNode(Node);
  509.  
  510.             return(Node);
  511.         }
  512.         else
  513.             FreeVec(Node);
  514.     }
  515.  
  516.     return(NULL);
  517. }
  518.  
  519.     /* RemPhoneEntry(LONG Num):
  520.      *
  521.      *    Remove a given entry from the phone book.
  522.      */
  523.  
  524. VOID
  525. RemPhoneEntry(LONG Num)
  526. {
  527.     struct PhoneEntry    *Entry;
  528.     LONG             i;
  529.  
  530.     Entry = Phonebook[Num];
  531.  
  532.     for(i = Num ; i < NumPhoneEntries ; i++)
  533.         Phonebook[i] = Phonebook[i + 1];
  534.  
  535.     Phonebook[NumPhoneEntries--] = NULL;
  536.  
  537.     if(Entry -> Config)
  538.         DeleteConfiguration(Entry -> Config);
  539.  
  540.     FreeTimeDateList((struct List *)&Entry -> TimeDateList);
  541.  
  542.     FreeVec(Entry);
  543. }
  544.  
  545.     /* NewPhoneEntry():
  546.      *
  547.      *    Create a new phone book entry with default values and
  548.      *    add it to the array. Expand the phone book if necessary.
  549.      */
  550.  
  551. BYTE
  552. NewPhoneEntry()
  553. {
  554.     struct PhoneEntry    **PrivatePhonebook;
  555.     LONG             PrivatePhoneSize,i;
  556.  
  557.         /* The phone book is filled `to the brim', so let's expand
  558.          * it.
  559.          */
  560.  
  561.     if(NumPhoneEntries + 1 > PhoneSize)
  562.     {
  563.             /* Allocate another phone book. */
  564.  
  565.         if(PrivatePhonebook = CreatePhonebook(PhoneSize + 1,&PrivatePhoneSize,FALSE))
  566.         {
  567.                 /* Copy the data. */
  568.  
  569.             if(Phonebook && PhoneSize)
  570.             {
  571.                 for(i = 0 ; i < PhoneSize ; i++)
  572.                     PrivatePhonebook[i] = Phonebook[i];
  573.  
  574.                     /* Remove the old phonebook. */
  575.  
  576.                 DeletePhonebook(Phonebook,PhoneSize,FALSE);
  577.             }
  578.  
  579.                 /* Assign the new pointers. */
  580.  
  581.             Phonebook = PrivatePhonebook;
  582.             PhoneSize = PrivatePhoneSize;
  583.         }
  584.         else
  585.             return(FALSE);
  586.     }
  587.  
  588.         /* Allocate another entry and add it to the phone book. */
  589.  
  590.     if(Phonebook[NumPhoneEntries] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry) + sizeof(struct PhoneHeader),MEMF_ANY | MEMF_CLEAR))
  591.     {
  592.         if(Phonebook[NumPhoneEntries] -> Config = CreateConfiguration(FALSE))
  593.         {
  594.             struct TimeDateNode *TimeDateNode;
  595.  
  596.             Phonebook[NumPhoneEntries] -> Header = (struct PhoneHeader *)(Phonebook[NumPhoneEntries] + 1);
  597.  
  598.             strcpy(Phonebook[NumPhoneEntries] -> Header -> Name,LocaleString(MSG_TERMPHONE_UNUSED_ENTRY_TXT));
  599.  
  600.             Phonebook[NumPhoneEntries] -> Count = -1;
  601.  
  602.             NewList((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList);
  603.  
  604.             if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
  605.                 AddTail((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList,&TimeDateNode -> VanillaNode);
  606.  
  607.             NumPhoneEntries++;
  608.  
  609.             return(TRUE);
  610.         }
  611.  
  612.         FreeVec(Phonebook[NumPhoneEntries]);
  613.  
  614.         Phonebook[NumPhoneEntries] = NULL;
  615.     }
  616.  
  617.     return(FALSE);
  618. }
  619.  
  620.     /* CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries):
  621.      *
  622.      *    Create a new phone entry array (so-called phone book).
  623.      */
  624.  
  625. struct PhoneEntry **
  626. CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries)
  627. {
  628.     struct PhoneEntry **PhoneEntry = NULL;
  629.  
  630.     if(Size)
  631.     {
  632.             /* Round the number of phone entries to a
  633.              * multiple of eight.
  634.              */
  635.  
  636.         *AllocSize = (Size + 7) & ~7;
  637.  
  638.             /* Create the list of pointers. */
  639.  
  640.         if(PhoneEntry = (struct PhoneEntry **)AllocVec(*AllocSize * sizeof(struct PhoneEntry *),MEMF_ANY | MEMF_CLEAR))
  641.         {
  642.                 /* And create some entries if necessary. */
  643.  
  644.             if(CreateEntries)
  645.             {
  646.                 BYTE Success = TRUE;
  647.                 LONG i;
  648.  
  649.                 for(i = 0 ; Success && i < Size ; i++)
  650.                 {
  651.                     if(PhoneEntry[i] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry) + sizeof(struct PhoneHeader),MEMF_ANY | MEMF_CLEAR))
  652.                     {
  653.                         if(PhoneEntry[i] -> Config = CreateConfiguration(FALSE))
  654.                         {
  655.                             PhoneEntry[i] -> Header = (struct PhoneHeader *)(PhoneEntry[i] + 1);
  656.  
  657.                             NewList((struct List *)&PhoneEntry[i] -> TimeDateList);
  658.                         }
  659.                         else
  660.                             Success = FALSE;
  661.                     }
  662.                     else
  663.                         Success = FALSE;
  664.                 }
  665.  
  666.                 if(!Success)
  667.                 {
  668.                     for(i = 0 ; i < *AllocSize ; i++)
  669.                     {
  670.                         if(PhoneEntry[i])
  671.                         {
  672.                             if(PhoneEntry[i] -> Config)
  673.                                 DeleteConfiguration(PhoneEntry[i] -> Config);
  674.  
  675.                             FreeVec(PhoneEntry[i]);
  676.                         }
  677.                     }
  678.  
  679.                     FreeVec(PhoneEntry);
  680.  
  681.                     return(NULL);
  682.                 }
  683.             }
  684.         }
  685.     }
  686.  
  687.     return(PhoneEntry);
  688. }
  689.  
  690.     /* DeletePhonebook(struct PhoneEntry **PhoneBook,LONG Size,BYTE FreeEntries):
  691.      *
  692.      *    Deallocates a given phone book and its entries if necessary.
  693.      */
  694.  
  695. VOID
  696. DeletePhonebook(struct PhoneEntry **Phonebook,LONG Size,BYTE FreeEntries)
  697. {
  698.     if(FreeEntries)
  699.     {
  700.         LONG i;
  701.  
  702.         for(i = 0 ; i < Size ; i++)
  703.         {
  704.             if(Phonebook[i])
  705.             {
  706.                 FreeTimeDateList((struct List *)&Phonebook[i] -> TimeDateList);
  707.  
  708.                 if(Phonebook[i] -> Config)
  709.                     DeleteConfiguration(Phonebook[i] -> Config);
  710.  
  711.                 FreeVec(Phonebook[i]);
  712.             }
  713.         }
  714.     }
  715.  
  716.     FreeVec(Phonebook);
  717. }
  718.