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

📄 telnetdlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
* The <pParserCtrlRtn> argument provides a routine using the following* interface:* .CS* STATUS parserControlRtn*     (*     int telnetdEvent,/@ start or stop a telnet session @/*     UINT32 sessionId,/@ a unique session identifier @/*     int ioFd         /@ file descriptor for character i/o @/*     )* .CE** The telnet server calls the control routine with a <telnetdEvent>* parameter of REMOTE_INIT during inititialization.  The telnet server then* calls the control routine with a <telnetdEvent> parameter of REMOTE_START * when a client establishes a new connection.* The <sessionId> parameter provides a unique identifier for the session.* * In the default configuration, the telnet server calls the control routine* with a <telnetdEvent> parameter of REMOTE_STOP when a session ends. ** The telnet server does not call the control routine when a session ends* if it is configured to spawn all tasks and allocate all resources in* advance of any connections. The associated file descriptors will be reused* by later clients and cannot be released. In that case, the REMOTE_STOP* operation only occurs to allow the command interpreter to close those* files when the server encounters a fatal error.** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only.  In addition, all arguments to this function can  * reference only that data which is valid in the kernel protection domain. * This restriction does not apply under non-AE versions of VxWorks.  ** RETURNS: OK if parser control routine installed, or ERROR otherwise.** INTERNAL: Can be called before or after telnetdInit() and telnetdStart()*/STATUS telnetdParserSet    (    FUNCPTR     pParserCtrlRtn 	/* provides parser's file descriptors */    )    {    /* We must have a valid parser */    if (pParserCtrlRtn == NULL)        return (ERROR);    /* We can not change parsers */     if (telnetdParserControl != NULL)        return (ERROR);    /* Store the provided control routine.  */    telnetdParserControl = pParserCtrlRtn;    /* Allow client connections. */    telnetdParserFlag = TRUE; 	    return (OK);    }/********************************************************************************* telnetdIoTasksCreate  - Create tasks to transferring i/o between socket and fd* * Two tasks are created: An input task and an output task.  The name is based on*    the pSlot argument for uniqueness.** NOMANUAL* * RETURNS: OK if parser control routine installed, or ERROR otherwise.*/LOCAL STATUS telnetdIoTasksCreate    (    TELNETD_SESSION_DATA *pSlot    )    {    char sessionTaskName[IO_TASK_NAME_MAX_LEN];    char sessionInTaskName[IO_TASK_NAME_MAX_LEN];    char sessionOutTaskName[IO_TASK_NAME_MAX_LEN];     int result;    /*     * Spawn the input and output tasks which transfer data between     * the socket and the i/o file descriptor.      *     * If created in advance (static) the task pend on a semaphore     */    sprintf (sessionTaskName, "_%x", (unsigned int)pSlot);    sprintf (sessionInTaskName, "tTelnetIn%s", sessionTaskName);    sprintf (sessionOutTaskName,"tTelnetOut%s", sessionTaskName);      if (telnetdTaskFlag)         {        pSlot->startOutput = semBCreate (SEM_Q_FIFO, SEM_EMPTY);        pSlot->startInput = semBCreate (SEM_Q_FIFO, SEM_EMPTY);        if ((pSlot->startInput == NULL)  || (pSlot->startInput == NULL))            {            TELNETD_DEBUG ("telnetd: Unable to create semaphore. errno:%#x\n",                            errno, 0, 0, 0, 0, 0);            result = ERROR;            return ERROR;            }        }    pSlot->outputTask = taskSpawn (sessionOutTaskName,                                    telnetTaskPriority,                                   telnetTaskOptions,                                    telnetTaskStackSize,                                   (FUNCPTR)telnetOutTask,                                    (int)pSlot,                                   0, 0, 0, 0, 0, 0, 0, 0, 0);    if (pSlot->outputTask == ERROR)        {        TELNETD_DEBUG ("telnetd: Unable to create task. errno:%#x\n",                        errno, 0, 0, 0, 0, 0);        result = ERROR;        return ERROR;        }    pSlot->inputTask = taskSpawn (sessionInTaskName,                                   telnetTaskPriority,                                  telnetTaskOptions,                                   telnetTaskStackSize,                                  (FUNCPTR)telnetInTask,                                   (int)pSlot,                                  0, 0, 0, 0, 0, 0, 0, 0, 0);    if (pSlot->inputTask == ERROR)        {        TELNETD_DEBUG ("telnetd: Unable to create task. errno:%#x\n",                        errno, 0, 0, 0, 0, 0);        taskDelete (pSlot->outputTask);                result = ERROR;        return ERROR;        }    return OK;    }/********************************************************************************* telnetdSessionPtysCreate  - Create a pty pair and open them * * Two file descriptors are created: An input and an output fd.  The name is *    based on the pSlot argument for uniqueness.  The file descriptors are *    stored in the session structure.** NOMANUAL* * RETURNS: OK if successfull, or ERROR otherwise.*/LOCAL STATUS telnetdSessionPtysCreate     (    TELNETD_SESSION_DATA *pSlot    )    {    char sessionPtyRemoteName[PTY_DEVICE_NAME_MAX_LEN];    char sessionPtyRemoteNameM[PTY_DEVICE_NAME_MAX_LEN];    char sessionPtyRemoteNameS[PTY_DEVICE_NAME_MAX_LEN];    /* Create unique names for the pty device */    sprintf (sessionPtyRemoteName, "%s_%x.", ptyRemoteName, (int)pSlot);    sprintf (sessionPtyRemoteNameM, "%sM", sessionPtyRemoteName);    sprintf (sessionPtyRemoteNameS, "%sS", sessionPtyRemoteName);    /* pseudo tty device creation */    if (ptyDevCreate (sessionPtyRemoteName,                       PTY_BUFFER_SIZE,                       PTY_BUFFER_SIZE) == ERROR)        {        return ERROR;        }    /* Master-side open of pseudo tty */    strcpy (pSlot->ptyRemoteName, sessionPtyRemoteName);    if ((masterFd = open (sessionPtyRemoteNameM, O_RDWR, 0)) == ERROR)        {        return ERROR;        }    else        {        pSlot->inputFd = masterFd;        pSlot->outputFd = masterFd;        }    /* Slave-side open of pseudo tty */    if ((pSlot->slaveFd = open (sessionPtyRemoteNameS, O_RDWR, 0)) == ERROR)        {        return ERROR;        }    /* setup the slave device to act like a terminal */    (void) ioctl (pSlot->slaveFd, FIOOPTIONS, OPT_TERMINAL);    return OK;    }/********************************************************************************* telnetdStart - initialize the telnet services** Following the telnet server initialization, this routine creates a socket* for accepting remote connections and spawns the primary telnet server task.* It executes automatically during system startup when the INCLUDE_TELNET* configuration macro is defined since a parser control routine is available.* The server will not accept connections otherwise.** By default, the server will spawn a pair of secondary input and output* tasks after each client connection. Changing the TELNETD_TASKFLAG setting* to TRUE causes this routine to create all of those tasks in advance of* any connection. In that case, it calls the current parser control routine* repeatedly to obtain file descriptors for each possible client based on* the <numClients> argument to the initialization routine. The server will* not start if the parser control routine returns ERROR.** The TELNETD_PORT constant provides the <port> argument, which assigns the* port where the server accepts connections. The default value is the standard* setting of 23. ** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only.  This restriction does not apply under non-AE * versions of VxWorks.  ** RETURNS: OK, or ERROR if startup fails*/STATUS telnetdStart    (    int port 	/* target port for accepting connections */    )    {    struct sockaddr_in serverAddr;    if (!telnetdInitialized)        {        TELNETD_DEBUG ("telnetd: Must be initialized with telnetdInit() first.\n",                        0, 0, 0, 0, 0, 0);        return (ERROR);        }    if (telnetdStartFlag)        return (OK);    /*      * At this point (for both static and dynamic task initialization) we      * are ready to create the server socket.     */    telnetdServerSock = socket (AF_INET, SOCK_STREAM, 0);    if (telnetdServerSock < 0)        return (ERROR);    bzero ((char *)&serverAddr, sizeof (serverAddr));    serverAddr.sin_family = AF_INET;    serverAddr.sin_port   = htons (port);    if (bind (telnetdServerSock, (struct sockaddr *) &serverAddr,              sizeof (serverAddr)) < 0)        {        close (telnetdServerSock);        if (telnetdTaskFlag)            telnetdTaskDelete (telnetdMaxClients);        return (ERROR);        }    if (listen (telnetdServerSock, 5) < 0)        {        close (telnetdServerSock);        if (telnetdTaskFlag)            telnetdTaskDelete (telnetdMaxClients);        return (ERROR);        }          /* Create a telnet server task to receive connection requests. */    telnetdTaskId = taskSpawn ("tTelnetd",                                telnetTaskPriority,                               telnetTaskOptions,                                telnetTaskStackSize,                               (FUNCPTR)telnetd,                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0);    if (telnetdTaskId == ERROR)        {        close (telnetdServerSock);        if (telnetdTaskFlag)            telnetdTaskDelete (telnetdMaxClients);        return (ERROR);        }    return (OK);    }/********************************************************************************* telnetdTaskDelete - remove task data from task list** This routine releases the system objects which monitor the secondary input* and output tasks for telnet clients. The server uses this routine to clean* up the (partial) task list if an error occurs during multiple task enabled * startup.** RETURNS: N/A** NOMANUAL*/LOCAL void telnetdTaskDelete    (    int 	numTasks 	/* number of entries to remove */    )    {    int 	count;    BOOL telnetdTaskFlagSave;     telnetdTaskFlagSave = telnetdTaskFlag; /* Save original state */    /*      * Make sure the flag is set to FALSE so we delete objects instead of     * restart objects with  telnetdSessionDisconnectFromShell ()     */    telnetdTaskFlag = FALSE;    for (count = 0; count < numTasks; count++)        {        if (telnetdParserControl != NULL)           (*telnetdParserControl) (REMOTE_STOP,                                     telnetdTaskList [count].pSession,                                    0);          if (telnetdTaskList [count].pSession != NULL)            {            telnetdSessionDisconnect (telnetdTaskList [count].pSession, TRUE);            free (telnetdTaskList [count].pSession);            }        }     free (telnetdTaskList);    semDelete (telnetdMutexSem);    telnetdTaskFlag = telnetdTaskFlagSave; /* Restore original state */    return;    }/********************************************************************************* telnetdExit - close an active telnet session** This routine supports the session exit command for a command interpreter* (such as logout() for the VxWorks shell). Depending on the TELNETD_TASKFLAG* setting, it causes the associated input and output tasks to restart or exit.* The <sessionId> parameter must match a value provided to the command* interpreter with the REMOTE_START option.** INTERNAL* This routine is used for termination via the shell.  The inTask may also *   terminate the connection via telnetdSessionDisconnectFromShell()** RETURNS: N/A.** ERRNO: N/A*/void telnetdExit    (    UINT32 sessionId 	/* identifies the session to be deleted */    )    {    telnetdSessionDisconnectFromShell ((TELNETD_SESSION_DATA *)sessionId);    return;    }/********************************************************************************* telnetdSessionAdd - add a new entry to the telnetd session slot list** Each of the telnet clients is associated with an entry in the server's* session list which records the session-specific context for each* connection, including the file descriptors that access the command* interpreter. This routine creates and initializes a new entry in the* session list, unless the needed memory is not available or the upper* limit for simultaneous connections is reached.** RETURNS: A pointer to the session list entry, or NULL if none available.** ERRNO: N/A** NOMANUAL**/LOCAL TELNETD_SESSION_DATA *telnetdSessionAdd (void)    {    TELNETD_SESSION_DATA * 	pSlot;    int count = 0;    semTake (telnetdMutexSem, WAIT_FOREVER);     if (telnetdCurrentClients == telnetdMaxClients)        {        semGive (telnetdMutexSem);         return (NULL);        }    /* Find an idle pair of input/output tasks, if needed. */    if (telnetdTaskFlag)     /* Tasks created during server startup? */        {        for (count = 0; count < telnetdMaxClients; count++)            if (!telnetdTaskList [count].pSession->busyFlag)                break;        }       /* Are there no more sessions available ? */     if (telnetdTaskFlag && (count == telnetdMaxClients))        {        semGive (telnetdMutexSem);         return ((TELNETD_SESSION_DATA *) NULL);        }      /* get memory for the new session entry */    if (telnetdTaskFlag)            pSlot = telnetdTaskList [count].pSession;    else        {       pSlot = (TELNETD_SESSION_DATA *) calloc (sizeof (TELNETD_SESSION_DATA),                1);       if (pSlot == NULL)           {           semGive (telnetdMutexSem);            return (NULL);           }       telnetdTaskList [count].pSession = pSlot;       }    pSlot->busyFlag = TRUE;    pSlot->loggedIn = FALSE;    telnetdCurrentClients++;    if (!telnetdTaskFlag)        {

⌨️ 快捷键说明

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