home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff589.lza / Term / TermSrc.lha / termPhone.c < prev    next >
C/C++ Source or Header  |  1991-11-24  |  14KB  |  695 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Name .....: TermPhone.c
  6.  *    Created ..: Monday 21-Jan-91 20:12
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    21-Jan-91       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15. #include "TermGlobal.h"
  16.  
  17.     /* SetPrefToDefaults():
  18.      *
  19.      *    Initialize configuration with default values.
  20.      */
  21.  
  22. VOID
  23. SetPrefToDefaults(struct Configuration *Config,UBYTE *PathBuffer)
  24. {
  25.     if(!PathBuffer)
  26.         PathBuffer = "ENVARC:term";
  27.  
  28.     strcpy(Config -> DefaultStorage,PathBuffer);
  29.  
  30.     /* Serial Preferences. */
  31.  
  32.     Config -> BaudRate        = 2400;
  33.     Config -> BitsPerChar        = 8;
  34.     Config -> Parity        = PARITY_NONE;
  35.     Config -> StopBits        = 1;
  36.     Config -> Handshaking        = HANDSHAKING_XONXOFF;
  37.     Config -> Duplex        = DUPLEX_FULL;
  38.     Config -> HighSpeed        = FALSE;
  39.     Config -> BreakLength        = 250000;
  40.     Config -> UnitNumber        = 0;
  41.  
  42.     strcpy(Config -> SerialDevice,SERIALNAME);
  43.  
  44.     /* Modem Preferences. */
  45.  
  46.     Config -> RedialDelay        = 2;
  47.     Config -> DialRetries        = 10;
  48.     Config -> DialTimeout        = 60;
  49.     Config -> ConnectAutoBaud    = FALSE;
  50.  
  51.     strcpy(Config -> ModemInit,    "AT\\r");
  52.     strcpy(Config -> ModemExit,    "");
  53.     strcpy(Config -> ModemHangup,    "~~~~~~~~+++~~~~~~ATH0\\r");
  54.     strcpy(Config -> DialPrefix,    "~~ATX3DP");
  55.     strcpy(Config -> NoCarrier,    "NO CARRIER");
  56.     strcpy(Config -> Connect,    "CONNECT");
  57.     strcpy(Config -> Voice,        "VOICE");
  58.     strcpy(Config -> Ring,        "RING");
  59.     strcpy(Config -> Busy,        "BUSY");
  60.  
  61.     /* Transfer Preferences. */
  62.  
  63.     strcpy(Config -> Protocol,"xprzmodem.library");
  64.  
  65.     /* Macro Preferences. */
  66.  
  67.     strcpy(LastMacros,PathBuffer);
  68.     AddPart(LastMacros,"Macros.term",256);
  69.  
  70.     strcpy(Config -> MacroFile,LastMacros);
  71.  
  72.     /* Screen Preferences. */
  73.  
  74.     Config -> DisplayMode        = ModeID[0];
  75.     Config -> MakeScreenPublic    = TRUE;
  76.  
  77.     /* Terminal Preferences. */
  78.  
  79.     Config -> CaptureFilter        = TRUE;
  80.     Config -> DestructiveBackspace    = TRUE;
  81.     Config -> AudibleBell        = TRUE;
  82.     Config -> VisibleBell        = FALSE;
  83.     Config -> EightyColumns        = FALSE;
  84.     Config -> SendCR        = CR_ASCR;
  85.     Config -> SendLF        = LF_ASLF;
  86.     Config -> ColourMode        = COLOUR_AMIGA;
  87.     Config -> Emulation        = EMULATION_ANSIVT100;
  88.     Config -> Font            = FONT_TOPAZ;
  89.  
  90.     Config -> SwapBSDelete        = FALSE;
  91.     Config -> StripBit8        = FALSE;
  92.  
  93.     Config -> RasterEnabled        = TRUE;
  94.  
  95.     Config -> EmulationName[0]    = 0;
  96. }
  97.  
  98.     /* CreatePhoneList():
  99.      *
  100.      *    Turn the array of pointers to phonebook entries into
  101.      *    a linked standard Amiga List (gadtools needs this).
  102.      */
  103.  
  104. struct List *
  105. CreatePhoneList()
  106. {
  107.     struct List    *PhoneList;
  108.     struct Node    *PhoneNode;
  109.     LONG         i;
  110.  
  111.     if(Phonebook && NumPhoneEntries)
  112.     {
  113.         if(PhoneList = (struct List *)AllocVec(sizeof(struct List) + NumPhoneEntries * sizeof(struct Node),MEMF_PUBLIC|MEMF_CLEAR))
  114.         {
  115.             NewList(PhoneList);
  116.  
  117.             PhoneNode = (struct Node *)(PhoneList + 1);
  118.  
  119.             for(i = 0 ; i < NumPhoneEntries ; i++)
  120.             {
  121.                 PhoneNode[i] . ln_Name    = Phonebook[i] -> Name;
  122.  
  123.                 AddTail(PhoneList,&PhoneNode[i]);
  124.             }
  125.  
  126.             return(PhoneList);
  127.         }
  128.     }
  129.     else
  130.     {
  131.         if(PhoneList = (struct List *)AllocVec(sizeof(struct List),MEMF_PUBLIC|MEMF_CLEAR))
  132.         {
  133.             NewList(PhoneList);
  134.  
  135.             return(PhoneList);
  136.         }
  137.     }
  138.  
  139.     return(NULL);
  140. }
  141.  
  142.     /* DeletePhoneList(struct List *PhoneList):
  143.      *
  144.      *    Delete the entries listed in the Amiga List
  145.      *    created by the routine above.
  146.      */
  147.  
  148. VOID
  149. DeletePhoneList(struct List *PhoneList)
  150. {
  151.     if(PhoneList)
  152.     {
  153.         FreeVec(PhoneList);
  154.  
  155.         PhoneList = NULL;
  156.     }
  157. }
  158.  
  159.     /* Compare(struct PhoneEntry **A,struct PhoneEntry **B):
  160.      *
  161.      *    Comparison subroutine required by the QuickSort
  162.      *    call below.     
  163.      */
  164.  
  165. STATIC LONG
  166. Compare(struct PhoneEntry **A,struct PhoneEntry **B)
  167. {
  168.     return(Stricmp((*A) -> Name,(*B) -> Name));
  169. }
  170.  
  171.     /* SortPhoneEntries():
  172.      *
  173.      *    Sorts the current phone list array in ascending order.
  174.      */
  175.  
  176. VOID
  177. SortPhoneEntries()
  178. {
  179.     qsort(Phonebook,NumPhoneEntries,sizeof(struct PhoneEntry *),Compare);
  180. }
  181.  
  182.     /* RemPhoneEntry(LONG Num):
  183.      *
  184.      *    Remove a given entry from the phone book.
  185.      */
  186.  
  187. VOID
  188. RemPhoneEntry(LONG Num)
  189. {
  190.     struct PhoneEntry    *Entry;
  191.     LONG             i;
  192.  
  193.     Entry = Phonebook[Num];
  194.  
  195.     for(i = Num ; i < NumPhoneEntries ; i++)
  196.         Phonebook[i] = Phonebook[i + 1];
  197.  
  198.     Phonebook[NumPhoneEntries--] = NULL;
  199.  
  200.     FreeVec(Entry);
  201. }
  202.  
  203.     /* NewPhoneEntry():
  204.      *
  205.      *    Create a new phone book entry with default values and
  206.      *    add it to the array. Expand the phone book if necessary.
  207.      */
  208.  
  209. BYTE
  210. NewPhoneEntry()
  211. {
  212.     struct PhoneEntry    **PrivatePhonebook;
  213.     LONG             PrivatePhoneSize;
  214.     LONG             i;
  215.  
  216.         /* The phone book is filled `to the brim', so let's expand
  217.          * it.
  218.          */
  219.  
  220.     if(NumPhoneEntries + 1 > PhoneSize)
  221.     {
  222.             /* Allocate another phone book. */
  223.  
  224.         if(PrivatePhonebook = CreatePhonebook(PhoneSize + 1,&PrivatePhoneSize,FALSE))
  225.         {
  226.                 /* Copy the data. */
  227.  
  228.             if(Phonebook && PhoneSize)
  229.             {
  230.                 for(i = 0 ; i < PhoneSize ; i++)
  231.                     PrivatePhonebook[i] = Phonebook[i];
  232.  
  233.                     /* Remove the old phonebook. */
  234.  
  235.                 DeletePhonebook(Phonebook,PhoneSize,FALSE);
  236.             }
  237.  
  238.                 /* Assign the new pointers. */
  239.  
  240.             Phonebook = PrivatePhonebook;
  241.             PhoneSize = PrivatePhoneSize;
  242.         }
  243.         else
  244.             return(FALSE);
  245.     }
  246.  
  247.         /* Allocate another entry and add it to the phone book. */
  248.  
  249.     if(Phonebook[NumPhoneEntries] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry),MEMF_PUBLIC|MEMF_CLEAR))
  250.     {
  251.         strcpy(Phonebook[NumPhoneEntries] -> Name,"-- Unused Entry --");
  252.  
  253.         CopyMem(&Config,&Phonebook[NumPhoneEntries] -> Config,sizeof(struct Configuration));
  254.  
  255.             /* These are the german default values. */
  256.  
  257.         Phonebook[NumPhoneEntries] -> PayPerUnit[0] = 23;
  258.         Phonebook[NumPhoneEntries] -> PayPerUnit[1] = 23;
  259.  
  260.         Phonebook[NumPhoneEntries] -> SecPerUnit[0] =  6 * 60;
  261.         Phonebook[NumPhoneEntries] -> SecPerUnit[1] = 12 * 60;
  262.  
  263.         Phonebook[NumPhoneEntries] -> TimeOfDay[0] =  48;
  264.         Phonebook[NumPhoneEntries] -> TimeOfDay[1] = 108;
  265.  
  266.         NumPhoneEntries++;
  267.  
  268.         return(TRUE);
  269.     }
  270.  
  271.     return(FALSE);
  272. }
  273.  
  274.     /* CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries):
  275.      *
  276.      *    Create a new phone entry array (so-called phone book).
  277.      */
  278.  
  279. struct PhoneEntry **
  280. CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries)
  281. {
  282.     struct PhoneEntry **PhoneEntry = NULL;
  283.  
  284.     if(Size)
  285.     {
  286.             /* Round the number of phone entries to a
  287.              * multiple of eight.
  288.              */
  289.  
  290.         *AllocSize = (((Size + 7) >> 3) << 3);
  291.  
  292.             /* Create the list of pointers. */
  293.  
  294.         if(PhoneEntry = (struct PhoneEntry **)AllocVec(*AllocSize * sizeof(struct PhoneEntry *),MEMF_PUBLIC|MEMF_CLEAR))
  295.         {
  296.                 /* And create some entries if necessary. */
  297.  
  298.             if(CreateEntries)
  299.             {
  300.                 LONG i;
  301.  
  302.                 for(i = 0 ; i < Size ; i++)
  303.                 {
  304.                     if(!(PhoneEntry[i] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry),MEMF_PUBLIC|MEMF_CLEAR)))
  305.                     {
  306.                         LONG j;
  307.  
  308.                         for(j = 0 ; j < i ; j++)
  309.                             FreeVec(PhoneEntry[j]);
  310.  
  311.                         FreeVec(PhoneEntry);
  312.  
  313.                         return(NULL);
  314.                     }
  315.                 }
  316.             }
  317.         }
  318.     }
  319.  
  320.     return(PhoneEntry);
  321. }
  322.  
  323.     /* DeletePhonebook(struct PhoneEntry **PhoneBook,LONG Size,BYTE FreeEntries):
  324.      *
  325.      *    Deallocates a given phone book and its entries if necessary.
  326.      */
  327.  
  328. VOID
  329. DeletePhonebook(struct PhoneEntry **PhoneBook,LONG Size,BYTE FreeEntries)
  330. {
  331.     if(FreeEntries)
  332.     {
  333.         LONG i;
  334.  
  335.         for(i = 0 ; i < Size ; i++)
  336.         {
  337.             if(PhoneBook[i])
  338.                 FreeVec(PhoneBook[i]);
  339.         }
  340.     }
  341.  
  342.     FreeVec(PhoneBook);
  343. }
  344.  
  345.     /* SavePhonebook(UBYTE *Name):
  346.      *
  347.      *    Save the current phone book to a disk file.
  348.      */
  349.  
  350. BYTE
  351. SavePhonebook(UBYTE *Name)
  352. {
  353.     struct IFFHandle    *Handle;
  354.     BYTE             Success = FALSE;
  355.  
  356.     if(Phonebook && NumPhoneEntries)
  357.     {
  358.         if(Handle = (struct IFFHandle *)AllocIFF())
  359.         {
  360.             if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
  361.             {
  362.                 InitIFFasDOS(Handle);
  363.  
  364.                 if(!OpenIFF(Handle,IFFF_WRITE))
  365.                 {
  366.                     if(!PushChunk(Handle,'TERM',ID_CAT,IFFSIZE_UNKNOWN))
  367.                     {
  368.                         if(!PushChunk(Handle,'TERM',ID_FORM,IFFSIZE_UNKNOWN))
  369.                         {
  370.                             if(!PushChunk(Handle,0,'VERS',IFFSIZE_UNKNOWN))
  371.                             {
  372.                                 struct TermInfo TermInfo;
  373.  
  374.                                 TermInfo . Version    = TermVersion;
  375.                                 TermInfo . Revision    = 9;
  376.  
  377.                                 if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  378.                                 {
  379.                                     if(PopChunk(Handle))
  380.                                         Success = FALSE;
  381.                                     else
  382.                                     {
  383.                                         if(!PushChunk(Handle,0,'DIAL',IFFSIZE_UNKNOWN))
  384.                                         {
  385.                                             if(WriteChunkBytes(Handle,&NumPhoneEntries,sizeof(LONG)) == sizeof(LONG))
  386.                                             {
  387.                                                 if(PopChunk(Handle))
  388.                                                     Success = FALSE;
  389.                                                 else
  390.                                                 {
  391.                                                     if(PopChunk(Handle))
  392.                                                         Success = FALSE;
  393.                                                     else
  394.                                                     {
  395.                                                         LONG i;
  396.  
  397.                                                         for(i = 0 ; i < NumPhoneEntries ; i++)
  398.                                                         {
  399.                                                             if(!PushChunk(Handle,'TERM',ID_FORM,IFFSIZE_UNKNOWN))
  400.                                                             {
  401.                                                                 if(!PushChunk(Handle,0,'PREF',IFFSIZE_UNKNOWN))
  402.                                                                 {
  403.                                                                     if(WriteChunkBytes(Handle,Phonebook[i],sizeof(struct PhoneEntry)) != sizeof(struct PhoneEntry))
  404.                                                                     {
  405.                                                                         Success = FALSE;
  406.  
  407.                                                                         break;
  408.                                                                     }
  409.                                                                     else
  410.                                                                         Success = TRUE;
  411.  
  412.                                                                     if(PopChunk(Handle))
  413.                                                                     {
  414.                                                                         Success = FALSE;
  415.                                                                         break;
  416.                                                                     }
  417.                                                                 }
  418.  
  419.                                                                 if(PopChunk(Handle))
  420.                                                                 {
  421.                                                                     Success = FALSE;
  422.                                                                     break;
  423.                                                                 }
  424.                                                             }
  425.                                                         }
  426.                                                     }
  427.                                                 }
  428.                                             }
  429.                                         }
  430.                                     }
  431.                                 }
  432.                             }
  433.                         }
  434.  
  435.                         if(PopChunk(Handle))
  436.                             Success = FALSE;
  437.                     }
  438.  
  439.                     CloseIFF(Handle);
  440.                 }
  441.  
  442.                 Close(Handle -> iff_Stream);
  443.             }
  444.  
  445.             FreeIFF(Handle);
  446.         }
  447.  
  448.         if(Success)
  449.             SetProtection(Name,FIBF_EXECUTE);
  450.         else
  451.             DeleteFile(Name);
  452.     }
  453.  
  454.     return(Success);
  455. }
  456.  
  457.     /* OldLoadPhonebook(UBYTE *Name):
  458.      *
  459.      *    Restore a phone book from a disk file (old version).
  460.      */
  461.  
  462. STATIC BYTE
  463. OldLoadPhonebook(UBYTE *Name)
  464. {
  465.     struct PhoneEntry    **PrivatePhonebook;
  466.     LONG             PrivatePhoneSize;
  467.     LONG             Size,i;
  468.     struct IFFHandle    *Handle;
  469.     BYTE             Success = FALSE;
  470.     struct StoredProperty    *Prop;
  471.     struct TermInfo        *TermInfo;
  472.  
  473.     if(Handle = AllocIFF())
  474.     {
  475.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  476.         {
  477.             InitIFFasDOS(Handle);
  478.  
  479.             if(!OpenIFF(Handle,IFFF_READ))
  480.             {
  481.                 if(!PropChunks(Handle,&VersionProps[0],1))
  482.                 {
  483.                     if(!StopChunk(Handle,'TERM','DIAL'))
  484.                     {
  485.                         if(!ParseIFF(Handle,IFFPARSE_SCAN))
  486.                         {
  487.                             if(Prop = FindProp(Handle,'TERM','VERS'))
  488.                             {
  489.                                 TermInfo = (struct TermInfo *)Prop -> sp_Data;
  490.  
  491.                                 if(TermInfo -> Version <= TermVersion && TermInfo -> Revision <= TermRevision && TermInfo -> Revision >= 6)
  492.                                 {
  493.                                     if(ReadChunkRecords(Handle,&Size,sizeof(LONG),1))
  494.                                     {
  495.                                         if(Size)
  496.                                         {
  497.                                             if(PrivatePhonebook = CreatePhonebook(Size,&PrivatePhoneSize,TRUE))
  498.                                             {
  499.                                                 struct ContextNode    *Chunk;
  500.                                                 LONG             ItemSize;
  501.  
  502.                                                 Chunk = CurrentChunk(Handle);
  503.  
  504.                                                 ItemSize = Chunk -> cn_Size / Size;
  505.  
  506.                                                 for(i = 0 ; i < Size ; i++)
  507.                                                 {
  508.                                                     SetPrefToDefaults(&PrivatePhonebook[i] -> Config,NULL);
  509.  
  510.                                                     if(!ReadChunkRecords(Handle,PrivatePhonebook[i],ItemSize,1))
  511.                                                     {
  512.                                                         if(i)
  513.                                                             Size = i - 1;
  514.                                                         else
  515.                                                             Size = 0;
  516.  
  517.                                                         break;
  518.                                                     }
  519.                                                 }
  520.  
  521.                                                 if(Size)
  522.                                                 {
  523.                                                     if(Phonebook)
  524.                                                         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  525.  
  526.                                                     Phonebook = PrivatePhonebook;
  527.                                                     PhoneSize = PrivatePhoneSize;
  528.  
  529.                                                     NumPhoneEntries = Size;
  530.  
  531.                                                     Success = TRUE;
  532.                                                 }
  533.                                                 else
  534.                                                 {
  535.                                                     DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
  536.                                                     Success = FALSE;
  537.                                                 }
  538.  
  539.                                                 FreeSubList();
  540.                                             }
  541.                                         }
  542.                                     }
  543.                                 }
  544.                             }
  545.                         }
  546.                     }
  547.                 }
  548.  
  549.                 CloseIFF(Handle);
  550.             }
  551.  
  552.             Close(Handle -> iff_Stream);
  553.         }
  554.  
  555.         FreeIFF(Handle);
  556.     }
  557.  
  558.     return(Success);
  559. }
  560.  
  561.     /* LoadPhonebook(UBYTE *Name):
  562.      *
  563.      *    Restore a phone book from a disk file.
  564.      */
  565.  
  566. BYTE
  567. LoadPhonebook(UBYTE *Name)
  568. {
  569.     STATIC ULONG Stops[6] =
  570.     {
  571.         'TERM','VERS',
  572.         'TERM','DIAL',
  573.         'TERM','PREF'
  574.     };
  575.  
  576.     struct PhoneEntry    **PrivatePhonebook;
  577.     LONG             PrivatePhoneSize = 0;
  578.     LONG             Size = 0,i;
  579.     struct IFFHandle    *Handle;
  580.     BYTE             Success = FALSE;
  581.     struct ContextNode    *Chunk;
  582.     BYTE             UseOld = FALSE;
  583.  
  584.     if(Handle = AllocIFF())
  585.     {
  586.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  587.         {
  588.             InitIFFasDOS(Handle);
  589.  
  590.             if(!OpenIFF(Handle,IFFF_READ))
  591.             {
  592.                 if(!StopChunks(Handle,&Stops[0],3))
  593.                 {
  594.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  595.                     {
  596.                         Chunk = CurrentChunk(Handle);
  597.  
  598.                         if(Chunk -> cn_ID == 'VERS')
  599.                         {
  600.                             struct TermInfo TermInfo;
  601.  
  602.                             if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  603.                             {
  604.                                 if(TermInfo . Version > TermVersion || TermInfo . Revision > 9 || TermInfo . Revision < 6)
  605.                                     break;
  606.  
  607.                                 if(TermInfo . Revision < 9)
  608.                                 {
  609.                                     UseOld = TRUE;
  610.  
  611.                                     break;
  612.                                 }
  613.                             }
  614.                             else
  615.                                 break;
  616.                         }
  617.  
  618.                         if(Chunk -> cn_ID == 'DIAL')
  619.                         {
  620.                             if(ReadChunkBytes(Handle,&Size,sizeof(LONG)) == sizeof(LONG))
  621.                             {
  622.                                 i = 0;
  623.  
  624.                                 if(!(PrivatePhonebook = CreatePhonebook(Size,&PrivatePhoneSize,TRUE)))
  625.                                     break;
  626.                             }
  627.                             else
  628.                                 break;
  629.                         }
  630.  
  631.                         if(Chunk -> cn_ID == 'PREF')
  632.                         {
  633.                             if(Size && i < Size)
  634.                             {
  635.                                 WORD LastSize = sizeof(struct PhoneEntry);
  636.  
  637.                                 if(Chunk -> cn_Size < LastSize)
  638.                                     LastSize = Chunk -> cn_Size;
  639.  
  640.                                 SetPrefToDefaults(&PrivatePhonebook[i] -> Config,NULL);
  641.  
  642.                                 if(ReadChunkBytes(Handle,PrivatePhonebook[i],LastSize) == LastSize)
  643.                                     i++;
  644.                                 else
  645.                                 {
  646.                                     if(i)
  647.                                         Size = i - 1;
  648.                                     else
  649.                                         Size = 0;
  650.  
  651.                                     break;
  652.                                 }
  653.                             }
  654.                         }
  655.                     }
  656.  
  657.                     if(Size)
  658.                     {
  659.                         if(Phonebook)
  660.                             DeletePhonebook(Phonebook,PhoneSize,TRUE);
  661.  
  662.                         Phonebook = PrivatePhonebook;
  663.                         PhoneSize = PrivatePhoneSize;
  664.  
  665.                         NumPhoneEntries = Size;
  666.  
  667.                         Success = TRUE;
  668.                     }
  669.                     else
  670.                     {
  671.                         if(PrivatePhoneSize)
  672.                         {
  673.                             DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
  674.                             Success = FALSE;
  675.                         }
  676.                     }
  677.  
  678.                     FreeSubList();
  679.                 }
  680.  
  681.                 CloseIFF(Handle);
  682.             }
  683.  
  684.             Close(Handle -> iff_Stream);
  685.         }
  686.  
  687.         FreeIFF(Handle);
  688.     }
  689.  
  690.     if(UseOld)
  691.         Success = OldLoadPhonebook(Name);
  692.  
  693.     return(Success);
  694. }
  695.