home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / XSRVMAIN.C < prev    next >
Text File  |  1996-08-23  |  42KB  |  1,137 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   xsrvmain.c                                                              */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  Esp main function.                                                       */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   12/08/92 Created.                                                       */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14. #include "all.h"
  15.  
  16. static ESP_PARMS EspParms;
  17.  
  18. ESP_PARMS *GetEspParms   ( void ) { return(&EspParms); }
  19.  
  20. BOOL IsParent      ( void ) { return(EspParms.EspFlags.IsParentEsp)   ;}
  21. BOOL SingleMultiple( void ) { return(EspParms.EspFlags.SingleMultiple);}
  22. BOOL IsVerbose     ( void ) { return(EspParms.EspFlags.Verbose)       ;}
  23. BOOL DosDebugTrace ( void ) { return(EspParms.EspFlags.DosDebugTrace );}
  24. BOOL UseExecPgm    ( void ) { return(EspParms.EspFlags.UseExecPgm )   ;}
  25. BOOL DebugChild    ( void ) { return(EspParms.EspFlags.DebugChild )   ;}
  26. BOOL UseDebug      ( void ) { return(EspParms.EspFlags.UseDebug)      ;}
  27.  
  28. /*****************************************************************************/
  29. /* main()                                                                    */
  30. /*                                                                           */
  31. /* Description:                                                              */
  32. /*                                                                           */
  33. /*   Execution services probe main routine.                                  */
  34. /*                                                                           */
  35. /* Parameters:                                                               */
  36. /*                                                                           */
  37. /*   argc       Number of input parameters.                                  */
  38. /*   argv       -> -> to argument strings.                                   */
  39. /*                                                                           */
  40. /* Return:                                                                   */
  41. /*                                                                           */
  42. /* Assumptions:                                                              */
  43. /*                                                                           */
  44. /*****************************************************************************/
  45. int main( int argc, char **argv )
  46. {
  47.  APIRET      rc;
  48.  COMMAND     cmd = {0,0};
  49.  int         n;
  50.  char       *cp;
  51.  char        rc_string[12];
  52.  CONNECTION  Connection;
  53.  
  54.  EXCEPTIONREGISTRATIONRECORD  reg_rec;
  55.  
  56.  ESP_QUE_ELEMENT Qelement;
  57.  
  58.  
  59.  if( argc == 1 )
  60.   SayMsg(HELP_INVOCATION_ESP);
  61.  
  62.  /****************************************************************************/
  63.  /*                                                                          */
  64.  /* Parse the invocation options.                                            */
  65.  /*                                                                          */
  66.  /* - If this is a child debugger, then these additional parameters will     */
  67.  /*   precede the invocation parameters inherited from the parent.           */
  68.  /*                                                                          */
  69.  /*   - /child=xxxxx  where child  = child debugger and                      */
  70.  /*                         xxxxx  = child pid (for serial connections only.)*/
  71.  /*                                                                          */
  72.  /*   - /handle=xxxxx where handle = switch for com handle( serial only )    */
  73.  /*                         xxxxx  = parent's com handle - inherited by      */
  74.  /*                                  the child.                              */
  75.  /*                                                                          */
  76.  /****************************************************************************/
  77.  memset( &EspParms,   0, sizeof( ESP_PARMS ) );
  78.  memset( &Connection, 0, sizeof(Connection) );
  79.  if( strstr( argv[1], "/child" ) )
  80.  {
  81.   ParseEspChildOptions( argc, argv, &EspParms, &Connection );
  82.  }
  83.  else
  84.  {
  85.   ParseOptions( argc, argv, &EspParms, &Connection );
  86.  }
  87.  
  88.  printf("\nESP Version 5.00 \n");fflush(0);
  89.  
  90.  /****************************************************************************/
  91.  /* - Send connection info to the router.                                    */
  92.  /****************************************************************************/
  93.  SendConnectionToRouter( &Connection );
  94.  
  95.  /****************************************************************************/
  96.  /* - Make the connection.                                                   */
  97.  /****************************************************************************/
  98.  {
  99.   int RcMoreInfo = 0;
  100.  
  101.   rc = ConnectInit( &RcMoreInfo );
  102.  
  103.   if( rc != 0 )
  104.   {
  105.    char  BadConnectMsg[32] = "";
  106.    int   MsgId;
  107.  
  108.    if( (Connection.ConnectType == _NETBIOS) && (RcMoreInfo != 0) )
  109.    {
  110.     /*************************************************************************/
  111.     /* - handle netbios specific connect errors.                             */
  112.     /*************************************************************************/
  113.     n     = 1;
  114.     MsgId = ERR_NB_INADEQUATE_RESOURCES;
  115.  
  116.     switch( RcMoreInfo )
  117.     {
  118.      case CANT_LOAD_NETB_DLL:
  119.       n     = 0;
  120.       MsgId = ERR_NB_CANT_LOAD_DLL;
  121.       break;
  122.  
  123.      case INADEQUATE_SESSIONS:
  124.       strcpy( BadConnectMsg,"sessions");
  125.       break;
  126.  
  127.      case INADEQUATE_COMMANDS:
  128.       strcpy( BadConnectMsg,"commands");
  129.       break;
  130.  
  131.      case INADEQUATE_NAMES:
  132.       strcpy( BadConnectMsg,"names");
  133.       break;
  134.  
  135.      default:
  136.       n = 1;
  137.       MsgId = ERR_BAD_CONNECT;
  138.       sprintf( BadConnectMsg, "NetBios error rc=%d", rc );
  139.       break;
  140.     }
  141.    }
  142.    else if( (Connection.ConnectType == SOCKET) && (RcMoreInfo != 0) )
  143.    {
  144.     /*************************************************************************/
  145.     /* - handle tcpip specific connect errors.                               */
  146.     /*************************************************************************/
  147.     switch( RcMoreInfo )
  148.     {
  149.      case CANT_LOAD_TCPIP_DLL:
  150.       n     = 1;
  151.       MsgId = ERR_TCPIP_CANT_LOAD_DLL;
  152.  
  153.       sprintf( BadConnectMsg, "%d", rc );
  154.       break;
  155.  
  156.      case TCPIP_NOT_RUNNING:
  157.       n     = 0;
  158.       MsgId = ERR_TCPIP_NOT_RUNNING;
  159.       break;
  160.  
  161.      case TCPIP_ERROR:
  162.       n     = 0;
  163.       MsgId = ERR_TCPIP_ERROR;
  164.       break;
  165.  
  166.      case TCPIP_NO_SERVICES_PORT:
  167.       n     = 0;
  168.       MsgId = ERR_TCPIP_NO_SERVICES_PORT;
  169.       break;
  170.  
  171.      default:
  172.       n = 1;
  173.       MsgId = ERR_BAD_CONNECT;
  174.       sprintf( BadConnectMsg, "tcpip error rc=%d", rc );
  175.       break;
  176.     }
  177.    }
  178.    else
  179.    {
  180.     /*************************************************************************/
  181.     /* - handle generic connect errors.                                      */
  182.     /*************************************************************************/
  183.     n = 1;
  184.     MsgId = ERR_BAD_CONNECT;
  185.     sprintf( BadConnectMsg, "rc=%d", rc );
  186.    }
  187.    ErrorPrintf( MsgId, n, BadConnectMsg );
  188.   }
  189.  }
  190.  
  191.  /****************************************************************************/
  192.  /* - register an exception handler for the probe.                           */
  193.  /****************************************************************************/
  194.  reg_rec.ExceptionHandler = Handler;
  195.  DosSetExceptionHandler(®_rec);
  196.  
  197.  /****************************************************************************/
  198.  /* - Add a connect sema4 for serial connections and wait to be posted.      */
  199.  /****************************************************************************/
  200.  if( (SerialParallel() == SERIAL) && ( IsParent() == FALSE ) )
  201.  {
  202.   USHORT   EspPid;
  203.   TIB     *pTib;
  204.   PIB     *pPib;
  205.   ALLPIDS *p;
  206.  
  207.   SetComHandle( EspParms.handle );
  208.  
  209.   DosGetInfoBlocks(&pTib,&pPib);
  210.   EspPid = (USHORT)pPib->pib_ulpid;
  211.   CreateConnectSema4( EspPid, _ESP );
  212.   SerialConnect( JUST_WAIT, 0, _ESP, SendMsgToEspQue );
  213.   p = GetEspPid( EspPid );
  214.   p->Connect = CONNECTED;
  215.  }
  216.  
  217.  /****************************************************************************/
  218.  /* - Each child debugger will have a termination que so we can kill the     */
  219.  /*   child debuggers on quit/restart.                                       */
  220.  /****************************************************************************/
  221.  if( IsParent() == FALSE )
  222.  {
  223.   rc = StartEspTermQue( );
  224.   if( rc != 0 )
  225.   {
  226.    sprintf(rc_string, "%d",rc);
  227.    ErrorPrintf( ERR_CANT_START_QUE, TRUE, 1, rc_string );
  228.   }
  229.  }
  230.  /****************************************************************************/
  231.  /* - Now, start the command processing loop.                                */
  232.  /****************************************************************************/
  233.  for(;;)
  234.  {
  235.   memset(&cmd,0,sizeof(cmd) );
  236.   RmtRecv(DEFAULT_HANDLE, (char*)&cmd, sizeof(cmd));
  237.   if( IsVerbose() ) PrintCmdMessage( cmd.api ) ;
  238.   switch( cmd.api )
  239.   {
  240.    case FINDEXE:
  241.     RxFindExe(cmd);
  242.     break;
  243.  
  244.    case STARTUSER:
  245.     RxStartUser( cmd );
  246.     break;
  247.  
  248.    case GOINIT:
  249.     RxGoInit(cmd);
  250.     break;
  251.  
  252.    case GOENTRY:
  253.     RxGoEntry(cmd);
  254.     break;
  255.  
  256.    case DEFBRK:
  257.     RxDefBrk(cmd);
  258.     break;
  259.  
  260.    case UNDBRK:
  261.     RxUndBrk(cmd);
  262.     break;
  263.  
  264.    case PUTINBRK:
  265.     RxPutInBrk(cmd);
  266.     break;
  267.  
  268.    case PULLOUTBRK:
  269.     RxPullOutBrk(cmd);
  270.     break;
  271.  
  272.    case INSERTALLBRK:
  273.     RxInsertAllBrk();
  274.     break;
  275.  
  276.    case REMOVEALLBRK:
  277.     RxRemoveAllBrk();
  278.     break;
  279.  
  280.    case SELECT_SESSION:
  281.     /*************************************************************************/
  282.     /* - Only the parent probe can select one of the debuggee sessions, so   */
  283.     /*   we send a message and tell him to do it.                            */
  284.     /*************************************************************************/
  285.     Qelement.ChildPid = GetEspProcessID();
  286.     SendMsgToEspQue( ESP_QMSG_SELECT_SESSION, &Qelement, sizeof(Qelement) );
  287.  
  288.     memset(&cmd,0,sizeof(cmd) );
  289.  
  290.     cmd.api = SELECT_SESSION;
  291.     RmtSend( DEFAULT_HANDLE, &cmd, sizeof(cmd) );
  292.     break;
  293.  
  294.    case GOSTEP:
  295.     RxGoStep(cmd);
  296.     break;
  297.  
  298.    case GOFAST:
  299.     RxGoFast(cmd);
  300.     break;
  301.  
  302.    case DOSDEBUG:
  303.     RxDosDebug( cmd );
  304.     break;
  305.  
  306.    case GETTHREADINFO:
  307.     RxGetThreadInfo( cmd );
  308.     break;
  309.  
  310.    case FREEZETHREAD:
  311.     RxFreezeThread( cmd );
  312.     break;
  313.  
  314.    case THAWTHREAD:
  315.     RxThawThread( cmd );
  316.     break;
  317.  
  318.    case GETCALLSTACK:
  319.     RxGetCallStack(cmd);
  320.     break;
  321.  
  322.    case GETEXEORDLLENTRY:
  323.     RxGetExeOrDllEntryOrExitPt(cmd);
  324.     break;
  325.  
  326.    case NORMALQUIT:
  327.     RxNormalQuit(cmd);
  328.  
  329.     /*************************************************************************/
  330.     /* - The que has to be up until after the normal quit because the        */
  331.     /*   system will need to post an end session message to the queue.       */
  332.     /*************************************************************************/
  333.     if( IsParent() )
  334.     {
  335.      if( SingleMultiple() == MULTIPLE )
  336.      {
  337.       ALLPIDS *p;
  338.       /***********************************************************************/
  339.       /* - Send a message to all of the child probes telling them that       */
  340.       /*   they are going to be killed.                                      */
  341.       /***********************************************************************/
  342.       for( p = GetAllpids(); p ; p = p->next )
  343.       {
  344.        if( (p->PidFlags.IsDebug) == TRUE && (p->pid != GetEspProcessID()) )
  345.        {
  346.         ESP_QUE_ELEMENT Qelement;
  347.  
  348.         Qelement.ChildPid = p->EspPid;
  349.  
  350.         SendMsgToEspTermQue(ESP_PROBE_TERM, &Qelement, sizeof(Qelement) );
  351.        }
  352.       }
  353.       /***********************************************************************/
  354.       /* - send a message to the que to kill all the child probes and        */
  355.       /*   then wait until they are all dead.                                */
  356.       /***********************************************************************/
  357.       ResetAllProbesAreDeadFlag( );
  358.       SendMsgToEspQue(ESP_QMSG_PARENT_TERM,NULL,0);
  359.       while( AllProbesAreDead() == FALSE ){ DosSleep(100) ;}
  360.      }
  361.      SendMsgToEspQue(ESP_QMSG_QUE_TERM,NULL,0);
  362.     }
  363.  
  364.     CloseConnectSema4();
  365.  
  366.     cmd.api  = NORMALQUIT;
  367.     cmd.len  = sizeof(rc);
  368.  
  369.     /*************************************************************************/
  370.     /* - Now, tell dbg that we're finished normal quitting.                  */
  371.     /*************************************************************************/
  372.     RmtSend(DEFAULT_HANDLE, &cmd , sizeof(cmd) );
  373.     RmtSend(DEFAULT_HANDLE, &rc, cmd.len );
  374.     break;
  375.  
  376.    case SETEXECADDR:
  377.     RxSetExecAddr(cmd);
  378.     break;
  379.  
  380.    case DEFWPS:
  381.     RxDefWps(cmd);
  382.     break;
  383.  
  384.    case PUTINWPS:
  385.     RxPutInWps(cmd);
  386.     break;
  387.  
  388.    case PULLOUTWPS:
  389.     RxPullOutWps(cmd);
  390.     break;
  391.  
  392.    case GETDATABYTES:
  393.     RxGetDataBytes(cmd);
  394.     break;
  395.  
  396.    case GETMEMBLKS:
  397.     RxGetMemBlocks(cmd);
  398.     break;
  399.  
  400.    case SETXCPTNOTIFY:
  401.     RxSetExceptions(cmd);
  402.     break;
  403.  
  404.    case SETEXECTHREAD:
  405.     RxSetExecThread(cmd);
  406.     break;
  407.  
  408.    case WRITEREGS:
  409.     RxWriteRegs(cmd);
  410.     break;
  411.  
  412.    case GETCOREGS:
  413.     RxGetCoRegs(cmd);
  414.     break;
  415.  
  416.    case SETESPRUNOPTS:
  417.     RxSetEspRunOpts(cmd);
  418.     break;
  419.  
  420.    case TERMINATEESP:
  421.     if( IsParent() == FALSE )
  422.     {
  423.      memset( &Qelement, 0, sizeof(Qelement) );
  424.      Qelement.ChildPid = GetEspProcessID();
  425.  
  426.      SendMsgToEspQue( ESP_QMSG_CHILD_TERM, &Qelement, sizeof(Qelement) );
  427.     }
  428.     DosUnsetExceptionHandler(®_rec);
  429.     RmtSend(DEFAULT_HANDLE, &cmd , sizeof(cmd) );
  430.     ConnectClose( DEFAULT_HANDLE );
  431.     exit(0);
  432.     break;
  433.  
  434.    case START_QUE_LISTEN:
  435.     SendMsgToEspQue(ESP_QMSG_OPEN_CONNECT,NULL,0);
  436.     break;
  437.  
  438.    case START_ESP_QUE:
  439.     RxStartEspQue(cmd);
  440.     break;
  441.  
  442.    case CONNECT_ESP:
  443.     /*************************************************************************/
  444.     /* - Serial connection only.                                             */
  445.     /*************************************************************************/
  446.     {
  447.      USHORT   GoToPid;
  448.      USHORT   YieldPid;
  449.      ALLPIDS *pYield;
  450.      ALLPIDS *pGoTo;
  451.      BOOL     TorF;
  452.  
  453.      /************************************************************************/
  454.      /* - Receive the pid to be connected and mark it connected.             */
  455.      /* - If this pid has not yet been assigned to a probe, then pGoTo       */
  456.      /*   will be NULL.                                                      */
  457.      /* - There MUST be a probe with a pid==0, so we release that probe.     */
  458.      /*   ( The pid will be stuffed into the structure at goinit() time.)    */
  459.      /* - Post the connect sema4 for the goto pid.                           */
  460.      /************************************************************************/
  461.      RmtRecv( DEFAULT_HANDLE, &GoToPid, cmd.len );
  462.      pGoTo          = GetPid( GoToPid );
  463.  
  464.      if( pGoTo == NULL )
  465.       pGoTo = GetPid(0);
  466.  
  467.      pGoTo->Connect = CONNECTED;
  468.  
  469.  
  470.      TorF = TRUE;
  471.      if( GoToPid == GetEspProcessID() )
  472.       TorF = FALSE;
  473.  
  474.      /************************************************************************/
  475.      /* - Send back verification that the connection has been made.          */
  476.      /************************************************************************/
  477.      memset(&cmd,0,sizeof(cmd) );
  478.  
  479.      cmd.api = SERIAL_POLL;
  480.      RmtSend( DEFAULT_HANDLE, &cmd, sizeof(cmd) );
  481.  
  482.      PostConnectSema4( &pGoTo->ConnectSema4, TorF );
  483.  
  484.      /************************************************************************/
  485.      /* - Disconnect/block this probe.                                       */
  486.      /************************************************************************/
  487.      YieldPid        = (USHORT)GetEspProcessID();
  488.      pYield          = GetPid( YieldPid );
  489.      pYield->Connect = DISCONNECTED;
  490.  
  491.      SerialConnect( SET_WAIT, YieldPid, _ESP, SendMsgToEspQue );
  492.     }
  493.     break;
  494.  
  495.    case CTRL_BREAK:
  496.     {
  497.      USHORT          ThisPid;
  498.      USHORT          CtrlBreakPid;
  499.  
  500.      RmtRecv( DEFAULT_HANDLE, &CtrlBreakPid, cmd.len );
  501.  
  502.      ThisPid = (USHORT)GetEspProcessID();
  503.  
  504.      Qelement.ChildPid = CtrlBreakPid;
  505.      Qelement.ChildSid = ThisPid;
  506.  
  507.      SendMsgToEspQue(ESP_QMSG_CTRL_BREAK, &Qelement, sizeof(Qelement));
  508.  
  509.      SerialConnect( SET_WAIT, ThisPid,  _ESP, SendMsgToEspQue );
  510.     }
  511.     break;
  512.  
  513.    case SERIAL_POLL:
  514.     ReportMessage();
  515.     break;
  516.  
  517.    default:
  518.     cp = (char*)&cmd;
  519.     for( n=1; n<=sizeof(cmd); n++,cp++)
  520.      printf("%c",*cp);
  521.     AsyncFlushModem();
  522.     break;
  523.   }
  524.  }
  525. }
  526.  
  527. /*****************************************************************************/
  528. /* ParseOptions()                                                            */
  529. /*                                                                           */
  530. /* Description:                                                              */
  531. /*                                                                           */
  532. /*   - Parse the invocation options.                                         */
  533. /*                                                                           */
  534. /* Parameters:                                                               */
  535. /*                                                                           */
  536. /*   argc        Number of input parameters.                                 */
  537. /*   argv        -> -> to argument strings.                                  */
  538. /*   pEspParms   -> to the structure that will define the invocation parms.  */
  539. /*   pConnection -> to the structure that will define the connection parms.  */
  540. /*                                                                           */
  541. /* Return:                                                                   */
  542. /*                                                                           */
  543. /*   void                                                                    */
  544. /*                                                                           */
  545. /* Assumptions:                                                              */
  546. /*                                                                           */
  547. /*****************************************************************************/
  548. void ParseOptions( int          argc,
  549.                    char       **argv,
  550.                    ESP_PARMS    *pEspParms,
  551.                    CONNECTION  *pConnection)
  552. {
  553.  char          ParmString[512];
  554.  char          FileSpec[CCHMAXPATH];
  555.  int           i;
  556.  char         *pOption;
  557.  char         *cp;
  558.  char         *cpo;
  559.  int           len;
  560.  
  561.  /****************************************************************************/
  562.  /* - If user entered no arguments, go to case help.                         */
  563.  /****************************************************************************/
  564.  if( argc == 1 )
  565.    goto casehelp;
  566.  
  567.  /****************************************************************************/
  568.  /* - set any default options.                                               */
  569.  /****************************************************************************/
  570.  pConnection->DbgOrEsp = _ESP;
  571.  
  572.  pEspParms->EspFlags.IsParentEsp    = TRUE;
  573.  
  574.  /****************************************************************************/
  575.  /* - Build a string of tokens delimited by a single blank.                  */
  576.  /****************************************************************************/
  577.  ParmString[0] = '\0';
  578.  for( i=1 ; i<argc; i++)
  579.  {
  580.   strcat(ParmString,argv[i]);
  581.   strcat(ParmString," ");
  582.  }
  583.  strcat(ParmString,"\0");
  584.  
  585.  /****************************************************************************/
  586.  /* - Scan the parm block and pull off the options and program name.         */
  587.  /****************************************************************************/
  588.  pOption = strtok(ParmString," ");
  589.  do
  590.  {
  591.   switch( *pOption )
  592.   {
  593.    case '/':
  594.     switch( tolower(*(pOption + 1)) )
  595.     {
  596.  casehelp:
  597.      /************************************************************************/
  598.      /* - handle the help options.                                           */
  599.      /************************************************************************/
  600.      case 'h':
  601.      case '?':
  602.       SayMsg(HELP_INVOCATION_ESP);
  603.       break;
  604.  
  605.      case 'a':
  606.       /***********************************************************************/
  607.       /* - Parse the com port.                                               */
  608.       /***********************************************************************/
  609.       pConnection->ComPort = EspParseComPort( *(pOption+2) );
  610.       break;
  611.  
  612.      case 'r':
  613.      pConnection->ConnectType = ASYNC;
  614.      {
  615.      /************************************************************************/
  616.      /* - parse off the speed option.                                        */
  617.      /************************************************************************/
  618.       switch( *(pOption + 2) )
  619.       {
  620.        case '0':
  621.         pConnection->BitRate = 300;
  622.         break;
  623.  
  624.        case '1':
  625.         pConnection->BitRate = 1200;
  626.         break;
  627.  
  628.        case '2':
  629.         pConnection->BitRate = 2400;
  630.         break;
  631.  
  632.        case '3':
  633.         pConnection->BitRate = 4800;
  634.         break;
  635.  
  636.        case '4':
  637.         pConnection->BitRate = 9600;
  638.         break;
  639.  
  640.        case '5':
  641.         pConnection->BitRate = 19200;
  642.         break;
  643.  
  644.        case '6':
  645.         pConnection->BitRate = 38400;
  646.         break;
  647.  
  648.        default:
  649.         /*********************************************************************/
  650.         /* - assume online and already connected.                            */
  651.         /*********************************************************************/
  652.         pConnection->BitRate = 0;
  653.         break;
  654.       }
  655.      }
  656.      break;
  657.  
  658. caseo:
  659.      case 'o':
  660.       pConnection->modem = TRUE;
  661.       /***********************************************************************/
  662.       /* - Pull off the program name.                                        */
  663.       /***********************************************************************/
  664.       cpo = pOption + 2;
  665.       if( strlen(cpo) != 0 )
  666.       {
  667.        for( cp=FileSpec; (*cpo != ' ') && (*cpo != 0); )
  668.         *cp++ = toupper(*cpo++);
  669.        *cp = '\0';
  670.        pConnection->pModemFile = Talloc(strlen(FileSpec)+1);
  671.        strcpy(pConnection->pModemFile,FileSpec);
  672.       }
  673.       break;
  674.  
  675.      case '+': /* Joe's private option */
  676.       pEspParms->EspFlags.Verbose = TRUE;
  677.       break;
  678.  
  679.      case '!':
  680.       pEspParms->EspFlags.UseDebug  = TRUE;
  681.       break;
  682.  
  683.      case 'n':
  684.       /***********************************************************************/
  685.       /* - connect using netbios.                                            */
  686.       /* - get the logical adapter name.                                     */
  687.       /***********************************************************************/
  688.       pConnection->ConnectType = _NETBIOS;
  689.       len = strlen(pOption+2);
  690.       if( len != 0 )
  691.       {
  692.        if( len > ( MAX_LSN_NAME - LSN_RES_NAME ) )
  693.         len = MAX_LSN_NAME - LSN_RES_NAME;
  694.        cp = Talloc(len + 1);
  695.        strncpy( cp, pOption+2, len );
  696.        pConnection->pLsnName = cp;
  697.       }
  698.       break;
  699.  
  700.      case 't':
  701.      {
  702.       /***********************************************************************/
  703.       /* - connect using sockets.                                            */
  704.       /***********************************************************************/
  705.       pConnection->ConnectType = SOCKET;
  706.       len = strlen(pOption+2);
  707.       cp  = Talloc(len + 1);
  708.  
  709.       strncpy( cp, pOption+2, len );
  710.  
  711.       pConnection->pLsnName = cp;
  712.      }
  713.      break;
  714.  
  715.      case 'b':
  716.       /***********************************************************************/
  717.       /* - This option tells the probe that child processes are going to     */
  718.       /*   be debugged. It should only show up in the call to parse          */
  719.       /*   invocation options when the "parent" probe is spawned by the      */
  720.       /*   debugger which only happens when debugging child(multiple)        */
  721.       /*   processes on a single machine using local pipes.                  */
  722.       /***********************************************************************/
  723.       pConnection->ConnectType = LOCAL_PIPE;
  724.       break;
  725.  
  726.  
  727.      /************************************************************************/
  728.      /* - handle invalid "/" option.                                         */
  729.      /************************************************************************/
  730.      default:
  731.       printf("\n Invalid Option");
  732.        goto casehelp;
  733.  
  734.  
  735.     }
  736.     break;
  737.  
  738.    default:
  739.     printf("\n Invalid Option");
  740.     goto casehelp;
  741.   }
  742.   pOption = strtok(NULL," " );
  743.  }
  744.  while( pOption );
  745. }
  746.  
  747. /*****************************************************************************/
  748. /* EspParseComPort                                                           */
  749. /*                                                                           */
  750. /* Description:                                                              */
  751. /*                                                                           */
  752. /*  Get the com port to use for remote debugging.                            */
  753. /*                                                                           */
  754. /* Parameters:                                                               */
  755. /*                                                                           */
  756. /*  c            user specified com port 1-4.                                */
  757. /*                                                                           */
  758. /* Return:                                                                   */
  759. /*                                                                           */
  760. /*  ComPort      user specified Com Port 1-4.                                */
  761. /*                                                                           */
  762. /* Assumptions:                                                              */
  763. /*                                                                           */
  764. /*****************************************************************************/
  765. int EspParseComPort( char c )
  766. {
  767.  int ComPort;
  768.  
  769.  switch( c )
  770.  {
  771.   case '1':
  772.    ComPort = 1;
  773.    break;
  774.  
  775.   case '2':
  776.    ComPort = 2;
  777.    break;
  778.  
  779.   case '3':
  780.    ComPort = 3;
  781.    break;
  782.  
  783.   case '4':
  784.    ComPort = 4;
  785.    break;
  786.  
  787.   default:
  788.    SayMsg(ERR_COM_PORT_INVALID);
  789.    break;
  790.  }
  791.  return(ComPort);
  792. }
  793.  
  794. /*****************************************************************************/
  795. /* Handler()                                                                 */
  796. /*                                                                           */
  797. /* Description:                                                              */
  798. /*                                                                           */
  799. /*  Handler for SD386 exceptions. Currently, we're only interested in        */
  800. /*  C-Break.                                                                 */
  801. /*                                                                           */
  802. /* Parameters:                                                               */
  803. /*                                                                           */
  804. /*   x        See the OS/2 doc.                                              */
  805. /*   y                                                                       */
  806. /*   z                                                                       */
  807. /*   a                                                                       */
  808. /*                                                                           */
  809. /* Return:                                                                   */
  810. /*                                                                           */
  811. /* Assumptions:                                                              */
  812. /*                                                                           */
  813. /*****************************************************************************/
  814. ULONG _System Handler(PEXCEPTIONREPORTRECORD x,
  815.                       PEXCEPTIONREGISTRATIONRECORD y,
  816.                       PCONTEXTRECORD z,
  817.                       PVOID a)
  818. {
  819.  ULONG        rc;
  820.  
  821.  switch (x->ExceptionNum)
  822.  {
  823.   case XCPT_GUARD_PAGE_VIOLATION :
  824.   case XCPT_UNABLE_TO_GROW_STACK :
  825.    rc = XCPT_CONTINUE_SEARCH;
  826.    break;
  827.  
  828.   case XCPT_ACCESS_VIOLATION :
  829.   case XCPT_INTEGER_DIVIDE_BY_ZERO :
  830.   case XCPT_FLOAT_DIVIDE_BY_ZERO :
  831.   case XCPT_FLOAT_INVALID_OPERATION :
  832.   case XCPT_ILLEGAL_INSTRUCTION :
  833.   case XCPT_PRIVILEGED_INSTRUCTION :
  834.   case XCPT_INTEGER_OVERFLOW :
  835.   case XCPT_FLOAT_OVERFLOW :
  836.   case XCPT_FLOAT_UNDERFLOW :
  837.   case XCPT_FLOAT_DENORMAL_OPERAND :
  838.   case XCPT_FLOAT_INEXACT_RESULT :
  839.   case XCPT_FLOAT_STACK_CHECK :
  840.   case XCPT_DATATYPE_MISALIGNMENT :
  841.   case XCPT_ASYNC_PROCESS_TERMINATE:
  842.    DosUnsetExceptionHandler(y);
  843.    rc = XCPT_CONTINUE_SEARCH;
  844.    break;
  845.  
  846.   default :
  847.    rc = XCPT_CONTINUE_SEARCH;
  848.    break;
  849.  
  850.   case XCPT_SIGNAL:
  851.    switch (x->ExceptionInfo[0])
  852.    {
  853.      case XCPT_SIGNAL_KILLPROC :
  854.       {
  855.        ALLPIDS *p = NULL;
  856.  
  857.        p = GetPid( GetEspProcessID() );
  858.        /**********************************************************************/
  859.        /* - if p==NULL, then the probe is being killed before starting       */
  860.        /*   to debug any processes.                                          */
  861.        /**********************************************************************/
  862.        if( p == NULL)
  863.         goto casexcpt_signal_intr;
  864.  
  865.        if( p->PidFlags.CtrlBreak == TRUE )
  866.        {
  867.         /*********************************************************************/
  868.         /* - If we fall into this code, then the user is trying to do        */
  869.         /*   a Ctrl-Break:                                                   */
  870.         /*                                                                   */
  871.         /*    - Thread 1 is waiting on a DosDebug command.                   */
  872.         /*    - The signal was sent by the esp queue in response to          */
  873.         /*      a Ctrl-Break message.                                        */
  874.         /*********************************************************************/
  875.         p->PidFlags.CtrlBreak = FALSE;
  876.         rc = XCPT_CONTINUE_EXECUTION;
  877.        }
  878.        else
  879.        {
  880.         /*********************************************************************/
  881.         /* - If we get here, then we're being killed by an external process  */
  882.         /*   such as PSPM2. We need to be a good citizen and die.            */
  883.         /*********************************************************************/
  884.         rc = XCPT_CONTINUE_SEARCH;
  885.        }
  886.  
  887.       }
  888.       break;
  889.  
  890. casexcpt_signal_intr:
  891.      case XCPT_SIGNAL_INTR :
  892.      case XCPT_SIGNAL_BREAK :
  893.      {
  894.       /***********************************************************************/
  895.       /* - Come here when the user enters a Ctrl-Break in the probe          */
  896.       /*   session.                                                          */
  897.       /***********************************************************************/
  898.       CloseConnectSema4();
  899.       ConnectClose( DEFAULT_HANDLE );
  900.       DosUnsetExceptionHandler(y);
  901.       rc = XCPT_CONTINUE_SEARCH;
  902.      }
  903.      break;
  904.    }
  905.    break;
  906.  }
  907.  return(rc);
  908. }
  909.  
  910.  
  911. /*****************************************************************************/
  912. /* ParseEspChildOptions()                                                    */
  913. /*                                                                           */
  914. /* Description:                                                              */
  915. /*                                                                           */
  916. /*   - Parse the invocation options coming to a child probe.                 */
  917. /*                                                                           */
  918. /* Parameters:                                                               */
  919. /*                                                                           */
  920. /*   argc        Number of input parameters.                                 */
  921. /*   argv        -> -> to argument strings.                                  */
  922. /*   pEspParms   -> to the structure that will define the invocation parms.  */
  923. /*   pConnection -> to the structure that will define the connection parms.  */
  924. /*                                                                           */
  925. /* Return:                                                                   */
  926. /*                                                                           */
  927. /*   void                                                                    */
  928. /*                                                                           */
  929. /* Assumptions:                                                              */
  930. /*                                                                           */
  931. /*****************************************************************************/
  932. void ParseEspChildOptions( int          argc,
  933.                            char       **argv,
  934.                            ESP_PARMS    *pEspParms,
  935.                            CONNECTION  *pConnection)
  936. {
  937.  char          ParmString[512];
  938.  int           i;
  939.  char         *pOption;
  940.  char         *cp;
  941.  int           len;
  942.  
  943.  
  944.  /****************************************************************************/
  945.  /* - set any default options.                                               */
  946.  /****************************************************************************/
  947.  pConnection->DbgOrEsp = _ESP;
  948.  
  949.  pEspParms->EspFlags.IsParentEsp    = FALSE;
  950.  
  951.  /****************************************************************************/
  952.  /* - Build a string of tokens delimited by a single blank.                  */
  953.  /****************************************************************************/
  954.  ParmString[0] = '\0';
  955.  for( i=1 ; i<argc; i++)
  956.  {
  957.   strcat(ParmString,argv[i]);
  958.   strcat(ParmString," ");
  959.  }
  960.  strcat(ParmString,"\0");
  961.  
  962.  /****************************************************************************/
  963.  /* - Scan the parm block and pull off the options and program name.         */
  964.  /****************************************************************************/
  965.  pOption = strtok(ParmString," ");
  966.  do
  967.  {
  968.   printf("\n%s", pOption);fflush(0);
  969.   switch( *pOption )
  970.   {
  971.    case '/':
  972.     switch( tolower(*(pOption + 1)) )
  973.     {
  974.      case 'a':
  975.       /***********************************************************************/
  976.       /* - Parse the com port.                                               */
  977.       /***********************************************************************/
  978.       pConnection->ComPort = EspParseComPort( *(pOption+2) );
  979.       break;
  980.  
  981.      case 'r':
  982.       pConnection->ConnectType    = ASYNC;
  983.       break;
  984.  
  985.      case '+': /* Joe's private option */
  986.       pEspParms->EspFlags.Verbose = TRUE;
  987.       break;
  988.  
  989.      case 'n':
  990.       /***********************************************************************/
  991.       /* - connect using netbios.                                            */
  992.       /* - get the logical adapter name.                                     */
  993.       /***********************************************************************/
  994.       pConnection->ConnectType    = _NETBIOS;
  995.       len = strlen(pOption+2);
  996.       if( len != 0 )
  997.       {
  998.        if( len > ( MAX_LSN_NAME - LSN_RES_NAME ) )
  999.         len = MAX_LSN_NAME - LSN_RES_NAME;
  1000.        cp = Talloc(len + 1);
  1001.        strncpy( cp, pOption+2, len );
  1002.        pConnection->pLsnName = cp;
  1003.       }
  1004.       break;                                                            /*919*/
  1005.  
  1006.      case 't':
  1007.      {
  1008.       /***********************************************************************/
  1009.       /* - connect using sockets.                                            */
  1010.       /***********************************************************************/
  1011.       pConnection->ConnectType = SOCKET;
  1012.       len = strlen(pOption+2);
  1013.       cp  = Talloc(len + 1);
  1014.  
  1015.       strncpy( cp, pOption+2, len );
  1016.  
  1017.       pConnection->pLsnName = cp;
  1018.      }
  1019.      break;
  1020.  
  1021.      case 'c':
  1022.       /***********************************************************************/
  1023.       /* - handle the /child= option which MUST be argv[1];                  */
  1024.       /***********************************************************************/
  1025.       break;
  1026.  
  1027.  
  1028.      case 'b':
  1029.       /***********************************************************************/
  1030.       /* - This option tells the probe that child processes are going to     */
  1031.       /*   be debugged. It should only show up when esp is spawned           */
  1032.       /*   internally when specifying the /b option on the sd386             */
  1033.       /*   invocation line. Note that esp does not have an explicit          */
  1034.       /*   /b invocation option.                                             */
  1035.       /***********************************************************************/
  1036.       pConnection->ConnectType = LOCAL_PIPE;
  1037.       break;
  1038.  
  1039.      case 's':
  1040.       /***********************************************************************/
  1041.       /* - Set the shared heap memory handle.                                */
  1042.       /***********************************************************************/
  1043.       if( strstr( pOption+1, "shr" ) )
  1044.       {
  1045.        ULONG *pshrmem;
  1046.  
  1047.        pshrmem = (ULONG*)atol( strchr( pOption+1, '=' ) + 1 );
  1048.        SetShrMem( pshrmem );
  1049.       }
  1050.       break;
  1051.  
  1052.      case 'h':
  1053.       /***********************************************************************/
  1054.       /* - Set the start address of the shared heap.                         */
  1055.       /***********************************************************************/
  1056.       if( strstr( pOption+1, "heap" ) )
  1057.       {
  1058.        ULONG *heap;
  1059.  
  1060.        heap = (ULONG*)atol( strchr( pOption+1, '=' ) + 1 );
  1061.        SetShrHeap( heap );
  1062.       }
  1063.       else if( strstr( pOption+1, "handle" ) )
  1064.       {
  1065.        pEspParms->handle = (LHANDLE)atol( strchr( pOption+1, '=' ) + 1 );
  1066.       }
  1067.       break;
  1068.  
  1069.      case 'd':
  1070.      {
  1071.       int descriptor;
  1072.       /***********************************************************************/
  1073.       /* - Get the base socket descriptor if using sockets.                  */
  1074.       /***********************************************************************/
  1075.       descriptor = (int)atol( strchr( pOption+1, '=' ) + 1 );
  1076.       SockSetDescriptor(descriptor);
  1077.      }
  1078.      break;
  1079.  
  1080.      case 'q':
  1081.       /***********************************************************************/
  1082.       /* - Set the queue name for sending messages.                          */
  1083.       /***********************************************************************/
  1084.       if( strstr( pOption+1, "qname" ) )
  1085.       {
  1086.        char *pQueName;
  1087.  
  1088.        pQueName = strchr( pOption+1, '=' ) + 1 ;
  1089.        SetEspQueName( pQueName );
  1090.       }
  1091.       break;
  1092.  
  1093.      /************************************************************************/
  1094.      /* - handle invalid "/" option.                                         */
  1095.      /************************************************************************/
  1096.      default:
  1097.       break;
  1098.  
  1099.     }
  1100.     break;
  1101.  
  1102.    default:
  1103.     break;
  1104.   }
  1105.   pOption = strtok(NULL," " );
  1106.  }
  1107.  while( pOption );
  1108. }
  1109.  
  1110. /*****************************************************************************/
  1111. /* - Display a fatal error message in a child probe and then exit.           */
  1112. /*****************************************************************************/
  1113. void MyExit( void )
  1114. {
  1115.  ESP_QUE_ELEMENT  Qelement;
  1116.  USHORT           PidOfThisEsp;
  1117.  TIB             *pTib;
  1118.  PIB             *pPib;
  1119.  
  1120.  /****************************************************************************/
  1121.  /* - If we get an error in a child probe, then we need to bring that        */
  1122.  /*   probe session to the foreground and display the message.               */
  1123.  /****************************************************************************/
  1124.  if( IsParent() == FALSE )
  1125.  {
  1126.   DosGetInfoBlocks(&pTib,&pPib);
  1127.  
  1128.   PidOfThisEsp = (USHORT)pPib->pib_ulpid;
  1129.  
  1130.   Qelement.ChildPid = PidOfThisEsp;
  1131.   if( UseExecPgm() == FALSE )
  1132.    SendMsgToEspQue( ESP_QMSG_SELECT_ESP, &Qelement, sizeof(Qelement) );
  1133.   DosSleep(15000);
  1134.  }
  1135.  exit(0);
  1136. }
  1137.