⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 telnetdlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        /*          * Dynamic session creation needs all elements of the structure          * initialized to sane values          */        pSlot->socket         = -1;        pSlot->inputFd        = -1;                    pSlot->outputFd       = -1;                  pSlot->slaveFd        = -1;                  pSlot->outputTask     = -1;              pSlot->inputTask      = -1;              pSlot->parserControl  = 0;         }    /* Add new entry to the list of active sessions. */    lstAdd (&telnetdSessionList, &pSlot->node);    semGive (telnetdMutexSem);     return (pSlot);    }/********************************************************************************* telnetdSessionDisconnect - Shut down a session** This routine removes a connection and all associated resources for it.** This may be called because of login failure or end of a shell session** NOMANUAL*/LOCAL void telnetdSessionDisconnect      (     TELNETD_SESSION_DATA *pSlot,      BOOL pSlotDelete /* For DYNAMIC mode,  should pSlot be free'd when done? */     )     {     if (pSlot == NULL)         return;     semTake (telnetdMutexSem, WAIT_FOREVER);      /*       * Make sure the task is still valid.  It is possible that       * the connection was killed during login (telnetInTask),      *                    failed login (telnetd)      *                    terminated by shell (shell task)      */           /* For STATIC sessions,  we need to clean/sanitize all of it's resources */     if (telnetdTaskFlag)          {        /* Halt the i/o tasks */        if (pSlot->outputTask)            taskSuspend (pSlot->outputTask);        if (pSlot->inputTask)            taskSuspend (pSlot->inputTask);        /* Make sure the semaphores are empty */        if (pSlot->startInput)            semTake (pSlot->startInput, NO_WAIT);        if (pSlot->startOutput)            semTake (pSlot->startOutput, NO_WAIT);        /* Restart the I/O tasks, they will pend on the empty semaphores */        if (pSlot->outputTask)            taskRestart (pSlot->outputTask);        if (pSlot->inputTask)            taskRestart (pSlot->inputTask);        /* Clear out the i/o descriptors */        if ((pSlot->outputFd) > STD_ERR)            ioctl (pSlot->outputFd, FIOFLUSH, 0);        if ((pSlot->slaveFd) > STD_ERR)            ioctl (pSlot->slaveFd, FIOFLUSH, 0);        /* Close the socket connection to the client */        if ((pSlot->socket) > STD_ERR)             close (pSlot->socket);          /*          * Re-Initialize some elements of the structure to sane values          * We will not re-initialize the taskId's or the i/o file descriptors         * because these resources are just reset and not removed.         */        pSlot->socket        = -1;        pSlot->parserControl = telnetdParserControl;        pSlot->loggedIn      = FALSE;        pSlot->busyFlag      = FALSE;        --telnetdCurrentClients;        lstDelete (&telnetdSessionList, &pSlot->node);        }     else        {        /* For DYNAMIC sessions,  we need to free all of it's resources */        /* Remove the i/o tasks */        if (pSlot->outputTask)            taskDelete (pSlot->outputTask);        if (pSlot->inputTask)            taskDelete (pSlot->inputTask);        /* Delete the semaphores */        if (pSlot->startInput)            semDelete (pSlot->startInput);        if (pSlot->startOutput)            semDelete (pSlot->startOutput);        /* Close the i/o descriptors */        if ((pSlot->outputFd) > STD_ERR)            close (pSlot->outputFd);        if ((pSlot->slaveFd) > STD_ERR)            close (pSlot->slaveFd);        /* Remove the pseudo terminal for the session. */        (void) ptyDevRemove (pSlot->ptyRemoteName);        /* Close the socket connection to the client */        if ((pSlot->socket) > STD_ERR)             close (pSlot->socket);          /* Re-Initialize all elements of the structure to sane values */        pSlot->socket         = -1;        pSlot->inputFd        = -1;                    pSlot->outputFd       = -1;                  pSlot->slaveFd        = -1;                  pSlot->outputTask     = 0;              pSlot->inputTask      = 0;              pSlot->parserControl  = 0;         pSlot->busyFlag       = FALSE;        --telnetdCurrentClients;        lstDelete (&telnetdSessionList, &pSlot->node);        /*          * If we are not logged in, then the connection must have been shut down         * during login.   When the login routine terminates, the pSlot will be         * free'd. This will be determined by the telnetd if parserControl == 0         */        if ((pSlot->loggedIn == TRUE) &&             (pSlotDelete == TRUE))            free (pSlot);        else            pSlot->loggedIn = FALSE;         }     semGive (telnetdMutexSem);      }/********************************************************************************* telnetdSessionDisconnectFromShellJob - terminate a session from the shell** This is called from the shell context during a excTask() and is invoked * by calling telnetdSessionDisconnectFromShell.** NOTE: The inTask may also terminate the connection via *       telnetdSessionDisconnectFromRemote()** RETURNS N/A** NOMANUAL*/LOCAL void telnetdSessionDisconnectFromShellJob (TELNETD_SESSION_DATA *pSlot)    {    /* Shut down the connection */    telnetdSessionDisconnect (pSlot, FALSE);    if (*telnetdParserControl)         (*telnetdParserControl) (REMOTE_STOP, pSlot, 0);      if (!telnetdTaskFlag)        free (pSlot);    }/********************************************************************************* telnetdSessionDisconnectFromShell - terminate a session from the shell** This is called from the shell context during a logout() call * NOTE: The inTask may also terminate the connection via *       telnetdSessionDisconnectFromRemote()** RETURNS N/A** NOMANUAL*/LOCAL void telnetdSessionDisconnectFromShell (TELNETD_SESSION_DATA *pSlot)     {     excJobAdd (telnetdSessionDisconnectFromShellJob,                 (int) pSlot,                 0, 0, 0, 0, 0);     taskDelay (sysClkRateGet());     }/********************************************************************************* telnetdSessionDisconnectFromRemote - terminate a session from the shell** This is called from the telnetInTask context if the user terminates the * connection.** RETURNS N/A** NOMANUAL*/LOCAL void telnetdSessionDisconnectFromRemote (TELNETD_SESSION_DATA *pSlot)    {    /* Make the shell restart locally */    (*telnetdParserControl) (REMOTE_STOP, pSlot, 0);     /* The shell will terminate the connection for us */    if (pSlot->loggedIn == TRUE)        {        /* Shut down the connection */        telnetdSessionDisconnect (pSlot, TRUE);        }    taskDelay (sysClkRateGet());     }/********************************************************************************* telnetd - primary telnet server task** This routine monitors the telnet port for connection requests from clients.* It is the entry point for the primary telnet task created during the* library initialization.** The server will only accept telnet connection requests when a task is* available to handle the input and provide output to the remote user.* The default configuration uses the shell for this purpose by redirecting* the `stdin', `stdout', and `stderr' file descriptors away from the console.* When the remote user disconnects, those values are restored to their* previous settings and the shell is restarted.** RETURNS: N/A** NOMANUAL*/void telnetd (void)    {    struct sockaddr_in clientAddr;    int clientAddrLen;    int newSock;    int optval;    TELNETD_SESSION_DATA *pSlot;    BOOL startFlag;  /* Command interpreter started successfully? */    STATUS result;    FOREVER        {        clientAddrLen = sizeof (clientAddr);        pSlot = NULL;        result = OK;        startFlag = FALSE;        newSock = accept (telnetdServerSock,                          (struct sockaddr *) &clientAddr, &clientAddrLen);        if (newSock == ERROR)            {            break;     /* Exit if unable to accept connection. */            }        /*          * Get (static) or create (dynamic) a new session entry for this          * connection */        pSlot = telnetdSessionAdd ();        /* Check if the maximum number of connections has been reached. */        if (pSlot == NULL)              {            fdprintf (newSock, "\r\nSorry, session limit reached.\r\n");            /* Prevent denial of service attack by waiting 5 seconds */            taskDelay (sysClkRateGet () * 5);              close (newSock);            result = ERROR;            continue;            }        pSlot->socket = newSock;        /* If we haven't created the pseudo tty device, so so now */        if (remoteInitFlag == FALSE)            {            /* Create pty device for all remote sessions. */            if (ptyDrv () == ERROR)                {                fdprintf (newSock, "\n\ntelnetd: Unable to initialize ptyDrv().  errno:%#x\n",                           errno, 0, 0, 0, 0, 0);                /* Prevent denial of service attack by waiting 5 seconds */                taskDelay (sysClkRateGet () * 5);                  close (newSock);                continue;                result = ERROR;                }            remoteInitFlag = TRUE;   /* Disable further device creation. */            }        /* Check if we are in the dynamic mode */        if (!telnetdTaskFlag)            {            /*             * Create the pseudo terminal for a session. The remote machine             * will write to the master side and read from the slave side.             *              */            result = telnetdSessionPtysCreate (pSlot);            if (result == OK)                result = telnetdIoTasksCreate (pSlot);            if (result == ERROR)                {                fdprintf (newSock,                           "\r\ntelnetd: Sorry, session limit reached. Unable to spawn tasks. errno %#x\r\n",                           errno);                /* Prevent denial of service attack by waiting 5 seconds */                taskDelay (sysClkRateGet () * 5);                 telnetdSessionDisconnect (pSlot, TRUE);                result = ERROR;                continue;                }            }        /* setup the slave device to act like a terminal */        (void) ioctl (pSlot->slaveFd, FIOOPTIONS, OPT_TERMINAL);        /* Check if a parser has been installed */        if (!telnetdParserFlag)            {            fdprintf (newSock,                       "\r\ntelnetd: Sorry, a shell has not been installed.\r\n"                     );            /* Prevent denial of service attack by waiting 5 seconds */            taskDelay (sysClkRateGet () * 5);              telnetdSessionDisconnect (pSlot, TRUE);            continue;            }        /*         * Spawn (or wake up) the input task which transfers data from         * the client socket and the output task which transfers data to         * the socket.          */        if (telnetdTaskFlag)            {            semGive (pSlot->startInput);            semGive (pSlot->startOutput);            }        /* turn on KEEPALIVE so if the client crashes, we'll know about it */        optval = 1;        setsockopt (newSock, SOL_SOCKET, SO_KEEPALIVE,                    (char *) &optval, sizeof (optval));        /* initialize modes and options and offer to do remote echo */        raw = FALSE;        echo = TRUE;        bzero ((char *)myOpts, sizeof (myOpts));        bzero ((char *)remOpts, sizeof (remOpts));        (void)localDoOpt (pSlot->slaveFd, TELOPT_ECHO, TRUE, newSock, FALSE);        /*         * File descriptors are available. Save the corresponding         * parser control routine.         */        pSlot->parserControl = telnetdParserControl;        /*         * Tell the parser control function to activate the shell          *  for this session.         */        result = (*telnetdParserControl) (REMOTE_START,                                           (UINT32)pSlot,                                          pSlot->slaveFd);        /*          * If parserControl == 0, then the connection was terminated         *  during login.  The inTask has already cleaned up all resources         *  for us except the memory for pSlot.         */        if (pSlot->parserControl == 0)            {            if (!telnetdTaskFlag)                free (pSlot);            continue;            }        /*          * Was the REMOTE_START of the shell successful?          * Did we fail the login or did the remote user disconnect?         */         if (result == ERROR) /* No,  must have failed to login */            {            telnetdSessionDisconnect (pSlot, TRUE);            continue;            }        else              {            /*              * We must keep track of a successfull login with              * 'loggedIn' element since failure to login means that the              * shell was not spawned.             *             * Future session cleanup's will know that the login has been              * a success.  Therefore, the parser control will need a 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -