home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / online / source / c / compilers / Tickle-4.0.sit.hqx / Tickle-4.0 / src / tcl-ctb.c < prev    next >
Text File  |  1993-11-20  |  23KB  |  1,102 lines

  1.  
  2. /*
  3. ** This source code was written by Tim Endres
  4. ** Email: time@ice.com.
  5. ** USMail: 8840 Main Street, Whitmore Lake, MI  48189
  6. **
  7. ** Some portions of this application utilize sources
  8. ** that are copyrighted by ICE Engineering, Inc., and
  9. ** ICE Engineering retains all rights to those sources.
  10. **
  11. ** Neither ICE Engineering, Inc., nor Tim Endres, 
  12. ** warrants this source code for any reason, and neither
  13. ** party assumes any responsbility for the use of these
  14. ** sources, libraries, or applications. The user of these
  15. ** sources and binaries assumes all responsbilities for
  16. ** any resulting consequences.
  17. */
  18.  
  19. #pragma segment TCLCTB
  20.  
  21. #include "tickle.h"
  22. #include "tcl.h"
  23.  
  24. #include <Connections.h>
  25. #include <CTBUtilities.h>
  26. #include <CommResources.h>
  27. #include <FileTransfers.h>
  28. #include <Terminals.h>
  29.  
  30. extern int errno;
  31. extern int macintoshErr;
  32.  
  33. typedef enum
  34.     {
  35.     CONNECTION_CLOSED_STATE,
  36.     CONNECTION_LISTEN_STATE,
  37.     CONNECTION_OPEN_STATE,
  38.     CONNECTION_UNUSED_STATE
  39.     } CONN_STATE;
  40.  
  41. typedef struct
  42.     {
  43.     CONN_STATE    state;
  44.     ConnHandle    connH;
  45.     short        connID;
  46.     char        name[32];
  47.     } CTB_NAMED_CONN;
  48.  
  49.  
  50. #define MAX_CTB        16
  51.  
  52. int                _ctb_is_available_ = 0;
  53. static int                _max_ctb_ = 0;
  54. static CTB_NAMED_CONN    *_ctb_ = NULL;
  55.  
  56.  
  57. init_tcl_ctb()
  58.     {
  59.     int        i;
  60.     
  61.     _ctb_is_available_ = 0;
  62.     if ( CheckForCTB() )
  63.         {
  64.         if ( InitCTBCommunications() )
  65.             {
  66.             _ctb_is_available_ = 1;
  67.  
  68.             _ctb_ = (CTB_NAMED_CONN *) malloc(sizeof(CTB_NAMED_CONN) * MAX_CTB);
  69.             if (_ctb_ == NULL)
  70.                 _max_ctb_ = 0;
  71.             else
  72.                 _max_ctb_ = MAX_CTB;
  73.             
  74.             for ( i = 0 ; i < _max_ctb_ ; ++i )
  75.                 {
  76.                 _ctb_[i].state = CONNECTION_UNUSED_STATE;
  77.                 _ctb_[i].connH = (ConnHandle) 0;
  78.                 _ctb_[i].connID = -1;
  79.                 _ctb_[i].name[0] = '\0';
  80.                 }
  81.             }
  82.         }
  83.     }
  84.  
  85. close_tcl_ctb()
  86.     {
  87.     int        i, myerr;
  88.     
  89.     if (! _ctb_is_available_)
  90.         return;
  91.         
  92.     for ( i = 0 ; i < _max_ctb_ ; ++i )
  93.         {
  94.         if (_ctb_[i].connH != (ConnHandle)0)
  95.             {
  96.             myerr = CMClose(_ctb_[i].connH, (Boolean)0, NULL,
  97.                                 (long)0, (Boolean)1);
  98.             CMDispose(_ctb_[i].connH);
  99.             }
  100.         }
  101.     }
  102.  
  103.  
  104. int
  105. Cmd_CTBCreate(clientData, interp, argc, argv)
  106.     char        *clientData;
  107.     Tcl_Interp    *interp;
  108.     int            argc;
  109.     char        **argv;
  110.     {
  111.     ConnHandle        connH;
  112.     short            connID;
  113.     Str255            tool_name;
  114.     CMBufferSizes    sizes;
  115.     int                index, myerr;
  116. #pragma unused (clientData)
  117.  
  118.     if ( ! _ctb_is_available_ )
  119.         {
  120.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  121.         return TCL_ERROR;
  122.         }
  123.     
  124.     if (argc < 3 || argc > 4)
  125.         {
  126.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  127.                             " ctbname toolname ?configstr?\"", NULL);
  128.         return TCL_ERROR;
  129.         }
  130.  
  131.     for (index = 0 ; index < _max_ctb_ ; ++index)
  132.         {
  133.         if (_ctb_[index].connH == NULL)
  134.             break;
  135.         
  136.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  137.             {
  138.             Tcl_AppendResult(interp, "\"", argv[0], "\" duplicate connection name '",
  139.                                     argv[1], "'", (char *) NULL);
  140.             return TCL_ERROR;
  141.             }
  142.         }
  143.  
  144.     if (index >= _max_ctb_)
  145.         {
  146.         Tcl_AppendResult(interp, "\"", argv[0], "\" max connection's open", NULL);
  147.         return TCL_ERROR;
  148.         }
  149.  
  150.     connH = NULL;
  151.     connID = -1;
  152.     
  153.     if ( strcmp(argv[2], "any") == 0 )
  154.         {
  155.         myerr = CRMGetIndToolName((OSType)classCM, 1, tool_name);
  156.         if (myerr != noErr)
  157.             {
  158.             strcpy(tool_name, "Serial Tool");
  159.             c2pstr(tool_name);    
  160.             }
  161.         }
  162.     else
  163.         {
  164.         strcpy(tool_name, argv[2]);
  165.         c2pstr(tool_name);    
  166.         }
  167.     
  168.     connID = CMGetProcID(tool_name);
  169.     if (connID == -1)
  170.         {
  171.         Tcl_AppendResult(interp, "could not open tool \"", argv[2], "\"", NULL);
  172.         return TCL_ERROR;
  173.         }
  174.  
  175.     sizes[cmDataIn]   = 1024;
  176.     sizes[cmDataOut]  = 1024;
  177.     sizes[cmCntlIn]   = 0;
  178.     sizes[cmCntlOut]  = 0;
  179.     sizes[cmAttnIn]   = 0;
  180.     sizes[cmAttnOut]  = 0;
  181.     connH = CMNew( (short)connID,
  182.                   (CMRecFlags) ( cmData | cmNoMenus | cmQuiet ),
  183.                    sizes, (long)0, (long)0);
  184.  
  185.     if (connH == NULL)
  186.         {
  187.         Tcl_AppendResult(interp, "could not open CTB connection", NULL);
  188.         return TCL_ERROR;
  189.         }
  190.  
  191.     if (argc == 4)
  192.         {
  193.         myerr = CMSetConfig(connH, (Ptr)argv[3]);
  194.         if (myerr != noErr)
  195.             Tcl_AppendResult(interp, "warning - config string error", NULL);
  196.         }
  197.     
  198.     strcpy(_ctb_[index].name, argv[1]);
  199.     _ctb_[index].connH = connH;
  200.     _ctb_[index].connID = connID;
  201.     _ctb_[index].state = CONNECTION_CLOSED_STATE;
  202.     
  203.     return TCL_OK;
  204.     }
  205.  
  206. int
  207. Cmd_CTBOpen(clientData, interp, argc, argv)
  208.     char        *clientData;
  209.     Tcl_Interp    *interp;
  210.     int            argc;
  211.     char        **argv;
  212.     {
  213.     int            index, myerr;
  214. #pragma unused (clientData)
  215.  
  216.     if ( ! _ctb_is_available_ )
  217.         {
  218.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  219.         return TCL_ERROR;
  220.         }
  221.     
  222.     if (argc != 2)
  223.         {
  224.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  225.                             " ctbname\"", NULL);
  226.         return TCL_ERROR;
  227.         }
  228.  
  229.     for (index = 0 ; index < _max_ctb_ ; ++index)
  230.         {
  231.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  232.             break;
  233.         }
  234.  
  235.     if (index >= _max_ctb_)
  236.         {
  237.         Tcl_AppendResult(interp, "connection \"",
  238.                             argv[1], "\" not found", (char *) NULL);
  239.         return TCL_ERROR;
  240.         }
  241.  
  242.     myerr = CMOpen(_ctb_[index].connH, (Boolean)0, (ProcPtr)0, (long)0 );
  243.     if (myerr != noErr)
  244.         {
  245.         Tcl_AppendResult(interp, "error opening connection \"", argv[1],
  246.                             "\", ", Tcl_MacGetError(interp, myerr), NULL);
  247.         return TCL_ERROR;
  248.         }
  249.         
  250.     _ctb_[index].state = CONNECTION_OPEN_STATE;
  251.  
  252.     return TCL_OK;
  253.     }
  254.  
  255. int
  256. Cmd_CTBListen(clientData, interp, argc, argv)
  257.     char        *clientData;
  258.     Tcl_Interp    *interp;
  259.     int            argc;
  260.     char        **argv;
  261.     {
  262.     int            index, myerr;
  263. #pragma unused (clientData)
  264.  
  265.     if ( ! _ctb_is_available_ )
  266.         {
  267.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  268.         return TCL_ERROR;
  269.         }
  270.     
  271.     if (argc != 2)
  272.         {
  273.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  274.                             " ctbname\"", NULL);
  275.         return TCL_ERROR;
  276.         }
  277.  
  278.     for (index = 0 ; index < _max_ctb_ ; ++index)
  279.         {
  280.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  281.             break;
  282.         }
  283.  
  284.     if (index >= _max_ctb_)
  285.         {
  286.         Tcl_AppendResult(interp, "connection \"",
  287.                             argv[1], "\" not found", (char *) NULL);
  288.         return TCL_ERROR;
  289.         }
  290.  
  291.     myerr = CMListen(_ctb_[index].connH, (Boolean)1, NULL, -1);
  292.     if (myerr != noErr)
  293.         {
  294.         Tcl_AppendResult(interp, "error listening on connection \"", argv[1],
  295.                             "\", ", Tcl_MacGetError(interp, myerr), NULL);
  296.         return TCL_ERROR;
  297.         }
  298.  
  299.     _ctb_[index].state = CONNECTION_LISTEN_STATE;
  300.         
  301.     return TCL_OK;
  302.     }
  303.  
  304. int
  305. Cmd_CTBAccept(clientData, interp, argc, argv)
  306.     char        *clientData;
  307.     Tcl_Interp    *interp;
  308.     int            argc;
  309.     char        **argv;
  310.     {
  311.     int                index, myerr;
  312.     CMStatFlags        flags;
  313.     CMBufferSizes    sizes;
  314. #pragma unused (clientData)
  315.  
  316.     if ( ! _ctb_is_available_ )
  317.         {
  318.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  319.         return TCL_ERROR;
  320.         }
  321.     
  322.     if (argc != 2)
  323.         {
  324.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  325.                             " ctbname\"", NULL);
  326.         return TCL_ERROR;
  327.         }
  328.  
  329.     for (index = 0 ; index < _max_ctb_ ; ++index)
  330.         {
  331.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  332.             break;
  333.         }
  334.  
  335.     if (index >= _max_ctb_)
  336.         {
  337.         Tcl_AppendResult(interp, "connection \"",
  338.                             argv[1], "\" not found", (char *) NULL);
  339.         return TCL_ERROR;
  340.         }
  341.  
  342.     if (_ctb_[index].state != CONNECTION_LISTEN_STATE)
  343.         {
  344.         Tcl_AppendResult(interp, "connection \"", argv[1],
  345.                             "\" is not listening", NULL);
  346.         return TCL_ERROR;
  347.         }
  348.     
  349.     myerr = CMStatus(_ctb_[index].connH, sizes, &flags);
  350.     if (myerr != noErr)
  351.         {
  352.         Tcl_AppendResult(interp, "error getting connection \"", argv[1],
  353.                             "\" status, ", Tcl_MacGetError(interp, myerr), NULL);
  354.         return TCL_ERROR;
  355.         }
  356.  
  357.     if ( (flags & cmStatusIncomingCallPresent) == 0 )
  358.         {
  359.         Tcl_AppendResult(interp, "connection \"", argv[1],
  360.                             "\" does not have incoming call", NULL);
  361.         return TCL_ERROR;
  362.         }
  363.  
  364.     myerr = CMAccept(_ctb_[index].connH, (Boolean)1);
  365.     if (myerr != noErr)
  366.         {
  367.         Tcl_AppendResult(interp, "error accepting on connection \"", argv[1],
  368.                             "\", ", Tcl_MacGetError(interp, myerr), NULL);
  369.         return TCL_ERROR;
  370.         }
  371.  
  372.     _ctb_[index].state = CONNECTION_OPEN_STATE;
  373.         
  374.     return TCL_OK;
  375.     }
  376.  
  377. int
  378. Cmd_CTBToolname(clientData, interp, argc, argv)
  379.     char        *clientData;
  380.     Tcl_Interp    *interp;
  381.     int            argc;
  382.     char        **argv;
  383.     {
  384.     int            index, myerr;
  385.     Str255        toolname;
  386.     
  387. #    pragma unused (clientData)
  388.  
  389.     if ( ! _ctb_is_available_ )
  390.         {
  391.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  392.         return TCL_ERROR;
  393.         }
  394.     
  395.     if (argc < 2 || argc > 3)
  396.         {
  397.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  398.                             " ctbname ?varname?\"", NULL);
  399.         return TCL_ERROR;
  400.         }
  401.  
  402.     for (index = 0 ; index < _max_ctb_ ; ++index)
  403.         {
  404.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  405.             break;
  406.         }
  407.  
  408.     if (index >= _max_ctb_)
  409.         {
  410.         Tcl_AppendResult(interp, "connection \"",
  411.                             argv[1], "\" not found", (char *) NULL);
  412.         return TCL_ERROR;
  413.         }
  414.  
  415.     CMGetToolName(_ctb_[index].connID, toolname);
  416.     p2cstr(toolname);
  417.     
  418.     if (argc == 3)
  419.         {
  420.         if ( Tcl_SetVar(interp, argv[2], toolname, TCL_LEAVE_ERR_MSG) == NULL )
  421.             return TCL_ERROR;
  422.         }
  423.     else
  424.         {
  425.         Tcl_AppendResult(interp, toolname, NULL);
  426.         }
  427.     
  428.     return TCL_OK;
  429.     }
  430.  
  431. int
  432. Cmd_CTBGetConfig(clientData, interp, argc, argv)
  433.     char        *clientData;
  434.     Tcl_Interp    *interp;
  435.     int            argc;
  436.     char        **argv;
  437.     {
  438.     ConnHandle        connH;
  439.     short            connID;
  440.     Ptr                configstr;
  441.     int                index, myerr;
  442. #pragma unused (clientData)
  443.  
  444.     if ( ! _ctb_is_available_ )
  445.         {
  446.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  447.         return TCL_ERROR;
  448.         }
  449.     
  450.     if (argc < 2 || argc > 3)
  451.         {
  452.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  453.                             " ctbname ?varname?\"", NULL);
  454.         return TCL_ERROR;
  455.         }
  456.  
  457.     for (index = 0 ; index < _max_ctb_ ; ++index)
  458.         {
  459.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  460.             break;
  461.         }
  462.  
  463.     if (index >= _max_ctb_)
  464.         {
  465.         Tcl_AppendResult(interp, "connection \"",
  466.                             argv[1], "\" not found", (char *) NULL);
  467.         return TCL_ERROR;
  468.         }
  469.  
  470.     configstr = CMGetConfig(_ctb_[index].connH);
  471.     if (configstr == NULL)
  472.         {
  473.         Tcl_AppendResult(interp, "error getting configuration string", NULL);
  474.         return TCL_ERROR;
  475.         }
  476.     
  477.     if (argc == 3)
  478.         {
  479.         if ( Tcl_SetVar(interp, argv[2], configstr, TCL_LEAVE_ERR_MSG) == NULL )
  480.             {
  481.             DisposPtr(configstr);
  482.             return TCL_ERROR;
  483.             }
  484.         }
  485.     else
  486.         {
  487.         Tcl_AppendResult(interp, configstr, NULL);
  488.         }
  489.     
  490.     DisposPtr(configstr);
  491.     
  492.     return TCL_OK;
  493.     }
  494.  
  495. int
  496. Cmd_CTBGetStatus(clientData, interp, argc, argv)
  497.     char        *clientData;
  498.     Tcl_Interp    *interp;
  499.     int            argc;
  500.     char        **argv;
  501.     {
  502.     char            str[64], *statestr;
  503.     int                index, myerr;
  504.     CMStatFlags        flags;
  505.     CMBufferSizes    sizes;
  506. #pragma unused (clientData)
  507.  
  508.     if ( ! _ctb_is_available_ )
  509.         {
  510.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  511.         return TCL_ERROR;
  512.         }
  513.     
  514.     if (argc != 2)
  515.         {
  516.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  517.                             " ctbname\"", NULL);
  518.         return TCL_ERROR;
  519.         }
  520.  
  521.     for (index = 0 ; index < _max_ctb_ ; ++index)
  522.         {
  523.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  524.             break;
  525.         }
  526.  
  527.     if (index >= _max_ctb_)
  528.         {
  529.         Tcl_AppendResult(interp, "connection \"",
  530.                             argv[1], "\" not found", (char *) NULL);
  531.         return TCL_ERROR;
  532.         }
  533.  
  534.     myerr = CMStatus(_ctb_[index].connH, sizes, &flags);
  535.     if (myerr != noErr)
  536.         {
  537.         Tcl_AppendResult(interp, "error getting connection status, ", 
  538.                             Tcl_MacGetError(interp, myerr), NULL);
  539.         return TCL_ERROR;
  540.         }
  541.  
  542.     switch (_ctb_[index].state)
  543.         {
  544.         case CONNECTION_UNUSED_STATE:    statestr = "UNUSED"; break;
  545.         case CONNECTION_CLOSED_STATE:    statestr = "CLOSED"; break;
  546.         case CONNECTION_LISTEN_STATE:    statestr = "LISTEN"; break;
  547.         case CONNECTION_OPEN_STATE:        statestr = "OPEN"; break;
  548.         default:
  549.             sprintf(str, "UNKNOWN-%d", _ctb_[index].state);
  550.             statestr = str;
  551.             break;
  552.         }
  553.     Tcl_AppendElement(interp, statestr);
  554.  
  555.     sprintf(str, "0x%08lX", flags);
  556.     Tcl_AppendElement(interp, str);
  557.     
  558.     sprintf(str, "%d", sizes[cmDataIn]);
  559.     Tcl_AppendElement(interp, str);
  560.     
  561.     sprintf(str, "%d", sizes[cmDataOut]);
  562.     Tcl_AppendElement(interp, str);
  563.     
  564.     return TCL_OK;
  565.     }
  566.  
  567. int
  568. Cmd_CTBSetConfig(clientData, interp, argc, argv)
  569.     char        *clientData;
  570.     Tcl_Interp    *interp;
  571.     int            argc;
  572.     char        **argv;
  573.     {
  574.     char        buf[64];
  575.     int            index, myerr;
  576.     
  577. #    pragma unused (clientData)
  578.  
  579.     if ( ! _ctb_is_available_ )
  580.         {
  581.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  582.         return TCL_ERROR;
  583.         }
  584.     
  585.     if (argc != 3)
  586.         {
  587.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  588.                             " ctbname configstr\"", NULL);
  589.         return TCL_ERROR;
  590.         }
  591.  
  592.     for (index = 0 ; index < _max_ctb_ ; ++index)
  593.         {
  594.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  595.             break;
  596.         }
  597.  
  598.     if (index >= _max_ctb_)
  599.         {
  600.         Tcl_AppendResult(interp, "connection \"",
  601.                             argv[1], "\" not found", (char *) NULL);
  602.         return TCL_ERROR;
  603.         }
  604.  
  605.     myerr = CMSetConfig(_ctb_[index].connH, (Ptr)argv[2]);
  606.     if (myerr != noErr)
  607.         {
  608.         sprintf(buf, "%d", myerr);
  609.         Tcl_AppendResult(interp, "config string error at character # ",
  610.                             buf, NULL);
  611.         return TCL_ERROR;
  612.         }
  613.         
  614.     return TCL_OK;
  615.     }
  616.  
  617. int
  618. Cmd_CTBConfigDialog(clientData, interp, argc, argv)
  619.     char        *clientData;
  620.     Tcl_Interp    *interp;
  621.     int            argc;
  622.     char        **argv;
  623.     {
  624. #ifdef TCLAPPL
  625.     short        connID;
  626.     int            index, myerr;
  627.     Point        mypoint;
  628.     ConnHandle    connH;
  629.     
  630. #    pragma unused (clientData)
  631.  
  632.     if ( ! _ctb_is_available_ )
  633.         {
  634.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  635.         return TCL_ERROR;
  636.         }
  637.     
  638.     if (argc != 2)
  639.         {
  640.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  641.                             " ctbname\"", NULL);
  642.         return TCL_ERROR;
  643.         }
  644.  
  645.     for (index = 0 ; index < _max_ctb_ ; ++index)
  646.         {
  647.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  648.             break;
  649.         }
  650.  
  651.     if (index >= _max_ctb_)
  652.         {
  653.         Tcl_AppendResult(interp, "connection \"",
  654.                             argv[1], "\" not found", (char *) NULL);
  655.         return TCL_ERROR;
  656.         }
  657.  
  658.     connH = _ctb_[index].connH;
  659.     mypoint.h = ((scrnrect.right - scrnrect.left) - 480) >> 1;
  660.     mypoint.v = 40;
  661.     
  662.     myerr = CMChoose(&connH, mypoint, NULL);
  663.     
  664.     if (myerr == chooseDisaster)
  665.         {
  666.         Tcl_AppendResult( interp, "error in the Communications ToolBox, ",
  667.                             Tcl_MacGetError(interp, myerr), NULL );
  668.         }
  669.     else if (myerr == chooseOKMajor || myerr == chooseOKMinor)
  670.         {
  671.         if (myerr == chooseOKMajor)
  672.             _ctb_[index].connID = (**connH).procID;
  673.  
  674.         _ctb_[index].connH = connH;
  675.         }
  676.     
  677.     return TCL_OK;
  678. #else
  679.     Tcl_AppendResult(interp, "\"", argv[0],
  680.                         "\" is not supported in engine", NULL);
  681.     return TCL_ERROR;
  682. #endif
  683.     }
  684.  
  685. int
  686. Cmd_CTBWrite(clientData, interp, argc, argv)
  687.     char        *clientData;
  688.     Tcl_Interp    *interp;
  689.     int            argc;
  690.     char        **argv;
  691.     {
  692.     int        index, myerr, bytes, tries, length;
  693.     char    *ptr;
  694.     
  695. #    pragma unused (clientData)
  696.  
  697.     if ( ! _ctb_is_available_ )
  698.         {
  699.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  700.         return TCL_ERROR;
  701.         }
  702.     
  703.     if (argc != 3)
  704.         {
  705.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  706.                             " ctbname data\"", NULL);
  707.         return TCL_ERROR;
  708.         }
  709.  
  710.     for (index = 0 ; index < _max_ctb_ ; ++index)
  711.         {
  712.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  713.             break;
  714.         }
  715.  
  716.     if (index >= _max_ctb_)
  717.         {
  718.         Tcl_AppendResult(interp, "connection \"",
  719.                             argv[1], "\" not found", (char *) NULL);
  720.         return TCL_ERROR;
  721.         }
  722.  
  723.     if (_ctb_[index].state != CONNECTION_OPEN_STATE)
  724.         {
  725.         Tcl_AppendResult(interp, "connection \"", argv[1],
  726.                             "\" is not open", NULL);
  727.         return TCL_ERROR;
  728.         }
  729.  
  730.     ptr = argv[2];
  731.     length = strlen(argv[2]);
  732.     for ( tries = 0 ; tries < 5 && length > 0 ; ++tries )
  733.         {
  734.         bytes = length;
  735.         myerr = CMWrite(_ctb_[index].connH, ptr, &bytes,
  736.                         cmData, (Boolean)0, NULL, (long)0, (Boolean)0);
  737.         
  738.         if (myerr != noErr)
  739.             {
  740.             Tcl_AppendResult(interp, "error storing data, ", 
  741.                                 Tcl_MacGetError(interp, myerr), NULL);
  742.             return TCL_ERROR;
  743.             }
  744.         
  745.         ptr += bytes;
  746.         length -= bytes;
  747.         }
  748.     
  749.     if (length > 0)
  750.         {
  751.         Tcl_AppendResult(interp, "error could not write all of data", NULL);
  752.         return TCL_ERROR;
  753.         }
  754.         
  755.     return TCL_OK;
  756.     }
  757.  
  758. int
  759. Cmd_CTBRead(clientData, interp, argc, argv)
  760.     char        *clientData;
  761.     Tcl_Interp    *interp;
  762.     int            argc;
  763.     char        **argv;
  764.     {
  765.     int            index, result, myerr;
  766.     long        flags, bytes, bufsize;
  767.     CMFlags        cmflags;
  768.     CMBufferSizes    sizes;
  769.     char        buffer[1024];
  770.     
  771. #    pragma unused (clientData)
  772.  
  773.     if ( ! _ctb_is_available_ )
  774.         {
  775.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  776.         return TCL_ERROR;
  777.         }
  778.     
  779.     if (argc < 2 || argc > 3)
  780.         {
  781.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  782.                             " ctbname ?varname?\"", NULL);
  783.         return TCL_ERROR;
  784.         }
  785.  
  786.     for (index = 0 ; index < _max_ctb_ ; ++index)
  787.         {
  788.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  789.             break;
  790.         }
  791.  
  792.     if (index >= _max_ctb_)
  793.         {
  794.         Tcl_AppendResult(interp, "connection \"",
  795.                             argv[1], "\" not found", (char *) NULL);
  796.         return TCL_ERROR;
  797.         }
  798.  
  799.     if (_ctb_[index].state != CONNECTION_OPEN_STATE)
  800.         {
  801.         Tcl_AppendResult(interp, "connection \"", argv[1],
  802.                             "\" is not open", NULL);
  803.         return TCL_ERROR;
  804.         }
  805.  
  806.     myerr = CMStatus(_ctb_[index].connH, sizes, &flags);
  807.     if (myerr != noErr)
  808.         {
  809.         Tcl_AppendResult(interp, "error getting connection status, ", 
  810.                             Tcl_MacGetError(interp, myerr), NULL);
  811.         return TCL_ERROR;
  812.         }
  813.  
  814.     if ((flags & cmStatusOpen) == 0)
  815.         {
  816.         Tcl_AppendResult(interp, "connection is closed", NULL);
  817.         return TCL_ERROR;
  818.         }
  819.     
  820.     buffer[0] = '\0';
  821.     bufsize = sizeof(buffer);
  822.     Tcl_ResetResult(interp);
  823.     
  824.     if ( (flags & cmStatusDataAvail) != 0 )
  825.         {
  826.         bytes = ( sizes[cmDataIn] < bufsize ) ?
  827.                             sizes[cmDataIn] : bufsize - 1;
  828.         myerr = CMRead(_ctb_[index].connH, buffer, &bytes,
  829.                             cmData, (Boolean)0, NULL, (long)0, &cmflags);
  830.         if (myerr != noErr)
  831.             {
  832.             Tcl_AppendResult(interp, "error reading data, ",
  833.                                 Tcl_MacGetError(interp, myerr), NULL);
  834.             return TCL_ERROR;
  835.             }
  836.         
  837.         buffer[bytes] = '\0';
  838.         if (argc == 3)
  839.             {
  840.             if ( Tcl_SetVar(interp, argv[2], buffer, TCL_LEAVE_ERR_MSG) == NULL )
  841.                 return TCL_ERROR;
  842.             }
  843.         else
  844.             {
  845.             Tcl_AppendResult(interp, buffer, (char *) NULL);
  846.             }
  847.         }
  848.     
  849.     return TCL_OK;
  850.     }
  851.  
  852. int
  853. Cmd_CTBBreak(clientData, interp, argc, argv)
  854.     char        *clientData;
  855.     Tcl_Interp    *interp;
  856.     int            argc;
  857.     char        **argv;
  858.     {
  859.     int        index, myerr;
  860.     long    duration = 30;
  861.     char    *ptr;
  862.     
  863. #    pragma unused (clientData)
  864.  
  865.     if ( ! _ctb_is_available_ )
  866.         {
  867.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  868.         return TCL_ERROR;
  869.         }
  870.     
  871.     if (argc != 2 && argc != 3)
  872.         {
  873.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  874.                             " ctbname ?ticks?\"", NULL);
  875.         return TCL_ERROR;
  876.         }
  877.  
  878.     for (index = 0 ; index < _max_ctb_ ; ++index)
  879.         {
  880.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  881.             break;
  882.         }
  883.  
  884.     if (index >= _max_ctb_)
  885.         {
  886.         Tcl_AppendResult(interp, "connection \"",
  887.                             argv[1], "\" not found", (char *) NULL);
  888.         return TCL_ERROR;
  889.         }
  890.  
  891.     if (_ctb_[index].state != CONNECTION_OPEN_STATE)
  892.         {
  893.         Tcl_AppendResult(interp, "connection \"", argv[1],
  894.                             "\" is not open", NULL);
  895.         return TCL_ERROR;
  896.         }
  897.  
  898.     if (argc == 3)
  899.         {
  900.         if ( sscanf(argv[2], "%ld", &duration) != 1 )
  901.             duration = 30;
  902.         }
  903.     
  904.     CMBreak(_ctb_[index].connH, duration, (Boolean)0, NULL);
  905.         
  906.     if (myerr != noErr)
  907.         {
  908.         Tcl_AppendResult(interp, "error storing data, ", 
  909.                             Tcl_MacGetError(interp, myerr), NULL);
  910.         return TCL_ERROR;
  911.         }
  912.     return TCL_OK;
  913.     }
  914.  
  915. int
  916. Cmd_CTBClose(clientData, interp, argc, argv)
  917.     char        *clientData;
  918.     Tcl_Interp    *interp;
  919.     int            argc;
  920.     char        **argv;
  921.     {
  922.     int        index, result, myerr;
  923.     
  924. #    pragma unused (clientData)
  925.  
  926.     if ( ! _ctb_is_available_ )
  927.         {
  928.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  929.         return TCL_ERROR;
  930.         }
  931.     
  932.     if (argc != 2)
  933.         {
  934.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  935.             " ctbname\"", (char *) NULL);
  936.         return TCL_ERROR;
  937.         }
  938.  
  939.     for (index = 0 ; index < _max_ctb_ ; ++index)
  940.         {
  941.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  942.             break;
  943.         }
  944.  
  945.     if (index >= _max_ctb_)
  946.         {
  947.         Tcl_AppendResult(interp, "connection \"", argv[1], "\" not found", NULL);
  948.         return TCL_ERROR;
  949.         }
  950.  
  951.     if (_ctb_[index].state == CONNECTION_CLOSED_STATE ||
  952.         _ctb_[index].state == CONNECTION_UNUSED_STATE)
  953.         {
  954.         Tcl_AppendResult(interp, "connection \"", argv[1], "\" is not open", NULL);
  955.         return TCL_ERROR;
  956.         }
  957.     
  958.     myerr = CMClose(_ctb_[index].connH, (Boolean)0, NULL, (long)0, (Boolean)1);
  959.  
  960.     _ctb_[index].state = CONNECTION_CLOSED_STATE;
  961.     
  962.     return TCL_OK;
  963.     }
  964.  
  965. int
  966. Cmd_CTBDispose(clientData, interp, argc, argv)
  967.     char        *clientData;
  968.     Tcl_Interp    *interp;
  969.     int            argc;
  970.     char        **argv;
  971.     {
  972.     int        index, result, myerr;
  973.     
  974. #    pragma unused (clientData)
  975.  
  976.     if ( ! _ctb_is_available_ )
  977.         {
  978.         Tcl_AppendResult(interp, "CTB is not available on this Macintosh", NULL);
  979.         return TCL_ERROR;
  980.         }
  981.     
  982.     if (argc != 2)
  983.         {
  984.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  985.             " ctbname\"", (char *) NULL);
  986.         return TCL_ERROR;
  987.         }
  988.  
  989.     for (index = 0 ; index < _max_ctb_ ; ++index)
  990.         {
  991.         if (strcmp(_ctb_[index].name, argv[1]) == SAMESTR)
  992.             break;
  993.         }
  994.  
  995.     if (index >= _max_ctb_)
  996.         {
  997.         Tcl_AppendResult(interp, "connection \"", argv[1], "\" not found", NULL);
  998.         return TCL_ERROR;
  999.         }
  1000.  
  1001.     if (_ctb_[index].state != CONNECTION_CLOSED_STATE)
  1002.         {
  1003.         myerr = CMClose(_ctb_[index].connH, (Boolean)0, NULL, (long)0, (Boolean)1);
  1004.         }
  1005.     
  1006.     CMDispose(_ctb_[index].connH);
  1007.  
  1008.     _ctb_[index].connH = (ConnHandle) 0;
  1009.     _ctb_[index].connID = -1;
  1010.     _ctb_[index].state = CONNECTION_UNUSED_STATE;
  1011.     _ctb_[index].name[0] = '\0';
  1012.     
  1013.     return TCL_OK;
  1014.     }
  1015.  
  1016. Tcl_CTBIdleChecks()
  1017.     {
  1018.     int        index;
  1019.     
  1020.     for (index = 0 ; index < _max_ctb_ ; ++index)
  1021.         {
  1022.         if (_ctb_[index].state != CONNECTION_UNUSED_STATE)
  1023.             if (_ctb_[index].connH != NULL)
  1024.                 CMIdle(_ctb_[index].connH);
  1025.         }
  1026.     }
  1027.  
  1028. Tcl_InitCTB(interp)
  1029.     Tcl_Interp    *interp;
  1030.     { 
  1031.     Tcl_CreateCommand(interp, "ctb_create", Cmd_CTBCreate,
  1032.                         (ClientData)NULL, (void (*)())NULL);
  1033.     Tcl_CreateCommand(interp, "ctb_dispose", Cmd_CTBDispose,
  1034.                         (ClientData)NULL, (void (*)())NULL);
  1035.     Tcl_CreateCommand(interp, "ctb_open", Cmd_CTBOpen,
  1036.                         (ClientData)NULL, (void (*)())NULL);
  1037.     Tcl_CreateCommand(interp, "ctb_listen", Cmd_CTBListen,
  1038.                         (ClientData)NULL, (void (*)())NULL);
  1039.     Tcl_CreateCommand(interp, "ctb_accept", Cmd_CTBAccept,
  1040.                         (ClientData)NULL, (void (*)())NULL);
  1041.     Tcl_CreateCommand(interp, "ctb_close", Cmd_CTBClose,
  1042.                         (ClientData)NULL, (void (*)())NULL);
  1043.     Tcl_CreateCommand(interp, "ctb_write", Cmd_CTBWrite,
  1044.                         (ClientData)NULL, (void (*)())NULL);
  1045.     Tcl_CreateCommand(interp, "ctb_break", Cmd_CTBBreak,
  1046.                         (ClientData)NULL, (void (*)())NULL);
  1047.     Tcl_CreateCommand(interp, "ctb_read", Cmd_CTBRead,
  1048.                         (ClientData)NULL, (void (*)())NULL);
  1049.     Tcl_CreateCommand(interp, "ctb_getconfig", Cmd_CTBGetConfig,
  1050.                         (ClientData)NULL, (void (*)())NULL);
  1051.     Tcl_CreateCommand(interp, "ctb_setconfig", Cmd_CTBSetConfig,
  1052.                         (ClientData)NULL, (void (*)())NULL);
  1053.     Tcl_CreateCommand(interp, "ctb_config", Cmd_CTBConfigDialog,
  1054.                         (ClientData)NULL, (void (*)())NULL);
  1055.     Tcl_CreateCommand(interp, "ctb_status", Cmd_CTBGetStatus,
  1056.                         (ClientData)NULL, (void (*)())NULL);
  1057.     }
  1058.  
  1059. InitCTBCommunications()
  1060.     {
  1061.     short    myerr;
  1062.  
  1063.     myerr = InitCRM();
  1064.     if (myerr != noErr)
  1065.         return 0;
  1066.     
  1067.     myerr = InitCTBUtilities();
  1068.     if (myerr != noErr)
  1069.         return 0;
  1070.     
  1071.     myerr = InitCM();
  1072.     if (myerr != noErr)
  1073.         return 0;
  1074.  
  1075. #ifdef UNDONE
  1076.     myerr = InitTM();
  1077.     if (myerr != noErr)
  1078.         return 0;
  1079.  
  1080.     myerr = InitFT();
  1081.     if (myerr != noErr)
  1082.         {
  1083.         return 0;
  1084.         }
  1085. #endif
  1086.  
  1087.     return 1;
  1088.     }
  1089.  
  1090. #define UNIMPTrapNumber        0x9F
  1091. #define CTBTrapNumber        0x8B
  1092.  
  1093. CheckForCTB()
  1094.     {
  1095.     if (NGetTrapAddress(UNIMPTrapNumber, OSTrap)
  1096.             == NGetTrapAddress(CTBTrapNumber, OSTrap))
  1097.         return 0;
  1098.     else
  1099.         return 1;
  1100.     }
  1101.  
  1102.