예제 #1
0
파일: remShell.c 프로젝트: ariavie/bcm
/*******************************************************************************
*
* remShellTelnetDisconn - disconnect shell from telnet
*
* This routine is called from the telnetInTask either as a result of the 
* connection terminating from the remote host, or as a result of the logout() 
* command issued to our shell.  It is therefore always run in the context of 
* the telnetInTask.
* 
* The shell standard I/O is redirected back to the console, and the shell is 
* restarted.
*
* RETURNS: N/A
*/
void remShellTelnetDisconn
    (
    int disconnArg
    )
    {
    shellLogoutInstall ((FUNCPTR) NULL, 0);     /* uninstall logout function */

    if (logFdFromRlogin != NONE)
        {
        logFdDelete (logFdFromRlogin);		/* cancel extra log device */
        logFdFromRlogin = NONE;			/* reset fd */
        }
#if VX_VERSION == 55 || VX_VERSION == 542
    shellOrigStdSet (STD_IN,  shellInFd);       /* restore shell's stnd I/O */
    shellOrigStdSet (STD_OUT, shellOutFd);
    shellOrigStdSet (STD_ERR, shellErrFd);
#endif
    shellLock (FALSE);                          /* unlock shell */

    /* For typical remote sessions, there is no need to restart the shell.
     * If we are in shell context, simply restoring the standard I/O
     * descriptors is enough to get the shell back on track upon return
     * from this function.  If we are in telnetInTask context, the closing
     * of the pty device will cause the shell to unblock from its read()
     * and do subsequent I/O from the restored descriptors.
     * However, problems can occur upon logout if the remote user has
     * disabled the line editor and/or put the pty device in raw mode.
     * The problem caused is that the shell does not resume properly.
     * It is therefore deemed prudent to always restart the shell, thereby
     * avoiding any funny business.
     *
     * The previous version attempted to send a ctrl-D up the pty device
     * to wakeup and restart the shell.  Unfortunately, ctrl-D only has
     * special meaning when the device is in line mode, and hence did
     * not work in raw mode.
     *
     * The pty device is closed after the shell is restarted, when called
     * from telnetInTask, to avoid waking the existing shell and causing an
     * additional prompt to appear on the console.
     */

    activeFlag = FALSE;			/* allow new connection */

#if (_WRS_VXWORKS_MAJOR >= 6) 
    excJobAdd((VOIDFUNCPTR)shellRestart,
                  (int)CURRENT_SHELL_SESSION , 0, 0, 0, 0, 0);
#else
    excJobAdd(shellRestart, FALSE, 0, 0, 0, 0, 0);
#endif
    } /* remShellTelnetDisconn */
예제 #2
0
파일: excLib.c 프로젝트: phoboz/vmx
void printExc(
    char *fmt,
    ARG arg0,
    ARG arg1,
    ARG arg2,
    ARG arg3,
    ARG arg4
    )
{
    if (excJobAdd(
            (VOIDFUNCPTR) printErr,
            fmt,
            (ARG) arg0,
            (ARG) arg1,
            (ARG) arg2,
            (ARG) arg3,
            (ARG) arg4
            ) != OK)
    {
        fprintf(
            stderr,
            fmt,
            (ARG) arg0,
            (ARG) arg1,
            (ARG) arg2,
            (ARG) arg3,
            (ARG) arg4
            );
    }
}
예제 #3
0
파일: dbgLib.c 프로젝트: phoboz/vmx
LOCAL void dbgTyAbort(
    void
    )
{
    /* Generate exception to restart shell */
    excJobAdd(
        (VOIDFUNCPTR) dbgTaskTyAbort,
        (ARG) 0,
        (ARG) 0,
        (ARG) 0,
        (ARG) 0,
        (ARG) 0,
        (ARG) 0
        );
}
예제 #4
0
파일: taskLib.c 프로젝트: phoboz/vmx
STATUS taskDestroy(
    int      taskId,
    BOOL     freeStack,
    unsigned timeout,
    BOOL     forceDestroy
    )
{
  STATUS status;
  int i, level;
  TCB_ID tcbId;

  if (INT_RESTRICT() != OK)
  {
    errnoSet (S_intLib_NOT_ISR_CALLABLE);
    return ERROR;
  }

  /* Get task context */
  tcbId = taskTcb(taskId);
  if (tcbId == NULL)
    return ERROR;

  /* If task self destruct and excption lib installed */
  if (tcbId == taskIdCurrent) {

    /* Wait for safe to destroy */
    while (tcbId->safeCount > 0)
      taskUnsafe();

    /* Kill it */
    status = excJobAdd(
        (VOIDFUNCPTR) taskDestroy,
        (ARG) tcbId,
        (ARG) freeStack,
        (ARG) WAIT_NONE,
        (ARG) FALSE,
        (ARG) 0,
        (ARG) 0
        );

    /* Block here and suspend */
    while(status == OK)
      taskSuspend(0);

  } /* End if task self destruct and exception lib installed */

taskDestroyLoop:

  /* Lock interrupts */
  INT_LOCK(level);

  /* Check id */
  if (TASK_ID_VERIFY(tcbId) != OK)
  {
    /* errno set by taskIdVerify() */

    /* Unlock interrupts */
    INT_UNLOCK(level);

    return ERROR;
  }

  /* Mask all signals */
  if (tcbId->pSignalInfo != NULL)
    tcbId->pSignalInfo->sigt_blocked = 0xffffffff;

  /* Block here for safe and running locked tasks */
  while ( (tcbId->safeCount > 0) ||
          ( (tcbId->status == TASK_READY) && (tcbId->lockCount > 0) )
        )
  {
    /* Enter kernel mode */
    kernelState = TRUE;

    /* Unlock interrupts */
    INT_UNLOCK(level);

    /* Check if force deletion, or suicide */
    if (forceDestroy || (tcbId == taskIdCurrent))
    {

      /* Remove protections */
      tcbId->safeCount = 0;
      tcbId->lockCount = 0;

      /* Check if flush of safety queue is needed */
      if (Q_FIRST(&tcbId->safetyQ) != NULL)
        vmxPendQFlush(&tcbId->safetyQ);

      /* Exit trough kernel */
      vmxExit();
    }
    else
    {
      /* Not forced deletion or suicide */

      /* Put task on safe queue */
      if (vmxPendQPut(&tcbId->safetyQ, timeout) != OK)
      {
        /* Exit trough kernel */
        vmxExit();

        errnoSet (S_taskLib_INVALID_TIMEOUT);

        return ERROR;
      }

      /* Exit trough kernel */
      status = vmxExit();

      /* Check for restart */
      if (status == SIG_RESTART)
      {
        timeout = (sigTimeoutRecalc)(timeout);
        goto taskDestroyLoop;
      }

      /* Check if unsuccessful */
      if (status == ERROR)
      {
          /* timer should have set errno to S_objLib_TIMEOUT */
          return ERROR;
      }

    } /* End else forced or suicide */

    /* Lock interrupts */
    INT_LOCK(level);

    /* Now verify class id again */
    if (TASK_ID_VERIFY(tcbId) != OK)
    {
      /* errno set by taskIdVerify() */

      /* Unlock interrupts */
      INT_UNLOCK(level);

      return ERROR;
    }

  } /* End while blocked by safety */

  /* Now only one cadidate is selected for deletion */

  /* Make myself safe */
  taskSafe();

  /* Protet deletion cadidate */
  tcbId->safeCount++;

   /* Check if not suicide */
   if (tcbId != taskIdCurrent)
   {
     /* Enter kernel mode */
     kernelState = TRUE;

     /* Unlock interrupts */
     INT_UNLOCK(level);

     /* Suspend victim */
     vmxSuspend(tcbId);

     /* Exit trough kernel */
     vmxExit();
  }
  else
  {
     /* Unlock interrupts */
     INT_UNLOCK(level);
  }

  /* Run deletion hooks */
  for (i = 0; i < MAX_TASK_DELETE_HOOKS; i++)
    if (taskDeleteHooks[i] != NULL)
      (*taskDeleteHooks[i])(tcbId);

  /* Lock task */
  taskLock();

  /* If dealloc and options dealloc stack */
  if ( freeStack && (tcbId->options & TASK_OPTIONS_DEALLOC_STACK) ) {

#if (_STACK_DIR == _STACK_GROWS_DOWN)

    objFree(taskClassId, tcbId->pStackEnd);

#else /* _STACK_GROWS_UP */

    objFree(taskClassId, tbcId - TASK_EXTRA_BYTES);

#endif /* _STACK_DIR */

  }

  /* Lock interrupts */
  INT_LOCK(level);

  /* Invalidate id */
  objCoreTerminate(&tcbId->objCore);

  /* Enter kernel mode */
  kernelState = TRUE;

  /* Unlock interrupts */
  INT_UNLOCK(level);

  /* Delete task */
  status = vmxDelete(tcbId);

  /* Check if safe quque needs to be flushed */
  if (Q_FIRST(&tcbId->safetyQ) != NULL)
    vmxPendQFlush(&tcbId->safetyQ);

  /* Exit trough kernel */
  vmxExit();

  /* Unprotect */
  taskUnlock();
  taskUnsafe();

  return OK;
}
예제 #5
0
STATUS shellParserControl
    (
    UINT32 remoteEvent,	/* Starting or stopping a connection? */
    UINT32 sessionId, 	/* Unique identifier for each session */
    UINT32 slaveFd      /* File descriptor for character i/o  */
    )
    {

    if ((taskNameToId ("tShell")) == ERROR)   /* Shell not started yet. */
        return (ERROR);

    if (remoteEvent == REMOTE_START)
        {
        /* Handle a new telnet or rlogin session. */

        if (remoteId != 0)    /* Failed request - only one session allowed. */
            return (ERROR); 

        if (!shellLock (TRUE)) 	/* Shell is not available. */
            {
	    fdprintf (slaveFd, "The shell is currently in use.\n");
            return (ERROR);
            }

        /* Let the user try to login */
	if (shellLogin (slaveFd) != OK)
	    { 
 	    shellLock (FALSE);
            return (ERROR);
            }

        /* setup the slave device to act like a terminal */

        (void) ioctl (slaveFd, FIOOPTIONS, OPT_TERMINAL);

        shellLogoutInstall ((FUNCPTR) telnetdExit, sessionId);

        /* get the shell's standard I/O fd's so we can restore them later */

        shellInFd  = ioGlobalStdGet (STD_IN);
        shellOutFd = ioGlobalStdGet (STD_OUT);
        shellErrFd = ioGlobalStdGet (STD_ERR);

        /* set shell's standard I/O to new device; add extra logging device */

        shellOrigStdSet (STD_IN, slaveFd);
        shellOrigStdSet (STD_OUT, slaveFd);
        shellOrigStdSet (STD_ERR, slaveFd);

        logFdAdd (slaveFd);
        logFdFromRlogin = slaveFd;      /* store new fd for logFdSet() */

        /* Store the session identifier. */

        remoteId = sessionId;

        /* notify the shell we have started a remote session */
        
        shellIsRemoteConnectedSet (TRUE);

        printErr ("\ntelnetd: This system *IN USE* via telnet.\n");

        /* Prevent network denial of service attacks by waiting a second */

        taskDelay (sysClkRateGet() / 2); 
       
        /* Restart the shell to access the redirected file descriptors. */

        excJobAdd (shellRestart, TRUE, 0, 0, 0, 0, 0);

        return (OK);
        }
    else if (remoteEvent == REMOTE_STOP)
        {
        /*
         * End an active telnet or rlogin session. This event occurs
         * after the server closes the socket.
         */

        if (remoteId != sessionId)    /* Unknown remote session. */
            return (ERROR);

        shellLogoutInstall ((FUNCPTR) NULL, 0);  /* remove logout function */

        if (logFdFromRlogin != NONE)
            {
            logFdDelete (logFdFromRlogin);       /* cancel extra log device */
            logFdFromRlogin = NONE;              /* reset fd */
            }

        shellOrigStdSet (STD_IN,  shellInFd);    /* restore shell's stnd I/O */
        shellOrigStdSet (STD_OUT, shellOutFd);
        shellOrigStdSet (STD_ERR, shellErrFd);

        shellLock (FALSE);                       /* unlock shell */

        /*
         * For typical remote sessions, restoring the standard I/O
         * descriptors is enough to reconnect the shell to the console
         * because closing the pty device will cause the shell to unblock
         * from its read() and use the restored descriptors. However,
         * problems can occur upon logout if the remote user has disabled
         * the line editor and/or put the pty device in raw mode, so the
         * shell is restarted in all cases.
         */

        remoteId = 0;    /* Allow a new session. */

       /* notify the shell we have ended a remote session */
        
        shellIsRemoteConnectedSet (FALSE);

        excJobAdd (shellRestart, FALSE, 0, 0, 0, 0, 0);

        return (OK);
        }

    return (ERROR);    /* Ignore unknown control operations. */
    }
