如何将telnet通道连接到Tcl解释器

时间:2015-05-04 09:36:30

标签: tcl telnet interpreter

我在我的C应用程序中嵌入了Tcl解释器。我想将C应用程序作为telnet服务器运行,并且执行从telnet客户端发送的Tcl命令

我写了一个示例代码,如Tcl_SocketObjCmd()

问题:如何将telnet通道连接到Tcl解释器,然后执行从telnet客户端发送的Tcl命令?

似乎是为了在Tcl_MainEx()中实现tclMain.c的功能。 但现在我不知道如何将Telnet服务器通道连接到Tcl解释器。

typedef struct AcceptCallback 
{
     char *script;       
     Tcl_Interp *interp;     
} AcceptCallback;


int 
main(int argc, char **argv)
{

    Tcl_Interp *interp;

    interp = Tcl_CreateInterp();
    if (NULL == interp)
    {
        return 1;
    }

    if (Tcl_Init(interp) == TCL_ERROR)
    {
       return 1;
    }

    telnet_server_init(interp, 8888, "192.168.1.100");

    while (true)
    {
        sleep(100);
    }

    return 0
}

int 
telnet_server_init(
Tcl_Interp *interp,
int port,
char *host)
{
    char *script = "";
    Tcl_Channel chan;

    AcceptCallback *acceptCallbackPtr = ckalloc(sizeof(AcceptCallback));
    unsigned len = strlen(script) + 1;
    char *copyScript = ckalloc(len);

    memcpy(copyScript, script, len);
    acceptCallbackPtr->script = copyScript;
    acceptCallbackPtr->interp = interp;
    chan = Tcl_OpenTcpServer(interp, port, host, AcceptCallbackProc, acceptCallbackPtr);
    if (chan == NULL) 
    {
        ckfree(copyScript);
        ckfree(acceptCallbackPtr);
       return TCL_ERROR;
    }

    RegisterTcpServerInterpCleanup(interp, acceptCallbackPtr);

    Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr);

    return TCL_OK;
}  

static void
AcceptCallbackProc(
    ClientData callbackData,    
    Tcl_Channel chan,       
    char *address,      
    int port)           
{
    AcceptCallback *acceptCallbackPtr = callbackData;

/*
 * Check if the callback is still valid; the interpreter may have gone
 * away, this is signalled by setting the interp field of the callback
 * data to NULL.
 */

   if (acceptCallbackPtr->interp != NULL) {
    char portBuf[TCL_INTEGER_SPACE];
    char *script = acceptCallbackPtr->script;
    Tcl_Interp *interp = acceptCallbackPtr->interp;
    int result;

    Tcl_Preserve(script);
    Tcl_Preserve(interp);

    TclFormatInt(portBuf, port);
    Tcl_RegisterChannel(interp, chan);

/*
 * Artificially bump the refcount to protect the channel from being
 * deleted while the script is being evaluated.
 */

    Tcl_RegisterChannel(NULL, chan);

    result = Tcl_VarEval(interp, script, " ", Tcl_GetChannelName(chan),
        " ", address, " ", portBuf, NULL);
    if (result != TCL_OK) {
        Tcl_BackgroundException(interp, result);
        Tcl_UnregisterChannel(interp, chan);
    }

/*
 * Decrement the artificially bumped refcount. After this it is not
 * safe anymore to use "chan", because it may now be deleted.
 */

    Tcl_UnregisterChannel(NULL, chan);

    Tcl_Release(interp);
    Tcl_Release(script);
    } else {
/*
 * The interpreter has been deleted, so there is no useful way to use
 * the client socket - just close it.
 */

    Tcl_Close(NULL, chan);
    }
}

0 个答案:

没有答案