home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / telecomm / terms / term-4.1-source.lha / Extras / Source / term-Source.lha / termDial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-01  |  35.3 KB  |  1,644 lines

  1. /*
  2. **    termDial.c
  3. **
  4. **    The dialing routine as called by the phonebook
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Panel gadget IDs. */
  13.  
  14. enum    {    GAD_CALLING=1,GAD_TIME,GAD_NOTE,
  15.         GAD_SKIP,GAD_REMOVE,GAD_ONLINE,GAD_ABORT
  16.     };
  17.  
  18. STATIC VOID __stdargs
  19. PrintBox(struct LayoutHandle *Handle,LONG Box,LONG Line,STRPTR String,...)
  20. {
  21.     UBYTE     LocalBuffer[256];
  22.     va_list     VarArgs;
  23.  
  24.     va_start(VarArgs,String);
  25.     VSPrintf(LocalBuffer,String,VarArgs);
  26.     va_end(VarArgs);
  27.  
  28.     LT_SetAttributes(Handle,Box,LABX_Index,Line,LABX_Text,LocalBuffer,TAG_DONE);
  29. }
  30.  
  31.     /* BuildName(STRPTR Name):
  32.      *
  33.      *    Build a file name from a BBS name and the current date.
  34.      */
  35.  
  36. STATIC VOID __regargs
  37. BuildName(STRPTR Name,STRPTR Date)
  38. {
  39.     if(Date[0])
  40.     {
  41.         WORD    NameLen = strlen(Name),
  42.             DateLen = strlen(Date),
  43.             Delta;
  44.  
  45.         if((Delta = NameLen + 1 + DateLen - 32) > 0)
  46.             Name[NameLen - Delta] = 0;
  47.  
  48.         strcat(Name,"_");
  49.         strcat(Name,Date);
  50.     }
  51. }
  52.  
  53.     /* OpenAutoCaptureFile(STRPTR SomeName):
  54.      *
  55.      *    Open a capture file.
  56.      */
  57.  
  58. STATIC VOID __regargs
  59. OpenAutoCaptureFile(STRPTR SomeName)
  60. {
  61.     UBYTE        SharedBuffer[MAX_FILENAME_LENGTH],
  62.             Name[50],
  63.             Date[20],
  64.             Time[20];
  65.     struct DateTime    DateTime;
  66.  
  67.         /* Get the current time and date. */
  68.  
  69.     DateStamp(&DateTime . dat_Stamp);
  70.  
  71.         /* Prepare for date conversion. */
  72.  
  73.     DateTime . dat_Format    = FORMAT_DOS;
  74.     DateTime . dat_Flags    = 0;
  75.     DateTime . dat_StrDay    = NULL;
  76.     DateTime . dat_StrDate    = Date;
  77.     DateTime . dat_StrTime    = Time;
  78.  
  79.         /* Convert the date. */
  80.  
  81.     if(DateToStr(&DateTime))
  82.     {
  83.             /* Remember the BBS name. */
  84.  
  85.         strcpy(Name,SomeName);
  86.  
  87.             /* Append the creation date if necessary. */
  88.  
  89.         if(Config -> CaptureConfig -> AutoCaptureDate == AUTOCAPTURE_DATE_NAME)
  90.             BuildName(Name,Date);
  91.  
  92.             /* Make it a reasonable name. */
  93.  
  94.         FixName(Name);
  95.  
  96.             /* Get the capture file path. */
  97.  
  98.         strcpy(SharedBuffer,Config -> CaptureConfig -> CapturePath);
  99.  
  100.             /* Try to build a valid file and path name. */
  101.  
  102.         if(AddPart(SharedBuffer,Name,MAX_FILENAME_LENGTH))
  103.         {
  104.                 /* Is the capture file still open? */
  105.  
  106.             if(FileCapture)
  107.             {
  108.                     /* Close the file. */
  109.  
  110.                 BufferClose(FileCapture);
  111.  
  112.                 FileCapture = NULL;
  113.  
  114.                     /* Any data written? */
  115.  
  116.                 if(!GetFileSize(CaptureName))
  117.                     DeleteFile(CaptureName);
  118.                 else
  119.                 {
  120.                     AddProtection(CaptureName,FIBF_EXECUTE);
  121.  
  122.                     if(Config -> MiscConfig -> CreateIcons)
  123.                         AddIcon(CaptureName,FILETYPE_TEXT,TRUE);
  124.                 }
  125.             }
  126.  
  127.                 /* Try to append the new data. */
  128.  
  129.             if(FileCapture = BufferOpen(SharedBuffer,"a"))
  130.             {
  131.                     /* Set the menu checkmark. */
  132.  
  133.                 CheckItem(MEN_CAPTURE_TO_FILE,TRUE);
  134.  
  135.                     /* Remember the current capture file name. */
  136.  
  137.                 strcpy(CaptureName,SharedBuffer);
  138.  
  139.                     /* Add the creation date if necessary. */
  140.  
  141.                 if(Config -> CaptureConfig -> AutoCaptureDate == AUTOCAPTURE_DATE_INCLUDE)
  142.                 {
  143.                     UBYTE DateTimeBuffer[256];
  144.  
  145.                     if(FormatStamp(&DateTime . dat_Stamp,NULL,NULL,DateTimeBuffer,FALSE))
  146.                         BPrintf(FileCapture,LocaleString(MSG_DIALPANEL_FILE_CREATED_TXT),DateTimeBuffer);
  147.                 }
  148.             }
  149.             else
  150.                 CheckItem(MEN_CAPTURE_TO_FILE,FALSE);
  151.  
  152.             ConOutputUpdate();
  153.         }
  154.     }
  155. }
  156.  
  157.     /* Connect(struct PhoneNode *DialNode,STRPTR NumberBuffer):
  158.      *
  159.      *    Perform connect action(s).
  160.      */
  161.  
  162. STATIC VOID __regargs
  163. Connect(struct PhoneNode *DialNode,STRPTR NumberBuffer)
  164. {
  165.     if(DialNode -> Entry)
  166.     {
  167.         UpdateConfig(DialNode -> Entry -> Config,Config);
  168.  
  169.         ConfigChanged = FALSE;
  170.  
  171.         MakeCall(DialNode -> Entry -> Header -> Name,NumberBuffer);
  172.  
  173.         ObtainSemaphore(&PatternSemaphore);
  174.  
  175.         ChosenPattern = FindTimeDate(PatternList,NumberBuffer);
  176.  
  177.         SelectTime(DialNode -> Entry,ChosenPattern,NULL);
  178.  
  179.         ChosenEntry    = DialNode -> Entry;
  180.         WhichUnit    = DT_FIRST_UNIT;
  181.         CurrentPay    = 0;
  182.         SendStartup    = TRUE;
  183.  
  184.         ReleaseSemaphore(&PatternSemaphore);
  185.  
  186.         strcpy(Password,DialNode -> Entry -> Header -> Password);
  187.         strcpy(UserName,DialNode -> Entry -> Header -> UserName);
  188.  
  189.         strcpy(CurrentBBSName,DialNode -> Entry -> Header -> Name);
  190.         strcpy(CurrentBBSComment,DialNode -> Entry -> Header -> Comment);
  191.  
  192.         strcpy(CurrentBBSNumber,NumberBuffer);
  193.  
  194.         if(DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  195.         {
  196.             OnlinePlus = DialNode -> Entry -> Config -> ModemConfig -> TimeToConnect;
  197.  
  198.             if(DialNode -> Entry -> Config -> ModemConfig -> ConnectLimit > 0 && DialNode -> Entry -> Config -> ModemConfig -> ConnectLimitMacro[0])
  199.             {
  200.                 LimitCount = DialNode -> Entry -> Config -> ModemConfig -> ConnectLimit;
  201.  
  202.                 strcpy(LimitMacro,DialNode -> Entry -> Config -> ModemConfig -> ConnectLimitMacro);
  203.             }
  204.             else
  205.                 LimitCount = -1;
  206.         }
  207.         else
  208.         {
  209.             OnlinePlus = Config -> ModemConfig -> TimeToConnect;
  210.  
  211.             if(Config -> ModemConfig -> ConnectLimit > 0 && Config -> ModemConfig -> ConnectLimitMacro[0])
  212.             {
  213.                 LimitCount = Config -> ModemConfig -> ConnectLimit;
  214.  
  215.                 strcpy(LimitMacro,Config -> ModemConfig -> ConnectLimitMacro);
  216.             }
  217.             else
  218.                 LimitCount = -1;
  219.         }
  220.  
  221.         LogAction(LocaleString(MSG_DIALPANEL_CONNECTED_TO_1_TXT),DialNode -> Entry -> Header -> Name,NumberBuffer);
  222.     }
  223.     else
  224.     {
  225.         OnlinePlus = Config -> ModemConfig -> TimeToConnect;
  226.  
  227.         MakeCall("???",NumberBuffer);
  228.  
  229.         ObtainSemaphore(&PatternSemaphore);
  230.  
  231.         ChosenPattern = FindTimeDate(PatternList,NumberBuffer);
  232.  
  233.         SelectTime(NULL,ChosenPattern,NULL);
  234.  
  235.         ChosenEntry    = NULL;
  236.  
  237.         ReleaseSemaphore(&PatternSemaphore);
  238.  
  239.         CurrentPay    = 0;
  240.         Password[0]    = 0;
  241.         UserName[0]    = 0;
  242.         SendStartup    = FALSE;
  243.  
  244.         CurrentBBSName[0]    = 0;
  245.         CurrentBBSComment[0]    = 0;
  246.  
  247.         strcpy(CurrentBBSNumber,NumberBuffer);
  248.  
  249.         if(Config -> ModemConfig -> ConnectLimit > 0 && Config -> ModemConfig -> ConnectLimitMacro[0])
  250.         {
  251.             LimitCount = Config -> ModemConfig -> ConnectLimit;
  252.  
  253.             strcpy(LimitMacro,Config -> ModemConfig -> ConnectLimitMacro);
  254.         }
  255.         else
  256.             LimitCount = -1;
  257.  
  258.         LogAction(LocaleString(MSG_DIALPANEL_CONNECTED_TO_2_TXT),NumberBuffer);
  259.     }
  260.  
  261.         /* We are now online. */
  262.  
  263.     ObtainSemaphore(&OnlineSemaphore);
  264.  
  265.     Online = TRUE;
  266.  
  267.     ReleaseSemaphore(&OnlineSemaphore);
  268.  
  269.         /* Open auto-capture file. */
  270.  
  271.     if(Config -> CaptureConfig -> ConnectAutoCapture && Config -> CaptureConfig -> CapturePath[0])
  272.     {
  273.         if(DialNode -> Entry)
  274.             OpenAutoCaptureFile(DialNode -> Entry -> Header -> Name);
  275.         else
  276.             OpenAutoCaptureFile(LocaleString(MSG_DIALPANEL_CAPTURE_NAME_TXT));
  277.     }
  278.  
  279.         /* Remove node from
  280.          * dialing list and
  281.          * perform system
  282.          * setup.
  283.          */
  284.  
  285.     if(DialNode -> Entry)
  286.         RemoveDialNode(DialNode);
  287.  
  288.     Remove(&DialNode -> VanillaNode);
  289.  
  290.     FreeVecPooled(DialNode);
  291.  
  292.     if(PrivateConfig -> MiscConfig -> BackupConfig)
  293.     {
  294.         if(!BackupConfig)
  295.         {
  296.             if(BackupConfig = CreateConfiguration(TRUE))
  297.                 SaveConfig(PrivateConfig,BackupConfig);
  298.         }
  299.     }
  300.  
  301.         /* Make sure that the following
  302.          * setup/initialization will not
  303.          * touch the serial configuration.
  304.          */
  305.  
  306.     memcpy(PrivateConfig -> SerialConfig,Config -> SerialConfig,sizeof(struct SerialSettings));
  307.  
  308.     ConfigSetup();
  309.  
  310.         /* Reset the scanner. */
  311.  
  312.     FlowInit(TRUE);
  313. }
  314.  
  315.     /* DialPanel():
  316.      *
  317.      *    This routine opens a small window in the middle of the
  318.      *    console window and walks down the list of numbers to
  319.      *    dial.
  320.      */
  321.  
  322. BYTE
  323. DialPanel()
  324. {
  325.     struct LayoutHandle    *Handle;
  326.     struct PhoneNode    *DialNode;
  327.     BYTE             Result = FALSE,
  328.                  Record = FALSE;
  329.  
  330.     BlockWindows();
  331.  
  332.     ObtainSemaphore(&PatternSemaphore);
  333.  
  334.     ChosenEntry    = NULL;
  335.     ChosenPattern    = NULL;
  336.  
  337.     ReleaseSemaphore(&PatternSemaphore);
  338.  
  339.         /* We are dialing. */
  340.  
  341.     Status = STATUS_DIALING;
  342.  
  343.     if(Handle = LT_CreateHandleTags(Window -> WScreen,
  344.         LH_LocaleHook,    &LocaleHook,
  345.     TAG_DONE))
  346.     {
  347.         struct Window *PanelWindow;
  348.  
  349.         LT_New(Handle,
  350.             LA_Type,    VERTICAL_KIND,
  351.         TAG_DONE);
  352.         {
  353.             LT_New(Handle,
  354.                 LA_Type,    VERTICAL_KIND,
  355.             TAG_DONE);
  356.             {
  357.                 LT_New(Handle,
  358.                     LA_Type,    VERTICAL_KIND,
  359.                 TAG_DONE);
  360.                 {
  361.                     LT_New(Handle,
  362.                         LA_Type,        BOX_KIND,
  363.                         LA_ID,            GAD_CALLING,
  364.                         LA_Chars,        45,
  365.                         LA_Lines,        4,
  366.                         LABX_ReserveSpace,    TRUE,
  367.                         LABX_FirstLabel,    MSG_DIALPANEL_CALLING_TXT,
  368.                         LABX_LastLabel,        MSG_DIALPANEL_NEXT_TXT,
  369.                     TAG_DONE);
  370.  
  371.                     LT_New(Handle,
  372.                         LA_Type,        BOX_KIND,
  373.                         LA_ID,            GAD_TIME,
  374.                         LA_Chars,        45,
  375.                         LA_Lines,        2,
  376.                         LABX_ReserveSpace,    TRUE,
  377.                         LABX_FirstLabel,    MSG_DIALPANEL_TIMEOUT_TXT,
  378.                         LABX_LastLabel,        MSG_DIALPANEL_ATTEMPT_TXT,
  379.                     TAG_DONE);
  380.  
  381.                     LT_New(Handle,
  382.                         LA_Type,        BOX_KIND,
  383.                         LA_ID,            GAD_NOTE,
  384.                         LA_Chars,        45,
  385.                         LA_Lines,        1,
  386.                         LABX_ReserveSpace,    TRUE,
  387.                         LABX_FirstLabel,    MSG_DIALPANEL_MESSAGE_TXT,
  388.                         LABX_LastLabel,        MSG_DIALPANEL_MESSAGE_TXT,
  389.                     TAG_DONE);
  390.  
  391.                     LT_EndGroup(Handle);
  392.                 }
  393.  
  394.                 LT_New(Handle,
  395.                     LA_Type,    VERTICAL_KIND,
  396.                 TAG_DONE);
  397.                 {
  398.                     LT_New(Handle,
  399.                         LA_Type,        XBAR_KIND,
  400.                     TAG_DONE);
  401.  
  402.                     LT_New(Handle,
  403.                         LA_Type,        CHECKBOX_KIND,
  404.                         LA_LabelID,        MSG_DIALPANEL_RECORD_ON_CONNECTION_TXT,
  405.                         LA_BYTE,        &Record,
  406.                     TAG_DONE);
  407.  
  408.                     LT_EndGroup(Handle);
  409.                 }
  410.  
  411.                 LT_EndGroup(Handle);
  412.             }
  413.  
  414.             LT_New(Handle,
  415.                 LA_Type,VERTICAL_KIND,
  416.             TAG_DONE);
  417.             {
  418.                 LT_New(Handle,
  419.                     LA_Type,    XBAR_KIND,
  420.                     LAXB_FullSize,    TRUE,
  421.                 TAG_DONE);
  422.  
  423.                 LT_EndGroup(Handle);
  424.             }
  425.  
  426.             LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  427.                 LAGR_Spread,    TRUE,
  428.             TAG_DONE);
  429.             {
  430.                 LT_New(Handle,
  431.                     LA_Type,    BUTTON_KIND,
  432.                     LA_LabelID,    MSG_DIALPANEL_SKIP_GAD,
  433.                     LA_ID,        GAD_SKIP,
  434.                     LABT_ExtraFat,    TRUE,
  435.                 TAG_DONE);
  436.  
  437.                 LT_New(Handle,
  438.                     LA_Type,    BUTTON_KIND,
  439.                     LA_LabelID,    MSG_GLOBAL_REMOVE_GAD,
  440.                     LA_ID,        GAD_REMOVE,
  441.                     LABT_ExtraFat,    TRUE,
  442.                 TAG_DONE);
  443.  
  444.                 LT_New(Handle,
  445.                     LA_Type,    BUTTON_KIND,
  446.                     LA_LabelID,    MSG_DIALPANEL_GO_TO_ONLINE_GAD,
  447.                     LA_ID,        GAD_ONLINE,
  448.                     LABT_ReturnKey,    TRUE,
  449.                     LABT_ExtraFat,    TRUE,
  450.                 TAG_DONE);
  451.  
  452.                 LT_New(Handle,
  453.                     LA_Type,    BUTTON_KIND,
  454.                     LA_LabelID,    MSG_GLOBAL_ABORT_GAD,
  455.                     LA_ID,        GAD_ABORT,
  456.                     LABT_ExtraFat,    TRUE,
  457.                 TAG_DONE);
  458.  
  459.                 LT_EndGroup(Handle);
  460.             }
  461.  
  462.             LT_EndGroup(Handle);
  463.         }
  464.  
  465.         if(PanelWindow = LT_Layout(Handle,LocaleString(MSG_DIALPANEL_DIALING_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
  466.             LAWN_HelpHook,        &GuideHook,
  467.             LAWN_Parent,        Window,
  468.             WA_DepthGadget,        TRUE,
  469.             WA_CloseGadget,        TRUE,
  470.             WA_DragBar,        TRUE,
  471.             WA_RMBTrap,        TRUE,
  472.             WA_Activate,        TRUE,
  473.         TAG_DONE))
  474.         {
  475.             struct IntuiMessage    *Message;
  476.             BOOLEAN             Done = FALSE;
  477.             ULONG             MsgClass,
  478.                          MsgQualifier;
  479.             UWORD             MsgCode;
  480.             struct Gadget        *MsgGadget;
  481.             LONG             MsgGadgetID;
  482.  
  483.             LONG             RedialDelay = 0,DialTimeout,DialRetries,DialAttempt;
  484.             BYTE             Dialing,RunCount = 0,GotError = FALSE;
  485.  
  486.             UBYTE             SomeBuffer[300],ExitString[80],CallingBuffer[60],
  487.                          NumberBuffer[100],    *NextNumber    = NULL,
  488.                          InitBuffer[80],    *NextInit    = NULL,
  489.                          ExitBuffer[80],    *NextExit    = NULL,
  490.                          PrefixBuffer[80],    *NextPrefix    = NULL;
  491.  
  492.             struct SerialSettings     OriginalSerialConfig;
  493.             BOOLEAN             UseHangUp;
  494.             LONG             NumberCount,
  495.                          NumberCurrent = 0;
  496.             STRPTR             Calling;
  497.  
  498.             LT_ShowWindow(Handle,TRUE);
  499.  
  500.                 /* Remember the original serial settings, so we
  501.                  * can return to them later.
  502.                  */
  503.  
  504.             CopyMem(Config -> SerialConfig,&OriginalSerialConfig,sizeof(struct SerialSettings));
  505.  
  506.             GuideContext(CONTEXT_DIAL);
  507.  
  508.             ExitString[0] = 0;
  509.  
  510.                 /* Make the current one the active one. */
  511.  
  512.             PushWindow(PanelWindow);
  513.  
  514.                 /* Make a backup of the current configuration. */
  515.  
  516.             SaveConfig(Config,PrivateConfig);
  517.  
  518.                 /* Don't echo serial output. */
  519.  
  520.             Quiet        = TRUE;
  521.  
  522.                 /* Perform full sequence check. */
  523.  
  524.             FullCheck    = TRUE;
  525.  
  526.                 /* Reset the scanner. */
  527.  
  528.             FlowInit(TRUE);
  529.  
  530.                 /* Reset the number of dial attempts. */
  531.  
  532.             DialAttempt    = 0;
  533.  
  534.                 /* Get the first dial list entry. */
  535.  
  536.             DialNode    = (struct PhoneNode *)DialList -> lh_Head;
  537.  
  538.                 /* The big dialing loop, implemented as a goto -> mark
  539.                  * loop rather than one of those classical while .. do
  540.                  * loops.
  541.                  */
  542.  
  543. Dial:            Dialing        = TRUE;
  544.  
  545.                 /* Reset the sequence scanner, the user may have skipped
  546.                  * the previous dial attempt causing the modem to return
  547.                  * `NO CARRIER'. To prevent the dialer from skipping the
  548.                  * next dial entry as well as the previous we have to
  549.                  * flush any data pending on the serial line.
  550.                  */
  551.  
  552.             HandleSerial();
  553.  
  554.             FlowInit(TRUE);
  555.  
  556.                 /* Now for multiple phone numbers separated
  557.                  * by `|' characters. If `NextNumber' happens
  558.                  * to be zero, we will prepare to extract
  559.                  * the first phone number from the list.
  560.                  * In any other case we will try to obtain
  561.                  * the next number.
  562.                  */
  563.  
  564.             if(NextNumber)
  565.             {
  566.                 NextNumber    = ExtractString(NextNumber,    NumberBuffer,TRUE);
  567.                 NextInit    = ExtractString(NextInit,    InitBuffer,FALSE);
  568.                 NextExit    = ExtractString(NextExit,    ExitBuffer,FALSE);
  569.                 NextPrefix    = ExtractString(NextPrefix,    PrefixBuffer,FALSE);
  570.  
  571.                 NumberCurrent++;
  572.             }
  573.             else
  574.             {
  575.                 STRPTR    PhoneNumber;
  576.                 WORD    i,Len;
  577.  
  578.                 if(DialNode -> Entry)
  579.                 {
  580.                     PhoneNumber = DialNode -> Entry -> Header -> Number;
  581.  
  582.                     if(DialNode -> Entry -> Config -> ModemConfig)
  583.                     {
  584.                         NextInit    = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> ModemInit,InitBuffer,FALSE);
  585.                         NextExit    = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> ModemExit,ExitBuffer,FALSE);
  586.                         NextPrefix    = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> DialPrefix,PrefixBuffer,FALSE);
  587.                     }
  588.                     else
  589.                     {
  590.                         NextInit    = ExtractString(Config -> ModemConfig -> ModemInit,InitBuffer,FALSE);
  591.                         NextExit    = ExtractString(Config -> ModemConfig -> ModemExit,ExitBuffer,FALSE);
  592.                         NextPrefix    = ExtractString(Config -> ModemConfig -> DialPrefix,PrefixBuffer,FALSE);
  593.                     }
  594.                 }
  595.                 else
  596.                 {
  597.                     PhoneNumber = DialNode -> VanillaNode . ln_Name;
  598.  
  599.                     NextInit    = ExtractString(Config -> ModemConfig -> ModemInit,InitBuffer,FALSE);
  600.                     NextExit    = ExtractString(Config -> ModemConfig -> ModemExit,ExitBuffer,FALSE);
  601.                     NextPrefix    = ExtractString(Config -> ModemConfig -> DialPrefix,PrefixBuffer,FALSE);
  602.                 }
  603.  
  604.                 NextNumber = ExtractString(PhoneNumber,NumberBuffer,TRUE);
  605.  
  606.                 Len = strlen(PhoneNumber);
  607.  
  608.                 for(i = 0, NumberCount = 0 ; i < Len ; i++)
  609.                 {
  610.                     if(PhoneNumber[i] == '|')
  611.                     {
  612.                         WORD j;
  613.  
  614.                         for(j = i + 1 ; j <= Len ; j++)
  615.                         {
  616.                             if(PhoneNumber[j] != ' ' && PhoneNumber[j] != 0)
  617.                             {
  618.                                 if(PhoneNumber[j] != '|')
  619.                                     NumberCount++;
  620.  
  621.                                 break;
  622.                             }
  623.                         }
  624.                     }
  625.                 }
  626.  
  627.                 NumberCurrent = 0;
  628.             }
  629.  
  630.                 /* If DialNode -> Entry is nonzero it has
  631.                  * a configuration attached.
  632.                  */
  633.  
  634.             if(DialNode -> Entry)
  635.             {
  636.                 if(DialNode -> Entry -> Config -> ModemConfig)
  637.                 {
  638.                     DialTimeout    = DialNode -> Entry -> Config -> ModemConfig -> DialTimeout;
  639.                     DialRetries    = DialNode -> Entry -> Config -> ModemConfig -> DialRetries;
  640.                 }
  641.                 else
  642.                 {
  643.                     DialTimeout    = Config -> ModemConfig -> DialTimeout;
  644.                     DialRetries    = Config -> ModemConfig -> DialRetries;
  645.                 }
  646.  
  647.                     /* Send the modem exit string before we
  648.                      * will need to reconfigure the serial
  649.                      * device driver.
  650.                      */
  651.  
  652.                 if(ExitString[0])
  653.                 {
  654.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT));
  655.  
  656.                     FlowInit(TRUE);
  657.  
  658.                     SerialCommand(ExitString);
  659.  
  660.                     WaitTime(1,0);
  661.  
  662.                     HandleSerial();
  663.  
  664.                     if(FlowInfo . Changed && FlowInfo . Error)
  665.                     {
  666.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  667.  
  668.                         GotError = TRUE;
  669.  
  670.                         goto Quit;
  671.                     }
  672.                 }
  673.  
  674.                     /* We will need to change the serial parameters
  675.                      * in order to establish a connection.
  676.                      */
  677.  
  678.                 if(DialNode -> Entry -> Config -> SerialConfig)
  679.                 {
  680.                     if(ReconfigureSerial(PanelWindow,DialNode -> Entry -> Config -> SerialConfig) == RECONFIGURE_FAILURE)
  681.                         goto Quit;
  682.                 }
  683.                 else
  684.                 {
  685.                     if(ReconfigureSerial(PanelWindow,&OriginalSerialConfig) == RECONFIGURE_FAILURE)
  686.                         goto Quit;
  687.                 }
  688.  
  689.                     /* Send the modem init string. */
  690.  
  691.                 if(InitBuffer[0] && !Done)
  692.                 {
  693.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT));
  694.  
  695.                     FlowInit(TRUE);
  696.  
  697.                     SerialCommand(InitBuffer);
  698.  
  699.                     WaitTime(1,0);
  700.  
  701.                     HandleSerial();
  702.  
  703.                     if(FlowInfo . Changed && FlowInfo . Error)
  704.                     {
  705.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  706.  
  707.                         GotError = TRUE;
  708.  
  709.                         goto Quit;
  710.                     }
  711.                 }
  712.  
  713.                     /* Remember the new exit string. */
  714.  
  715.                 strcpy(ExitString,ExitBuffer);
  716.  
  717.                 Calling = DialNode -> Entry -> Header -> Name;
  718.  
  719.                 if(NumberCount)
  720.                 {
  721.                     UBYTE LocalBuffer[30];
  722.  
  723.                     SPrintf(LocalBuffer,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),NumberCurrent + 1,NumberCount + 1);
  724.  
  725.                     SPrintf(CallingBuffer,"%s (%s)",Calling,LocalBuffer);
  726.  
  727.                     Calling = CallingBuffer;
  728.                 }
  729.  
  730.                 PrintBox(Handle,GAD_CALLING,0,Calling);
  731.  
  732.                 if(DialNode -> Entry -> Header -> Comment[0])
  733.                     PrintBox(Handle,GAD_CALLING,1,DialNode -> Entry -> Header -> Comment);
  734.                 else
  735.                     PrintBox(Handle,GAD_CALLING,1,"-");
  736.  
  737.                 Say(LocaleString(MSG_DIALPANEL_NOW_CALLING_TXT),DialNode -> Entry -> Header -> Name);
  738.  
  739.                 strcpy(SomeBuffer,PrefixBuffer);
  740.  
  741.                 PrintBox(Handle,GAD_CALLING,2,NumberBuffer);
  742.  
  743.                 strcat(SomeBuffer,NumberBuffer);
  744.             }
  745.             else
  746.             {
  747.                 DialTimeout    = Config -> ModemConfig -> DialTimeout;
  748.                 DialRetries    = Config -> ModemConfig -> DialRetries;
  749.  
  750.                     /* Send the modem exit string. */
  751.  
  752.                 if(ExitString[0])
  753.                 {
  754.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT));
  755.  
  756.                     FlowInit(TRUE);
  757.  
  758.                     SerialCommand(ExitBuffer);
  759.  
  760.                     WaitTime(1,0);
  761.  
  762.                     HandleSerial();
  763.  
  764.                     if(FlowInfo . Changed && FlowInfo . Error)
  765.                     {
  766.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  767.  
  768.                         GotError = TRUE;
  769.  
  770.                         goto Quit;
  771.                     }
  772.                 }
  773.  
  774.                     /* Remember the new exit string. */
  775.  
  776.                 strcpy(ExitString,ExitBuffer);
  777.  
  778.                 Calling = LocaleString(MSG_GLOBAL_UNKNOWN_TXT);
  779.  
  780.                 if(NumberCount)
  781.                 {
  782.                     UBYTE LocalBuffer[30];
  783.  
  784.                     SPrintf(LocalBuffer,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),NumberCurrent + 1,NumberCount);
  785.  
  786.                     SPrintf(CallingBuffer,"%s (%s)",Calling,LocalBuffer);
  787.  
  788.                     Calling = CallingBuffer;
  789.                 }
  790.  
  791.                 PrintBox(Handle,GAD_CALLING,0,Calling);
  792.  
  793.                 PrintBox(Handle,GAD_CALLING,1,"-");
  794.  
  795.                 Say(LocaleString(MSG_DIALPANEL_NOW_CALLING_TXT),NumberBuffer);
  796.  
  797.                 strcpy(SomeBuffer,PrefixBuffer);
  798.  
  799.                 PrintBox(Handle,GAD_CALLING,2,NumberBuffer);
  800.  
  801.                 strcat(SomeBuffer,NumberBuffer);
  802.  
  803.                     /* Send the modem init string. */
  804.  
  805.                 if(InitBuffer[0])
  806.                 {
  807.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT));
  808.  
  809.                     FlowInit(TRUE);
  810.  
  811.                     SerialCommand(InitBuffer);
  812.  
  813.                     WaitTime(1,0);
  814.  
  815.                     HandleSerial();
  816.  
  817.                     if(FlowInfo . Changed && FlowInfo . Error)
  818.                     {
  819.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  820.  
  821.                         GotError = TRUE;
  822.  
  823.                         goto Quit;
  824.                     }
  825.                 }
  826.             }
  827.  
  828.             if(NextNumber)
  829.             {
  830.                 if(DialNode -> Entry)
  831.                     Calling = DialNode -> Entry -> Header -> Name;
  832.                 else
  833.                     Calling = DialNode -> VanillaNode . ln_Name;
  834.             }
  835.             else
  836.             {
  837.                 if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
  838.                 {
  839.                     if(DialNode -> Entry)
  840.                         Calling = ((struct PhoneNode *)DialNode -> VanillaNode . ln_Succ) -> Entry -> Header -> Name;
  841.                     else
  842.                         Calling = DialNode -> VanillaNode . ln_Succ -> ln_Name;
  843.                 }
  844.                 else
  845.                     Calling = "-";
  846.             }
  847.  
  848.             PrintBox(Handle,GAD_CALLING,3,Calling);
  849.  
  850.             if(DialNode -> Entry)
  851.             {
  852.                 if(DialNode -> Entry -> Config -> ModemConfig)
  853.                     strcat(SomeBuffer,DialNode -> Entry -> Config -> ModemConfig -> DialSuffix);
  854.                 else
  855.                     strcat(SomeBuffer,Config -> ModemConfig -> DialSuffix);
  856.             }
  857.             else
  858.                 strcat(SomeBuffer,Config -> ModemConfig -> DialSuffix);
  859.  
  860.             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_TXT));
  861.  
  862.                 /* Dial the number. */
  863.  
  864.             SerialCommand(SomeBuffer);
  865.  
  866.                 /* Reset the signal. */
  867.  
  868.             SetSignal(NULL,SIG_SKIP | SIG_BREAK);
  869.  
  870.             while(!Done)
  871.             {
  872.                 if(CheckSignal(SIG_BREAK))
  873.                 {
  874.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ABORTING_TXT));
  875.  
  876.                     if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  877.                         UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  878.                     else
  879.                         UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  880.  
  881.                     if(UseHangUp)
  882.                         HangUp();
  883.                     else
  884.                     {
  885.                         SerWrite("\r",1);
  886.                         WaitTime(1,0);
  887.                     }
  888.  
  889.                         /* Ignore the response of the modem. */
  890.  
  891.                     HandleSerial();
  892.  
  893.                     FlowInit(TRUE);
  894.  
  895.                     break;
  896.                 }
  897.  
  898.                 if(Dialing)
  899.                 {
  900.                     PrintBox(Handle,GAD_TIME,0,"%2ld:%02ld",DialTimeout / 60,DialTimeout % 60);
  901.  
  902.                     if(DialRetries < 0)
  903.                         PrintBox(Handle,GAD_TIME,1,LocaleString(MSG_DIAL_RETRIES_UNLIMITED_TXT));
  904.                     else
  905.                         PrintBox(Handle,GAD_TIME,1,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),DialAttempt + 1,DialRetries);
  906.                 }
  907.                 else
  908.                     PrintBox(Handle,GAD_TIME,0,"%2ld:%02ld",RedialDelay / 60,RedialDelay % 60);
  909.  
  910.                 WaitTime(0,MILLION / 2);
  911.  
  912.                     /* The following commands are executed each second */
  913.  
  914.                 if((RunCount++) && !Done)
  915.                 {
  916.                     RunCount = 0;
  917.  
  918.                         /* Are we dialing or waiting? */
  919.  
  920.                     if(Dialing)
  921.                     {
  922.                             /* No chance, the dial timeout
  923.                              * has elapsed and no connection
  924.                              * was made.
  925.                              */
  926.  
  927.                         if(!(--DialTimeout))
  928.                         {
  929.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIAL_ATTEMPT_TIMEOUT_TXT));
  930.  
  931. Skip1:
  932.                             if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  933.                                 UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  934.                             else
  935.                                 UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  936.  
  937.                             if(UseHangUp)
  938.                                 HangUp();
  939.                             else
  940.                             {
  941.                                 SerWrite("\r",1);
  942.                                 WaitTime(1,0);
  943.                             }
  944.  
  945.                                 /* Ignore the response of the modem. */
  946.  
  947.                             HandleSerial();
  948.  
  949.                             FlowInit(TRUE);
  950.  
  951.                                 /* Did we dial all the numbers available? */
  952.  
  953.                             if(NextNumber)
  954.                                 goto Dial;
  955.  
  956.                                 /* Is this one the last entry? */
  957.  
  958.                             if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
  959.                             {
  960.                                     /* Proceed to the next entry. */
  961.  
  962.                                 DialNode = (struct PhoneNode *)DialNode -> VanillaNode . ln_Succ;
  963.  
  964.                                 goto Dial;
  965.                             }
  966.                             else
  967.                             {
  968.                                     /* Is this one the last dial
  969.                                      * attempt to be made?
  970.                                      */
  971.  
  972.                                 if(++DialAttempt >= DialRetries && DialRetries >= 0)
  973.                                 {
  974.                                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  975.  
  976.                                     WakeUp(PanelWindow,SOUND_BELL);
  977.  
  978.                                     WaitTime(2,0);
  979.  
  980.                                     Say(LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  981.  
  982.                                     Done = TRUE;
  983.                                 }
  984.                                 else
  985.                                 {
  986.                                         /* Get the first list entry. */
  987.  
  988.                                     DialNode = (struct PhoneNode *)DialList -> lh_Head;
  989.  
  990.                                         /* Get the redial delay. */
  991.  
  992.                                     if(DialNode -> Entry)
  993.                                     {
  994.                                         if(DialNode -> Entry -> Config -> ModemConfig)
  995.                                             RedialDelay = DialNode -> Entry -> Config -> ModemConfig -> RedialDelay;
  996.                                         else
  997.                                             RedialDelay = Config -> ModemConfig -> RedialDelay;
  998.                                     }
  999.                                     else
  1000.                                         RedialDelay = Config -> ModemConfig -> RedialDelay;
  1001.  
  1002.                                         /* No redial delay? Restart dialing... */
  1003.  
  1004.                                     if(!RedialDelay)
  1005.                                     {
  1006.                                         WaitTime(1,0);
  1007.  
  1008.                                         goto Dial;
  1009.                                     }
  1010.                                     else
  1011.                                     {
  1012.                                             /* Go into redial delay. */
  1013.  
  1014.                                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_REDIAL_DELAY_TXT));
  1015.  
  1016.                                         Dialing = FALSE;
  1017.  
  1018.                                         Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
  1019.                                     }
  1020.                                 }
  1021.                             }
  1022.                         }
  1023.                     }
  1024.                     else
  1025.                     {
  1026.                         if(!(--RedialDelay))
  1027.                         {
  1028.                                 /* Get the first list entry. */
  1029.  
  1030. Skip2:                            DialNode = (struct PhoneNode *)DialList -> lh_Head;
  1031.  
  1032.                                 /* We are once again dialing. */
  1033.  
  1034.                             goto Dial;
  1035.                         }
  1036.                     }
  1037.                 }
  1038.  
  1039.                     /* Handle serial data flow. */
  1040.  
  1041.                 HandleSerial();
  1042.  
  1043.                     /* Something has changed in the flow
  1044.                      * info structure.
  1045.                      */
  1046.  
  1047.                 if(FlowInfo . Changed)
  1048.                 {
  1049.                         /* Current number is busy. */
  1050.  
  1051.                     if(FlowInfo . Busy || (FlowInfo . NoCarrier && Config -> ModemConfig -> NoCarrierIsBusy))
  1052.                     {
  1053.                         FlowInit(TRUE);
  1054.  
  1055.                         FlowInfo . Busy        = FALSE;
  1056.                         FlowInfo . NoCarrier    = FALSE;
  1057.                         FlowInfo . Changed    = FALSE;
  1058.  
  1059.                         if(Dialing)
  1060.                         {
  1061.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_LINE_IS_BUSY_TXT));
  1062.  
  1063.                             Say(LocaleString(MSG_DIALPANEL_LINE_IS_BUSY_TXT));
  1064.  
  1065.                             WaitTime(1,0);
  1066.  
  1067.                             goto Skip1;
  1068.                         }
  1069.                     }
  1070.  
  1071.                         /* Line does not feature a dialtone. */
  1072.  
  1073.                     if(FlowInfo . NoDialTone)
  1074.                     {
  1075.                         FlowInit(TRUE);
  1076.  
  1077.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_NO_DIALTONE_TXT));
  1078.  
  1079.                         WakeUp(PanelWindow,SOUND_BELL);
  1080.  
  1081.                         WaitTime(2,0);
  1082.  
  1083.                         Say(LocaleString(MSG_DIALPANEL_NO_DIALTONE_TXT));
  1084.  
  1085.                         Done = TRUE;
  1086.                     }
  1087.  
  1088.                         /* Somebody tries to call us. */
  1089.  
  1090.                     if(FlowInfo . Ring && !Done)
  1091.                     {
  1092.                         FlowInit(TRUE);
  1093.  
  1094.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  1095.  
  1096.                         WakeUp(PanelWindow,SOUND_RING);
  1097.  
  1098.                         WaitTime(2,0);
  1099.  
  1100.                         Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  1101.  
  1102.                         Done = TRUE;
  1103.                     }
  1104.  
  1105.                         /* Somebody's talking. */
  1106.  
  1107.                     if(FlowInfo . Voice && !Done)
  1108.                     {
  1109.                         FlowInit(TRUE);
  1110.  
  1111.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_INCOMING_VOICE_CALL_TXT));
  1112.  
  1113.                         WakeUp(PanelWindow,SOUND_VOICE);
  1114.  
  1115.                         WaitTime(2,0);
  1116.  
  1117.                         Say(LocaleString(MSG_DIALPANEL_INCOMING_VOICE_CALL_TXT));
  1118.  
  1119.                         Done = TRUE;
  1120.                     }
  1121.  
  1122.                         /* We got a connect. */
  1123.  
  1124.                     if(FlowInfo . Connect && !Done)
  1125.                     {
  1126.                         FlowInfo . Connect = FALSE;
  1127.                         FlowInfo . Changed = FALSE;
  1128.  
  1129.                         Connect(DialNode,NumberBuffer);
  1130.  
  1131.                         Done = TRUE;
  1132.  
  1133.                             /* Wake the user up. */
  1134.  
  1135.                         if(BaudBuffer[0])
  1136.                         {
  1137.                             PrintBox(Handle,GAD_NOTE,0,"CONNECT %s",BaudBuffer);
  1138.  
  1139.                             WakeUp(PanelWindow,SOUND_CONNECT);
  1140.  
  1141.                             WaitTime(2,0);
  1142.  
  1143.                                 /* Install new baud rate if desired. */
  1144.  
  1145.                             if(Config -> ModemConfig -> ConnectAutoBaud && DTERate > 110)
  1146.                             {
  1147.                                 Config -> SerialConfig -> BaudRate = DTERate;
  1148.  
  1149.                                 ReconfigureSerial(PanelWindow,NULL);
  1150.                             }
  1151.                         }
  1152.                         else
  1153.                         {
  1154.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_CONNECTION_ESTABLISHED_TXT));
  1155.  
  1156.                             WakeUp(PanelWindow,SOUND_CONNECT);
  1157.                         }
  1158.  
  1159.                         Say(LocaleString(MSG_DIALPANEL_CONNECTION_ESTABLISHED_TXT));
  1160.                     }
  1161.                 }
  1162.  
  1163.                     /* Look for the hotkey. */
  1164.  
  1165.                 if(CheckSignal(SIG_SKIP))
  1166.                 {
  1167.                     LT_PressButton(Handle,GAD_SKIP);
  1168.  
  1169.                         /* Are we dialing or waiting? */
  1170.  
  1171.                     if(Dialing)
  1172.                     {
  1173.                         DialTimeout = 0;
  1174.  
  1175.                         goto Skip1;
  1176.                     }
  1177.                     else
  1178.                     {
  1179.                         RedialDelay = 0;
  1180.  
  1181.                         goto Skip2;
  1182.                     }
  1183.                 }
  1184.  
  1185.                     /* Pick up the window input. */
  1186.  
  1187.                 while(!Done && (Message = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
  1188.                 {
  1189.                     MsgClass    = Message -> Class;
  1190.                     MsgQualifier    = Message -> Qualifier;
  1191.                     MsgCode        = Message -> Code;
  1192.                     MsgGadget    = (struct Gadget *)Message -> IAddress;
  1193.  
  1194.                     GT_ReplyIMsg(Message);
  1195.  
  1196.                     LT_HandleInput(Handle,MsgQualifier,&MsgClass,&MsgCode,&MsgGadget);
  1197.  
  1198.                     if(MsgClass == IDCMP_GADGETUP)
  1199.                         MsgGadgetID = MsgGadget -> GadgetID;
  1200.  
  1201.                     if(MsgClass == IDCMP_RAWKEY)
  1202.                     {
  1203.                         if(LT_GetCode(MsgQualifier,MsgClass,MsgCode,MsgGadget) == ' ')
  1204.                         {
  1205.                             MsgClass    = IDCMP_GADGETUP;
  1206.                             MsgCode        = 0;
  1207.                             MsgGadgetID    = GAD_SKIP;
  1208.  
  1209.                             LT_PressButton(Handle,GAD_SKIP);
  1210.                         }
  1211.                     }
  1212.  
  1213.                         /* Close the window, hang up the line. */
  1214.  
  1215.                     if(MsgClass == IDCMP_CLOSEWINDOW)
  1216.                     {
  1217.                         MsgClass    = IDCMP_GADGETUP;
  1218.                         MsgGadgetID    = GAD_ABORT;
  1219.  
  1220.                         Result = TRUE;
  1221.                     }
  1222.  
  1223.                     if(MsgClass == IDCMP_GADGETUP)
  1224.                     {
  1225.                         switch(MsgGadgetID)
  1226.                         {
  1227.                                     /* Don't proceed to the next number in the buffer! */
  1228.  
  1229.                             case GAD_REMOVE:
  1230.  
  1231.                                 NextNumber = NULL;
  1232.  
  1233.                                 if(Dialing)
  1234.                                 {
  1235.                                     struct PhoneNode *NextNode = NULL;
  1236.  
  1237.                                         /* Is there another entry in the list? */
  1238.  
  1239.                                     if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
  1240.                                         NextNode = (struct PhoneNode *)DialNode -> VanillaNode . ln_Succ;
  1241.                                     else
  1242.                                     {
  1243.                                             /* No, there isn't; do we have a list with
  1244.                                              * at least two entries in it?
  1245.                                              */
  1246.  
  1247.                                         if(DialList -> lh_Head -> ln_Succ -> ln_Succ)
  1248.                                         {
  1249.                                                 /* There is just a single entry
  1250.                                                  * available, check for dial retry
  1251.                                                  * limit.
  1252.                                                  */
  1253.  
  1254.                                             if(++DialAttempt >= DialRetries && DialRetries >= 0)
  1255.                                             {
  1256.                                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  1257.  
  1258.                                                 WakeUp(PanelWindow,SOUND_BELL);
  1259.  
  1260.                                                 WaitTime(2,0);
  1261.  
  1262.                                                 Say(LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  1263.  
  1264.                                                 Done = TRUE;
  1265.                                             }
  1266.                                             else
  1267.                                             {
  1268.                                                     /* Grab first list entry and continue. */
  1269.  
  1270.                                                 NextNode = (struct PhoneNode *)DialList -> lh_Head;
  1271.                                             }
  1272.                                         }
  1273.                                         else
  1274.                                         {
  1275.                                             Done = TRUE;
  1276.  
  1277.                                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_LIST_IS_EMPTY_TXT));
  1278.  
  1279.                                             WaitTime(2,0);
  1280.                                         }
  1281.                                     }
  1282.  
  1283.                                     DialTimeout = 0;
  1284.  
  1285.                                     if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  1286.                                         UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  1287.                                     else
  1288.                                         UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  1289.  
  1290.                                     if(UseHangUp)
  1291.                                         HangUp();
  1292.                                     else
  1293.                                     {
  1294.                                         SerWrite("\r",1);
  1295.                                         WaitTime(1,0);
  1296.                                     }
  1297.  
  1298.                                         /* Ignore the response of the modem. */
  1299.  
  1300.                                     HandleSerial();
  1301.  
  1302.                                     FlowInit(TRUE);
  1303.  
  1304.                                         /* Remove dial entry from list. */
  1305.  
  1306.                                     if(DialNode -> Entry)
  1307.                                         RemoveDialNode(DialNode);
  1308.  
  1309.                                     Remove(&DialNode -> VanillaNode);
  1310.  
  1311.                                     FreeVecPooled(DialNode);
  1312.  
  1313.                                         /* Is there an entry to proceed with? */
  1314.  
  1315.                                     if(NextNode)
  1316.                                     {
  1317.                                         DialNode = NextNode;
  1318.  
  1319.                                         goto Dial;
  1320.                                     }
  1321.                                 }
  1322.                                 else
  1323.                                 {
  1324.                                     struct PhoneNode *LastNode;
  1325.  
  1326.                                         /* We are to leave the redial delay loop,
  1327.                                          * are there at least two entries in
  1328.                                          * the list?
  1329.                                          */
  1330.  
  1331.                                     if(!DialList -> lh_Head -> ln_Succ -> ln_Succ)
  1332.                                     {
  1333.                                             /* No, there is just a single entry in
  1334.                                              * the list.
  1335.                                              */
  1336.  
  1337.                                         Done = TRUE;
  1338.  
  1339.                                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_LIST_IS_EMPTY_TXT));
  1340.  
  1341.                                         if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  1342.                                             UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  1343.                                         else
  1344.                                             UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  1345.  
  1346.                                         if(UseHangUp)
  1347.                                             HangUp();
  1348.                                         else
  1349.                                         {
  1350.                                             SerWrite("\r",1);
  1351.                                             WaitTime(2,0);
  1352.                                         }
  1353.  
  1354.                                             /* Ignore the response of the modem. */
  1355.  
  1356.                                         HandleSerial();
  1357.  
  1358.                                         FlowInit(TRUE);
  1359.                                     }
  1360.  
  1361.                                         /* Remove last dial entry from list. */
  1362.  
  1363.                                     LastNode = (struct PhoneNode *)DialList -> lh_TailPred;
  1364.  
  1365.                                     if(LastNode -> Entry)
  1366.                                         RemoveDialNode(LastNode);
  1367.  
  1368.                                     Remove(&LastNode -> VanillaNode);
  1369.  
  1370.                                     FreeVecPooled(LastNode);
  1371.  
  1372.                                         /* Get back to first list entry. */
  1373.  
  1374.                                     if(!Done)
  1375.                                     {
  1376.                                         RedialDelay = 0;
  1377.  
  1378.                                         goto Skip2;
  1379.                                     }
  1380.                                 }
  1381.  
  1382.                                 break;
  1383.  
  1384.                             case GAD_SKIP:
  1385.  
  1386.                                 if(Dialing)
  1387.                                 {
  1388.                                     DialTimeout = 0;
  1389.  
  1390.                                     goto Skip1;
  1391.                                 }
  1392.                                 else
  1393.                                 {
  1394.                                     RedialDelay = 0;
  1395.  
  1396.                                     goto Skip2;
  1397.                                 }
  1398.  
  1399.                             case GAD_ONLINE:
  1400.  
  1401.                                 Connect(DialNode,NumberBuffer);
  1402.  
  1403.                                 Done = TRUE;
  1404.  
  1405.                                 break;
  1406.  
  1407.                                 /* Abort the dialing process. */
  1408.  
  1409.                             case GAD_ABORT:
  1410.  
  1411.                                 Done = TRUE;
  1412.  
  1413.                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ABORTING_TXT));
  1414.  
  1415.                                 if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  1416.                                     UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  1417.                                 else
  1418.                                     UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  1419.  
  1420.                                 if(UseHangUp)
  1421.                                     HangUp();
  1422.                                 else
  1423.                                 {
  1424.                                     SerWrite("\r",1);
  1425.                                     WaitTime(1,0);
  1426.                                 }
  1427.  
  1428.                                     /* Ignore the response of the modem. */
  1429.  
  1430.                                 HandleSerial();
  1431.  
  1432.                                 FlowInit(TRUE);
  1433.  
  1434.                                 break;
  1435.                         }
  1436.                     }
  1437.                 }
  1438.             }
  1439.  
  1440.                 /* Are we online or not? */
  1441.  
  1442. Quit:            ObtainSemaphore(&OnlineSemaphore);
  1443.  
  1444.             if(!Online)
  1445.             {
  1446.                 ReleaseSemaphore(&OnlineSemaphore);
  1447.  
  1448.                     /* Is the serial setup different? */
  1449.  
  1450.                 if(memcmp(Config -> SerialConfig,PrivateConfig -> SerialConfig,sizeof(struct SerialSettings)))
  1451.                 {
  1452.                         /* Swap the serial data. */
  1453.  
  1454.                     swmem(Config -> SerialConfig,PrivateConfig -> SerialConfig,sizeof(struct SerialSettings));
  1455.  
  1456.                         /* Set up the old serial configuration. */
  1457.  
  1458.                     if(ReconfigureSerial(PanelWindow,NULL) != RECONFIGURE_FAILURE)
  1459.                     {
  1460.                         if(ExitString[0])
  1461.                         {
  1462.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT));
  1463.  
  1464.                             FlowInit(TRUE);
  1465.  
  1466.                             SerialCommand(ExitBuffer);
  1467.  
  1468.                             WaitTime(1,0);
  1469.  
  1470.                             HandleSerial();
  1471.  
  1472.                             if(FlowInfo . Changed && FlowInfo . Error)
  1473.                             {
  1474.                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1475.  
  1476.                                 GotError = TRUE;
  1477.                             }
  1478.                         }
  1479.  
  1480.                         if(Config -> ModemConfig -> ModemInit[0] && !GotError)
  1481.                         {
  1482.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT));
  1483.  
  1484.                             FlowInit(TRUE);
  1485.  
  1486.                             SerialCommand(Config -> ModemConfig -> ModemInit);
  1487.  
  1488.                             WaitTime(1,0);
  1489.  
  1490.                             HandleSerial();
  1491.  
  1492.                             if(FlowInfo . Changed && FlowInfo . Error)
  1493.                             {
  1494.                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1495.  
  1496.                                 GotError = TRUE;
  1497.                             }
  1498.                         }
  1499.                     }
  1500.                 }
  1501.             }
  1502.             else
  1503.                 ReleaseSemaphore(&OnlineSemaphore);
  1504.  
  1505.             if(GotError)
  1506.             {
  1507.                 WORD i;
  1508.  
  1509.                 for(i = GAD_SKIP ; i <= GAD_REMOVE ; i++)
  1510.                     LT_SetAttributes(Handle,i,GA_Disabled,TRUE,TAG_DONE);
  1511.  
  1512.                 WakeUp(PanelWindow,SOUND_BELL);
  1513.  
  1514.                 Done = FALSE;
  1515.  
  1516.                 do
  1517.                 {
  1518.                     if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
  1519.                         break;
  1520.  
  1521.                     while(Message = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort))
  1522.                     {
  1523.                         MsgClass    = Message -> Class;
  1524.                         MsgQualifier    = Message -> Qualifier;
  1525.                         MsgCode        = Message -> Code;
  1526.                         MsgGadget    = (struct Gadget *)Message -> IAddress;
  1527.  
  1528.                         GT_ReplyIMsg(Message);
  1529.  
  1530.                         LT_HandleInput(Handle,MsgQualifier,&MsgClass,&MsgCode,&MsgGadget);
  1531.  
  1532.                         if(MsgClass == IDCMP_CLOSEWINDOW || MsgClass == IDCMP_GADGETUP)
  1533.                             Done = TRUE;
  1534.                     }
  1535.                 }
  1536.                 while(!Done);
  1537.             }
  1538.  
  1539.             PopWindow();
  1540.         }
  1541.  
  1542.         LT_DeleteHandle(Handle);
  1543.     }
  1544.  
  1545.     ReleaseWindows();
  1546.  
  1547.             /* Reset the scanner. */
  1548.  
  1549.     FullCheck = FALSE;
  1550.  
  1551.     FlowInit(TRUE);
  1552.  
  1553.         /* We are done now, restart echoing serial */
  1554.  
  1555.     Quiet = FALSE;
  1556.  
  1557.         /* Reset the display if necessary. */
  1558.  
  1559.     if(ResetDisplay)
  1560.     {
  1561.         if(!DisplayReset())
  1562.             return(FALSE);
  1563.     }
  1564.  
  1565.     ObtainSemaphore(&OnlineSemaphore);
  1566.  
  1567.     if(Online)
  1568.     {
  1569.         ReleaseSemaphore(&OnlineSemaphore);
  1570.  
  1571.         SetDialMenu(FALSE);
  1572.  
  1573.             /* Send the startup macro if necessary. */
  1574.  
  1575.         if(SendStartup)
  1576.         {
  1577.             if(Config -> CommandConfig -> LoginMacro[0])
  1578.                 SerialCommand(Config -> CommandConfig -> LoginMacro);
  1579.  
  1580.             if(Config -> CommandConfig -> StartupMacro[0])
  1581.                 SerialCommand(Config -> CommandConfig -> StartupMacro);
  1582.  
  1583.             SendStartup = FALSE;
  1584.         }
  1585.  
  1586.             /* Take care of the recording feature. */
  1587.  
  1588.         if(Record)
  1589.         {
  1590.             if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : CurrentBBSNumber))
  1591.             {
  1592.                 RememberResetOutput();
  1593.                 RememberResetInput();
  1594.  
  1595.                 RememberOutput = TRUE;
  1596.  
  1597.                 Recording = TRUE;
  1598.                 RecordingLine = FALSE;
  1599.  
  1600.                 OnItem(MEN_RECORD_LINE);
  1601.             
  1602.                 CheckItem(MEN_RECORD,TRUE);
  1603.                 CheckItem(MEN_RECORD_LINE,FALSE);
  1604.             }
  1605.         }
  1606.  
  1607.         Forbid();
  1608.  
  1609.         if(DialMsg)
  1610.         {
  1611.             DialMsg -> rm_Result1 = RC_OK;
  1612.             DialMsg -> rm_Result2 = 0;
  1613.  
  1614.             ReplyMsg(DialMsg);
  1615.  
  1616.             DialMsg = NULL;
  1617.         }
  1618.  
  1619.         Permit();
  1620.     }
  1621.     else
  1622.     {
  1623.         ReleaseSemaphore(&OnlineSemaphore);
  1624.  
  1625.         Forbid();
  1626.  
  1627.         if(DialMsg)
  1628.         {
  1629.             DialMsg -> rm_Result1 = RC_WARN;
  1630.             DialMsg -> rm_Result2 = 0;
  1631.  
  1632.             ReplyMsg(DialMsg);
  1633.  
  1634.             DialMsg = NULL;
  1635.         }
  1636.  
  1637.         SetDialMenu(TRUE);
  1638.  
  1639.         Permit();
  1640.     }
  1641.  
  1642.     return(Result);
  1643. }
  1644.