예제 #6
0
파일: remShell.c 프로젝트: ariavie/bcm
/*******************************************************************************
*
* remShellTelnetConn - connect shell to telnet
*
* This routine is called by the telnet demon to connect the shell with the 
* remote telnet user.
* Remote telnet requests will cause `stdin', `stdout', and `stderr' to be stolen
* away from the console.  When the remote user disconnects, `stdin', `stdout',
* and `stderr' are restored, and the shell is restarted.
*
* RETURNS: OK or ERROR.
*/
STATUS remShellTelnetConn
    (
    int              interpConnArg,	/* argument for interpConn () */
    int              slaveFd,
    int              exitArg,		/*  */
    int *            disconnArg,
    char *           msg
    )
    {
    /* wait for shell to exist */

    while (taskNameToId (telnetShellName) == ERROR)
        taskDelay (sysClkRateGet ());

    /* check to see if there's already an active connection */

    if (activeFlag)
        {
        strcpy(msg, "\r\nSorry, this system is engaged.\r\n");

        return ERROR;
        }

    if (!shellLock (TRUE))
	{
	strcpy(msg, "\r\nSorry, shell is locked.\r\n");

	printErr ("telnetd: someone tried to login into.\n");
        return ERROR;
	}

    printErr ("\ntelnetd: This system *IN USE* via telnet.\n");

    shellLogoutInstall ((FUNCPTR) telnetdExit, exitArg);
    activeFlag    = TRUE;

    /* get the shell's standard I/O fd's so we can restore them later */

    shellInFd  = ioGlobalStdGet (STD_IN);
    shellOutFd = ioGlobalStdGet (STD_OUT);
    shellErrFd = ioGlobalStdGet (STD_ERR);

#ifndef BROADCOM_DEBUG
#if VX_VERSION == 55 || VX_VERSION == 542
    /* set shell's standard I/O to pty device; add extra logging device */

    shellOrigStdSet (STD_IN, slaveFd);
    shellOrigStdSet (STD_OUT, slaveFd);
    shellOrigStdSet (STD_ERR, slaveFd);

    logFdAdd (slaveFd);
    logFdFromRlogin = slaveFd;      /* store pty fd for logFdSet() */
#endif
#endif	/* BROADCOM_DEBUG */

    /* the shell is currently stuck in a read from the console, so we
     * restart it */

#ifndef BROADCOM_DEBUG
#if (_WRS_VXWORKS_MAJOR >= 6) 
    excJobAdd((VOIDFUNCPTR)shellRestart,
                  (int)CURRENT_SHELL_SESSION , 0, 0, 0, 0, 0);
#else
    excJobAdd (shellRestart, TRUE, 0, 0, 0, 0, 0);
#endif
#else
    sp (copyStreams, slaveFd, slaveFd,0,0,0,0,0,0,0); /* !!! */
#endif	/* BROADCOM_DEBUG */

    (void) ioctl (slaveFd, FIOFLUSH, 0 /*XXX*/);

    return OK;
    } /* remShellTelnetConn */