Ejemplo n.º 1
0
Archivo: dm.c Proyecto: mit-athena/dm
/* Oooh, we're on an sgi. */
static int openpty(int *amaster, int *aslave, char *name,
		   struct termios *termp, struct winsize *winp)
{
  char *p;

  p = _getpty(amaster, O_RDWR, 0600, 0);

  if (p == NULL)
    return(-1);

  if (name != NULL)
    strcpy(name, p);

  *aslave = open(p, O_RDWR);
  if (*aslave < 0)
    {
      close(*amaster);
      return(-1);
    }

  if (termsetup(*aslave, termp, winp) < 0)
    {
      close(*amaster);
      close(*aslave);
      return(-1);
    }

  return(0);
}
Ejemplo n.º 2
0
	static char *ptymopen(int *master)
	{
		char *slave=0;
#   if _lib__getpty
		return(_getpty(master,O_RDWR,MODE_666,0));
#   else
#	if defined(_pty_clone)
		*master = open(_pty_clone,O_RDWR|O_CREAT,MODE_666);
		if(*master>=0)
			slave = ptsname(*master);
#	else
		int fdm;
		char *name=0;
		while(name=master_name(name))
		{
			fdm = open(name,O_RDWR|O_CREAT,MODE_666);
			if(fdm >= 0)
			{
				*master = fdm;
#	   if _lib_ptsname
				slave = ptsname(fdm);
#	   else
				slave = slavename(name);
#	   endif
				break;
			}
		}
# 	endif
#   endif
		return(slave);
	}
Ejemplo n.º 3
0
int
PseudoTTY (char pty_name[])
{
    int fd;
    char *ptyn;

    ptyn = _getpty(&fd, O_RDWR, 0600, 0);
    if (ptyn == NULL) return -1;
    safeStrCpy(pty_name, ptyn, sizeof(pty_name)/sizeof(pty_name[0]));
    return fd;
}
Ejemplo n.º 4
0
/**
 * taken from pts(7D), and added error handling
 */
int
openpty(int  *amaster, int *aslave, char *name,
	struct termios *termp, struct winsize *winp)
{
  int fds = -1;
  int fdm = -1;
  int saved_errno = 0;
  char *line;
  
  line = _getpty(&fdm, O_RDWR|O_NDELAY, 0600, 0);
  if (!line) {
    fprintf(stderr, "_getpty() failed\n");
    goto errout;
  }
  if (0 > (fds = open(line, O_RDWR))) {
    goto errout;
  }


  *amaster = fdm;
  *aslave = fds;

  if (name) {
    strcpy(name, ptsname(*amaster));
  }
  printf("%d %d\n", *amaster, *aslave);
  if (termp) {
    if (0 > tcsetattr(*aslave, TCSADRAIN, termp)) {
      fprintf(stderr, "lala\n");
      goto errout;
    } 
  }
  if (winp) {
    if (0 > ioctl(*aslave, TIOCSWINSZ, winp)) {
      fprintf(stderr, "lolo\n");
      goto errout;
    }
  }
  return 0;

 errout:
  saved_errno = errno;
  if (0 < fds) {
    do_close(fds);
  }
  if (0 < fdm) {
    do_close(fdm);
  }
  if (name) {
    *name = 0;
  }
  errno = saved_errno;
  return -1;
}
Ejemplo n.º 5
0
Archivo: pty.c Proyecto: GNOME/gftp
static int
_gftp_ptym_open (char *pts_name, size_t len, int *fds)
{
  char *new_pts_name;
  int fdm;

  if ((new_pts_name = _getpty (&fdm, O_RDWR, 0600, 0)) == NULL)
    return (GFTP_ERETRYABLE);

  strncpy (pts_name, new_pts_name, len);
  pts_name[len - 1] = '\0';

  return (fdm);
}
Ejemplo n.º 6
0
static PyObject *
sgi__getpty(PyObject *self, PyObject *args)
{
	int oflag;
	int mode;
	int nofork;
	char *name;
	int fildes;
	if (!PyArg_Parse(args, "(iii)", &oflag, &mode, &nofork))
		return NULL;
	errno = 0;
	name = _getpty(&fildes, oflag, (mode_t)mode, nofork);
	if (name == NULL) {
		PyErr_SetFromErrno(PyExc_IOError);
		return NULL;
	}
	return Py_BuildValue("(si)", name, fildes);
}
Ejemplo n.º 7
0
Archivo: get_pty.c Proyecto: CVi/sudo
int
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
{
    char *line;

    /* IRIX-style dynamic ptys (may fork) */
    line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
    if (line == NULL)
	return 0;
    *slave = open(line, O_RDWR|O_NOCTTY, 0);
    if (*slave == -1) {
	close(*master);
	return 0;
    }
    (void) chown(line, ttyuid, -1);
    strlcpy(name, line, namesz);
    return 1;
}
Ejemplo n.º 8
0
    int
OpenPTY(char **ttyn)
{
    int f;
    char *name;
    RETSIGTYPE (*sigcld) SIGPROTOARG;

    /*
     * SIGCHLD set to SIG_DFL for _getpty() because it may fork() and
     * exec() /usr/adm/mkpts
     */
    sigcld = signal(SIGCHLD, SIG_DFL);
    name = _getpty(&f, O_RDWR | O_NONBLOCK | O_EXTRA, 0600, 0);
    signal(SIGCHLD, sigcld);

    if (name == 0)
	return -1;
    initmaster(f);
    *ttyn = name;
    return f;
}
Ejemplo n.º 9
0
Boolean ssh_pty_internal_allocate(int *ptyfd, int *ttyfd, char *namebuf)
{
  char *slave;

  slave = _getpty(ptyfd, O_RDWR, 0622, 0);
  if (slave == NULL)
    {
      ssh_warning("_getpty: %.100s", strerror(errno));
      return FALSE;
    }
  strcpy(namebuf, slave);
  /* Open the slave side. */
  *ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
  if (*ttyfd < 0)
    {
      ssh_warning("%.200s: %.100s", namebuf, strerror(errno));
      close(*ptyfd);
      return FALSE;
    }
  return TRUE;
}  
Ejemplo n.º 10
0
bool
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
{
    char *line;
    bool rval = false;
    debug_decl(get_pty, SUDO_DEBUG_PTY)

    /* IRIX-style dynamic ptys (may fork) */
    line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
    if (line != NULL) {
	*slave = open(line, O_RDWR|O_NOCTTY, 0);
	if (*slave != -1) {
	    (void) chown(line, ttyuid, -1);
	    strlcpy(name, line, namesz);
	    rval = true;
	} else {
	    close(*master);
	    *master = -1;
	}
    }
    debug_return_bool(rval);
}
Ejemplo n.º 11
0
int
openpty (int *amaster, int *aslave, char *name,
         struct termios const *termp, struct winsize const *winp)
{
  int master;
  char *slave_name;
  int slave;

# if HAVE__GETPTY /* IRIX */

  slave_name = _getpty (&master, O_RDWR, 0622, 0);
  if (slave_name == NULL)
    return -1;

# else /* AIX 5.1, HP-UX 11, Solaris 10, mingw */

#  if HAVE_POSIX_OPENPT /* Solaris 10 */

  master = posix_openpt (O_RDWR | O_NOCTTY);
  if (master < 0)
    return -1;

#  else /* AIX 5.1, HP-UX 11, Solaris 9, mingw */

#   ifdef _AIX /* AIX */

  master = open ("/dev/ptc", O_RDWR | O_NOCTTY);
  if (master < 0)
    return -1;

#   else /* HP-UX 11, Solaris 9, mingw */

  /* HP-UX, Solaris have /dev/ptmx.
     HP-UX also has /dev/ptym/clone, but this should not be needed.
     Linux also has /dev/ptmx, but Linux already has openpty().
     MacOS X also has /dev/ptmx, but MacOS X already has openpty().
     OSF/1 also has /dev/ptmx and /dev/ptmx_bsd, but OSF/1 already has
     openpty().  */
  master = open ("/dev/ptmx", O_RDWR | O_NOCTTY);
  if (master < 0)
    return -1;

#   endif

#  endif

  /* If all this does not work, we could try to open, one by one:
     - On MacOS X: /dev/pty[p-w][0-9a-f]
     - On *BSD:    /dev/pty[p-sP-S][0-9a-v]
     - On AIX:     /dev/ptyp[0-9a-f]
     - On HP-UX:   /dev/pty[p-r][0-9a-f]
     - On OSF/1:   /dev/pty[p-q][0-9a-f]
     - On Solaris: /dev/pty[p-r][0-9a-f]
   */
# endif

  /* This call does not require a dependency to the 'grantpt' module,
     because AIX, HP-UX, IRIX, Solaris all have the grantpt() function.  */
  if (grantpt (master))
    goto fail;

  /* This call does not require a dependency to the 'unlockpt' module,
     because AIX, HP-UX, IRIX, Solaris all have the unlockpt() function.  */
  if (unlockpt (master))
    goto fail;

# if !HAVE__GETPTY /* !IRIX */
  slave_name = ptsname (master);
  if (slave_name == NULL)
    goto fail;
# endif

  slave = open (slave_name, O_RDWR | O_NOCTTY);
  if (slave == -1)
    goto fail;

# if defined __sun || defined __hpux /* Solaris, HP-UX */
  if (ioctl (slave, I_PUSH, "ptem") < 0
      || ioctl (slave, I_PUSH, "ldterm") < 0
#  if defined __sun
      || ioctl (slave, I_PUSH, "ttcompat") < 0
#  endif
     )
    {
      close (slave);
      goto fail;
    }
# endif

  /* XXX Should we ignore errors here?  */
  if (termp)
    tcsetattr (slave, TCSAFLUSH, termp);
  if (winp)
    ioctl (slave, TIOCSWINSZ, winp);

  *amaster = master;
  *aslave = slave;
  if (name != NULL)
    strcpy (name, slave_name);

  return 0;

 fail:
  close (master);
  return -1;
}
Ejemplo n.º 12
0
bool KPty::open()
{
    Q_D(KPty);

    if (d->masterFd >= 0)
        return true;

    d->ownMaster = true;

    QByteArray ptyName;

    // Find a master pty that we can open ////////////////////////////////

    // Because not all the pty animals are created equal, they want to
    // be opened by several different methods.

    // We try, as we know them, one by one.

#ifdef HAVE_OPENPTY

    char ptsn[PATH_MAX];
    if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0)) {
        d->masterFd = -1;
        d->slaveFd = -1;
        qWarning(175) << "Can't open a pseudo teletype";
        return false;
    }
    d->ttyName = ptsn;

#else

#ifdef HAVE__GETPTY // irix

    char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
    if (ptsn) {
        d->ttyName = ptsn;
        goto grantedpt;
    }

#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)

#ifdef HAVE_POSIX_OPENPT
    d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
#elif defined(HAVE_GETPT)
    d->masterFd = ::getpt();
#elif defined(PTM_DEVICE)
    d->masterFd = ::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
#else
# error No method to open a PTY master detected.
#endif
    if (d->masterFd >= 0) {
#ifdef HAVE_PTSNAME
        char *ptsn = ptsname(d->masterFd);
        if (ptsn) {
            d->ttyName = ptsn;
#else
    int ptyno;
    if (!ioctl(d->masterFd, TIOCGPTN, &ptyno)) {
        d->ttyName = QByteArray("/dev/pts/") + QByteArray::number(ptyno);
#endif
#ifdef HAVE_GRANTPT
            if (!grantpt(d->masterFd)) {
                goto grantedpt;
            }
#else

    goto gotpty;
#endif
        }
        ::close(d->masterFd);
        d->masterFd = -1;
    }
#endif // HAVE_PTSNAME || TIOCGPTN

    // Linux device names, FIXME: Trouble on other systems?
    for (const char * s3 = "pqrstuvwxyzabcde"; *s3; s3++) {
        for (const char * s4 = "0123456789abcdef"; *s4; s4++) {
            ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toLatin1();
            d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toLatin1();

            d->masterFd = ::open(ptyName.data(), O_RDWR);
            if (d->masterFd >= 0) {
#ifdef Q_OS_SOLARIS
                /* Need to check the process group of the pty.
                 * If it exists, then the slave pty is in use,
                 * and we need to get another one.
                 */
                int pgrp_rtn;
                if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
                    ::close(d->masterFd);
                    d->masterFd = -1;
                    continue;
                }
#endif /* Q_OS_SOLARIS */
                if (!access(d->ttyName.data(),R_OK|W_OK)) { // checks availability based on permission bits
                    if (!geteuid()) {
                        struct group * p = getgrnam(TTY_GROUP);
                        if (!p) {
                            p = getgrnam("wheel");
                        }
                        gid_t gid = p ? p->gr_gid : getgid ();

                        if (!chown(d->ttyName.data(), getuid(), gid)) {
                            chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
                        }
                    }
                    goto gotpty;
                }
                ::close(d->masterFd);
                d->masterFd = -1;
            }
        }
    }

    qWarning() << "Can't open a pseudo teletype";
    return false;

gotpty:
    struct stat st;
    if (stat(d->ttyName.data(), &st)) {
        return false; // this just cannot happen ... *cough*  Yeah right, I just
        // had it happen when pty #349 was allocated.  I guess
        // there was some sort of leak?  I only had a few open.
    }
    if (((st.st_uid != getuid()) ||
            (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
            !d->chownpty(true)) {
        qWarning()
        << "chownpty failed for device " << ptyName << "::" << d->ttyName
        << "\nThis means the communication can be eavesdropped." << endl;
    }

#if defined (HAVE__GETPTY) || defined (HAVE_GRANTPT)
grantedpt:
#endif

#ifdef HAVE_REVOKE
    revoke(d->ttyName.data());
#endif

#ifdef HAVE_UNLOCKPT
    unlockpt(d->masterFd);
#elif defined(TIOCSPTLCK)
    int flag = 0;
    ioctl(d->masterFd, TIOCSPTLCK, &flag);
#endif

    d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
    if (d->slaveFd < 0) {
        qWarning() << "Can't open slave pseudo teletype";
        ::close(d->masterFd);
        d->masterFd = -1;
        return false;
    }

#if (defined(__svr4__) || defined(__sgi__))
    // Solaris
    ioctl(d->slaveFd, I_PUSH, "ptem");
    ioctl(d->slaveFd, I_PUSH, "ldterm");
#endif

#endif /* HAVE_OPENPTY */

    fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
    fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);

    return true;
}

bool KPty::open(int fd)
{
#if !defined(HAVE_PTSNAME) && !defined(TIOCGPTN)
     qWarning() << "Unsupported attempt to open pty with fd" << fd;
     return false;
#else
    Q_D(KPty);

    if (d->masterFd >= 0) {
        qWarning() << "Attempting to open an already open pty";
         return false;
    }

    d->ownMaster = false;

# ifdef HAVE_PTSNAME
    char *ptsn = ptsname(fd);
    if (ptsn) {
        d->ttyName = ptsn;
# else
    int ptyno;
    if (!ioctl(fd, TIOCGPTN, &ptyno)) {
        char buf[32];
        sprintf(buf, "/dev/pts/%d", ptyno);
        d->ttyName = buf;
# endif
    } else {
        qWarning() << "Failed to determine pty slave device for fd" << fd;
        return false;
    }

    d->masterFd = fd;
    if (!openSlave()) {

        d->masterFd = -1;
        return false;
    }

    return true;
#endif
}

void KPty::closeSlave()
{
    Q_D(KPty);

    if (d->slaveFd < 0) {
        return;
    }
    ::close(d->slaveFd);
    d->slaveFd = -1;
}
Ejemplo n.º 13
0
static UInt GetMasterPty ( int *pty, Char *nametty, Char *namepty )
{
#if HAVE_POSIX_OPENPT && HAVE_PTSNAME
    /* Attempt to use POSIX 98 pseudo ttys. Opening a master tty is done
       via posix_openpt, which is available on virtually every current
       UNIX system; indeed, according to gnulib, it is available on at
       least the following systems:
         - glibc >= 2.2.1 (released January 2001; but is a stub on GNU/Hurd),
         - Mac OS X >= 10.4 (released April 2005),
         - FreeBSD >= 5.1 (released June 2003),
         - NetBSD >= 3.0 (released December 2005),
         - AIX >= 5.2 (released October 2002),
         - HP-UX >= 11.31 (released February 2007),
         - Solaris >= 10 (released January 2005),
         - Cygwin >= 1.7 (released December 2009).
       Systems lacking posix_openpt (in addition to older versions of
       the systems listed above) include:
         - OpenBSD
         - Minix 3.1.8
         - IRIX 6.5
         - OSF/1 5.1
         - mingw
         - MSVC 9
         - Interix 3.5
         - BeOS
       */
    *pty = posix_openpt( O_RDWR | O_NOCTTY );
    if (*pty > 0) {
        if (grantpt(*pty) || unlockpt(*pty)) {
            close(*pty);
            return 1;
        }
        strxcpy(nametty, ptsname(*pty), 32);
        return 0;
    }
    return 1;

#elif HAVE_GETPT && HAVE_PTSNAME_R
    /* Attempt to use glibc specific APIs, for compatibility with older
       glibc versions (before 2.2.1, release January 2001). */
    *pty = getpt();
    if (*pty > 0) {
        if (grantpt(*pty) || unlockpt(*pty)) {
            close(*pty);
            return 1;
        }
        ptsname_r(*pty, nametty, 32); 
        return 0;
    }
    return 1;

#elif HAVE_PTSNAME
    /* Attempt to use Sys V pseudo ttys on systems that don't have posix_openpt,
       getpt or openpty, but do have ptsname.
       Platforms *missing* ptsname include:
       Mac OS X 10.3, OpenBSD 3.8, Minix 3.1.8, mingw, MSVC 9, BeOS. */
    *pty = open( "/dev/ptmx", O_RDWR );
    if ( *pty < 0 )
        return 1;
    strxcpy(nametty, ptsname(*pty), 32);
    return 0;

#elif HAVE_GETPSEUDOTTY
    /* TODO: From which system(s) does getpseudotty originate? */
    *pty = getpseudotty( nametty, namepty );
    return *pty < 0 ? 1 : 0;

#elif HAVE__GETPTY
    /* Available on SGI IRIX >= 4.0 (released September 1991).
       See also http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?cmd=getdoc&coll=0530&db=man&fname=7%20pty */
    char  * line;
    line = _getpty(pty, O_RDWR|O_NDELAY, 0600, 0) ;
    if (0 == line)
        return 1;
    strcpy( nametty, line );
    return 0;

#else
    /* fallback to old-style BSD pseudoterminals, doing a brute force
       search over all pty device files. */
    int devindex;
    int letter;
    int ttylen, ptylen;

    ttylen = strlen(nametty);
    ptylen = strlen(namepty);

    for ( letter = 0; SYS_PTYCHAR1[letter]; ++letter ) {
        nametty[ttylen-2] = SYS_PTYCHAR1[letter];
        namepty[ptylen-2] = SYS_PTYCHAR1[letter];

        for ( devindex = 0; SYS_PTYCHAR2[devindex]; ++devindex ) {
            nametty[ttylen-1] = SYS_PTYCHAR2[devindex];
            namepty[ptylen-1] = SYS_PTYCHAR2[devindex];
                    
            *pty = open( namepty, O_RDWR );
            if ( *pty >= 0 ) {
                int slave = open( nametty, O_RDWR );
                if ( slave >= 0 ) {
                    close(slave);
                    return 0;
                }
                close(*pty);
            } 
        }
    }
    return 1;
#endif
}
Ejemplo n.º 14
0
serial_init()
#endif
{
  char *p;
  int   c;
  int   n;
  char  tty_dev_name[128];
  struct termios ttybuf;

  wire_fd = -1;
  ttyp = -1;
  if (useTerminal)
    {
#if defined(IRIX)
      if ((p = _getpty(&wire_fd, O_RDWR | O_EXCL | O_NDELAY, 0666, 0)) == NULL)
        {
          wire_fd = -1;
          ttyp = -1;
        }
      else
        {
          if ((ttyp = open(p, O_RDWR | O_NDELAY, 0666)) < 0)
            {
              close(wire_fd);
              wire_fd = -1;
              ttyp = -1;
            }
          else
            {
              if (verbose)
                printf("%s: wire connection on %s\n", progname, p);
              wire_name = strdup(p);
            }
        }
#elif defined(SOLARIS)
      if ((wire_fd = open("/dev/ptmx", O_RDWR | O_NONBLOCK, 0666)) >= 0)
        {
          grantpt(wire_fd);
          unlockpt(wire_fd);
          p = ptsname(wire_fd);
          strcpy(tty_dev_name, p);
          if ((ttyp = open(tty_dev_name, O_RDWR | O_NDELAY, 0666)) >= 0)
            {
              ioctl(ttyp, I_PUSH, "ptem");
              ioctl(ttyp, I_PUSH, "ldterm");
              if (verbose)
                printf("%s: wire connection on %s\n", progname,
                      tty_dev_name);
              wire_name = strdup(tty_dev_name);
            }
        }
#elif defined(LINUX)
      /* Unix98 PTY (Preferred) */
      if ((wire_fd = open("/dev/ptmx", O_RDWR | O_NONBLOCK, 0666)) >= 0)
        {
          grantpt(wire_fd);
          unlockpt(wire_fd);
          p = ptsname(wire_fd);
          strcpy(tty_dev_name, p);
          if ((ttyp = open(tty_dev_name, O_RDWR | O_NDELAY, 0666)) >= 0)
            {
              if (verbose)
                printf("%s: wire connection on %s\n", progname,
                      tty_dev_name);
              wire_name = strdup(tty_dev_name);
            }
        }
      /* BSD PTY (Legacy) */
      else
	{
          c = 'p';
          do
            {
              for (n = 0; n < 16; n++)
                {
                  sprintf(tty_dev_name, "/dev/pty%c%x", c, n);
                  if ((wire_fd = open(tty_dev_name,
                                      O_RDWR | O_EXCL | O_NDELAY, 0666)) >= 0)
                    {
                      ttyp = wire_fd;
                      sprintf(tty_dev_name, "/dev/tty%c%x", c, n);
                      if (verbose)
                        printf("%s: wire connection on %s\n", progname,
                               tty_dev_name);
                      wire_name = strdup(tty_dev_name);
                      break;
                    }
                }
              c++;
            }
          while ((wire_fd < 0) && (errno != ENOENT));
	}
#else
      /*
       * Here we go for SUNOS, HPUX
       */
      c = 'p';
      do
        {
          for (n = 0; n < 16; n++)
            {
              sprintf(tty_dev_name, "/dev/ptyp%x", n);
              if ((wire_fd = open(tty_dev_name,
                                  O_RDWR | O_EXCL | O_NDELAY, 0666)) >= 0)
                {
                  sprintf(tty_dev_name, "/dev/tty%c%x", c, n);
                  if ((ttyp = open(tty_dev_name, O_RDWR | O_NDELAY, 0666)) < 0)
                    {
                      wire_fd = -1;
                      ttyp = -1;
                    }
                  else
                    {
                      if (verbose)
                        printf("%s: wire connection on %s\n", progname,
                               tty_dev_name);
                      wire_name = strdup(tty_dev_name);
                      break;
                    }
                }
            }
          c++;
        }
      while ((wire_fd < 0) && (errno != ENOENT));
#endif
    }

  if (ttyp >= 0)
    {
#if defined(TCSANOW)
      if (tcgetattr(ttyp, &ttybuf) < 0)
#else
      if (ioctl(ttyp, TCGETS, (char *)&ttybuf) < 0)
#endif
        {
          if (!quiet)
            fprintf(stderr, "%s: ioctl(wire, TCGETS) failed, errno = %d\n",
                    progname, errno);
          wire_fd = -1;
          ttyp = -1;
        }
    }

  ttybuf.c_lflag = 0;
  ttybuf.c_iflag = 0;
  ttybuf.c_oflag = 0;
  ttybuf.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
  for (n = 0; n < NCCS; n++)
    ttybuf.c_cc[n] = 0;
  ttybuf.c_cc[VTIME] = 0;
  ttybuf.c_cc[VMIN] = 1;

  if (ttyp >= 0)
    {
#if defined(TCSANOW)
      if (tcsetattr(ttyp, TCSANOW, &ttybuf) < 0)
#else
      if (ioctl(ttyp, TCSETS, (char *)&ttybuf) < 0)
#endif
        {
          if (!quiet)
            fprintf(stderr, "%s: ioctl(wire, TCSETS) failed, errno = %d\n",
                    progname, errno);
          wire_fd = -1;
          ttyp = -1;
        }
    }

  ir_fd = -1;
  if (useSerial)
    {
      sprintf(tty_dev_name, serialLine);
      if ((ir_fd = open(tty_dev_name, O_RDWR | O_NDELAY)) >= 0)
        {
          if (verbose)
            printf("%s: IR connection on %s\n", progname, tty_dev_name);
          ir_name = strdup(tty_dev_name);
	}
    }

  if (ir_fd >= 0)
    {
#if defined(TCSANOW)
      if (tcgetattr(ir_fd, &ttybuf) < 0)
#else
      if (ioctl(ir_fd, TCGETS, (char *)&ttybuf) < 0)
#endif
        {
          if (!quiet)
            fprintf(stderr, "%s: ioctl(IR, TCGETS) failed, errno = %d\n",
                    progname, errno);
          ir_fd = -1;
        }
    }

  ttybuf.c_lflag = 0;
  ttybuf.c_iflag = 0;
  ttybuf.c_oflag = 0;
  ttybuf.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
  for (n = 0; n < NCCS; n++)
    ttybuf.c_cc[n] = 0;
  ttybuf.c_cc[VTIME] = 0;
  ttybuf.c_cc[VMIN] = 1;

  if (ir_fd >= 0)
    {
#if defined(TCSANOW)
      if (tcsetattr(ir_fd, TCSANOW, &ttybuf) < 0)
#else
      if (ioctl(ir_fd, TCSETS, (char *)&ttybuf) < 0)
#endif
        {
          if (!quiet)
            fprintf(stderr, "%s: ioctl(IR, TCSETS) failed, errno = %d\n",
                    progname, errno);
          ir_fd = -1;
        }
    }
  update_connection_display();
  return 1;
}
Ejemplo n.º 15
0
int PTY::getpt()
{

#if defined(HAVE_GETPT) && defined(HAVE_PTSNAME)

    // 1: UNIX98: preferred way
    ptyfd = ::getpt();
    ttyname = ::ptsname(ptyfd);
    return ptyfd;

#elif defined(HAVE_OPENPTY)
    // 2: BSD interface
    // More preferred than the linux hacks
    char name[30];
    int master_fd, slave_fd;
    if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1)  {
	ttyname = name;
	name[5]='p';
	ptyname = name;
        close(slave_fd); // We don't need this yet // Yes, we do.
	ptyfd = master_fd;
	return ptyfd;
    }
    ptyfd = -1;
    kdDebug(900) << k_lineinfo << "Opening pty failed.\n";
    return -1;

#elif defined(HAVE__GETPTY)
    // 3: Irix interface
    int master_fd;
    ttyname = _getpty(&master_fd,O_RDWR,0600,0);
    if (ttyname)
	ptyfd = master_fd;
    else{
	ptyfd = -1;
	kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n';
    }
    return ptyfd;

#else

    // 4: Open terminal device directly
    // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris)

    ptyfd = open("/dev/ptmx", O_RDWR);
    if (ptyfd >= 0) {
	ptyname = "/dev/ptmx";
#ifdef HAVE_PTSNAME
	ttyname = ::ptsname(ptyfd);
	return ptyfd;
#elif defined (TIOCGPTN)
	int ptyno;
	if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) {
	    ttyname.sprintf("/dev/pts/%d", ptyno);
	    return ptyfd;
	}
#endif
	close(ptyfd);
    }

    // 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's)

    for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++)
    {
	for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++)
	{
	    ptyname.sprintf("/dev/pty%c%c", *c1, *c2);
	    ttyname.sprintf("/dev/tty%c%c", *c1, *c2);
	    if (access(ptyname, F_OK) < 0)
		goto linux_out;
	    ptyfd = open(ptyname, O_RDWR);
	    if (ptyfd >= 0)
		return ptyfd;
	}
    }
linux_out:

    // 4.3: Try /dev/pty%d (SCO, Unixware)

    for (int i=0; i<256; i++)
    {
	ptyname.sprintf("/dev/ptyp%d", i);
	ttyname.sprintf("/dev/ttyp%d", i);
	if (access(ptyname, F_OK) < 0)
	    break;
	ptyfd = open(ptyname, O_RDWR);
	if (ptyfd >= 0)
	    return ptyfd;
    }


    // Other systems ??
    ptyfd = -1;
    kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n";
    return -1;

#endif // HAVE_GETPT && HAVE_PTSNAME

}
Ejemplo n.º 16
0
void runshell_pty( int rd_pipe, int wr_pipe )
{
	/*
	char r_banner[17];
	r_banner[0] = 'r'; r_banner[ 8] = '.';
	r_banner[1] = 'o'; r_banner[ 9] = '3';
	r_banner[2] = 'o'; r_banner[10] = ' ';
	r_banner[3] = 't'; r_banner[11] = 'r';
	r_banner[4] = 'm'; r_banner[12] = 'e';
	r_banner[5] = 'e'; r_banner[13] = 'a';
	r_banner[6] = '-'; r_banner[14] = 'd';
	r_banner[7] = '0'; r_banner[15] = 'y';

	write( wr_pipe, r_banner, 16 );
	*/

    fd_set rfds;
    struct winsize ws;
    int pid, pty, tty, n;
    char *slave, *temp;
    char buffer[4096];

    /* request a pseudo-terminal */

#if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF

    if( openpty( &pty, &tty, NULL, NULL, NULL ) < 0 )
	{
        return;
	}

    if( ! ( slave = ttyname( tty ) ) )
	{
        return;
	}

#else
#if defined IRIX

    if( ! ( slave = _getpty( &pty, O_RDWR, 0622, 0 ) ) )
	{
        return;
	}

    if( ( tty = open( slave, O_RDWR | O_NOCTTY ) ) < 0 )
	{
        return;
	}

#else
#if defined CYGWIN || defined SUNOS || defined HPUX

    if( ( pty = open( "/dev/ptmx", O_RDWR | O_NOCTTY ) ) < 0 )
	{
        return;
	}

    if( grantpt( pty ) < 0 )
	{
        return;
	}

    if( unlockpt( pty ) < 0 )
	{
        return;
	}

    if( ! ( slave = ptsname( pty ) ) )
	{
        return;
	}

    if( ( tty = open( slave, O_RDWR | O_NOCTTY ) ) < 0 )
	{
        return;
	}

#if defined SUNOS || defined HPUX

    if( ioctl( tty, I_PUSH, "ptem" ) < 0 )
        return;

    if( ioctl( tty, I_PUSH, "ldterm" ) < 0 )
        return;

#if defined SUNOS

    if( ioctl( tty, I_PUSH, "ttcompat" ) < 0 )
        return;

#endif
#endif
#endif
#endif
#endif

    /* get the window size and TERM variable */

    memset( buffer, 0, sizeof( buffer ) );

    if( ( n = read( rd_pipe, buffer, 64 ) ) != 64 )
	{
        return;
	}

    ws.ws_row = ( (int) buffer[0] << 8 ) + (int) buffer[1];
    ws.ws_col = ( (int) buffer[2] << 8 ) + (int) buffer[3];

    ws.ws_xpixel = 0;
    ws.ws_ypixel = 0;

    if( ioctl( pty, TIOCSWINSZ, &ws ) < 0 )
	{
        return;
	}

    if( ! ( temp = (char *) malloc( 66 ) ) )
        return;

    temp[0] = 'T'; temp[3] = 'M';
    temp[1] = 'E'; temp[4] = '=';
    temp[2] = 'R';

    strncpy( temp + 5, buffer + 4, 61 );

    putenv( temp );

    /* fork to spawn a shell */

    if( ( pid = fork() ) < 0 )
	{
        return;
	}

    if( ! pid )
    {
        close( pty );

        if( setsid() < 0 )
            return;

        /* set controlling tty, to have job control */

#if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF

        if( ioctl( tty, TIOCSCTTY, NULL ) < 0 )
            return;

#else
#if defined CYGWIN || defined SUNOS || defined IRIX || defined HPUX

        {
            int fd = open( slave, O_RDWR );
            if( fd < 0 ) return;
            close( tty );
            tty = fd;
        }

#endif
#endif

        /* tty becomes stdin, stdout, stderr */

        dup2( tty, 0 );
        dup2( tty, 1 );
        dup2( tty, 2 );

        if( tty > 2 ) close( tty );

        /* just in case bash is run, kill the history file */

        if( ! ( temp = (char *) malloc( 10 ) ) )
            return;

        temp[0] = 'H'; temp[5] = 'I';
        temp[1] = 'I'; temp[6] = 'L';
        temp[2] = 'S'; temp[7] = 'E';
        temp[3] = 'T'; temp[8] = '=';
        temp[4] = 'F'; temp[9] = '\0';

        putenv( temp );

        /* set HOME to "/var/tmp" */

        if( ! ( temp = (char *) malloc( 14 ) ) )
            return;

        temp[0] = 'H'; temp[ 7] = 'a';
        temp[1] = 'O'; temp[ 8] = 'r';
        temp[2] = 'M'; temp[ 9] = '/';
        temp[3] = 'E'; temp[10] = 't';
        temp[4] = '='; temp[11] = 'm';
        temp[5] = '/'; temp[12] = 'p';
        temp[6] = 'v'; temp[13] = '\0';

        putenv( temp );
        chdir( temp + 5 );

        /* fire up the shell */

        buffer[0] = 'b'; buffer[2] = 's';
        buffer[1] = 'a'; buffer[3] = 'h';
        buffer[4] = '\0';
        execlp( buffer, HIDE_SHELL, (char *) 0 );

        buffer[0] = '/'; buffer[4] = '/';
        buffer[1] = 'b'; buffer[5] = 's';
        buffer[2] = 'i'; buffer[6] = 'h';
        buffer[3] = 'n'; buffer[7] = '\0';
        execlp( buffer, HIDE_SHELL, (char *) 0 );

        return;
    }

    /* tty (slave side) not needed anymore */

    close( tty );

    /* let's forward the data back and forth */

    while( 1 )
    {
        FD_ZERO( &rfds );
        FD_SET( rd_pipe, &rfds );
        FD_SET( pty, &rfds );

        n = ( pty > rd_pipe ) ? pty : rd_pipe;

        if( select( n + 1, &rfds, NULL, NULL, NULL ) < 0 )
            break;

        if( FD_ISSET( rd_pipe, &rfds ) )
        {
            n = read( rd_pipe, buffer, sizeof( buffer ) );

            if( n <= 0 ) break;

            if( write( pty, buffer, n ) != n )
                break;
        }

        if( FD_ISSET( pty, &rfds ) )
        {
            n = read( pty, buffer, sizeof( buffer ) );

            if( n <= 0 ) break;

            if( write( wr_pipe, buffer, n ) != n )
                break;
        }
    }
	kill(pid, 9);

	int status;
	wait(&status);

    return;
}
Ejemplo n.º 17
0
long
ptyint_getpty_ext(int *fd, char *slave, size_t slavelength, int do_grantpt)
{
#if !defined(HAVE__GETPTY) && !defined(HAVE_OPENPTY)
    char *cp;
    char *p;
    int i,ptynum;
    struct stat stb;
    char slavebuf[1024];
#endif

#ifdef HAVE__GETPTY
    char *slaveret; /*Temporary to hold pointer to slave*/
#endif /*HAVE__GETPTY*/

#ifdef HAVE_OPENPTY
    int slavefd;

    if(openpty(fd, &slavefd, slave, (struct termios *) 0,
         (struct winsize *) 0)) return 1;
    close(slavefd);
    return 0;
#else /*HAVE_OPENPTY*/
#ifdef HAVE__GETPTY
    /* This code is included for Irix; as of version 5.3, Irix has /dev/ptmx,
     * but it fails to work properly; even after calling unlockpt,
     * root gets permission denied opening the pty.
     * The code to support _getpty should be removed if Irix gets working
     * streams ptys in favor of maintaining the least needed code
     * paths.
     */
    if ((slaveret = _getpty(fd, O_RDWR|O_NDELAY, 0600, 0)) == 0) {
	*fd = -1;
	return PTY_GETPTY_NOPTY;
    }
    if (strlcpy(slave, slaveret, slavelength) >= slavelength) {
	close(*fd);
	*fd = -1;
	return PTY_GETPTY_SLAVE_TOOLONG;
    }
    return 0;
#else /*HAVE__GETPTY*/
    
    *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY);	/* HPUX*/
#ifdef HAVE_STREAMS
    if (*fd < 0) *fd = open("/dev/ptmx",O_RDWR|O_NDELAY); /*Solaris*/
#endif
    if (*fd < 0) *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */
    if (*fd < 0) *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */

    if (*fd >= 0) {

#if defined(HAVE_GRANTPT)&&defined(HAVE_STREAMS)
	if (do_grantpt)
	    if (grantpt(*fd) || unlockpt(*fd)) return PTY_GETPTY_STREAMS;
#endif
    
#ifdef HAVE_PTSNAME
	p = ptsname(*fd);
#else
#ifdef	HAVE_TTYNAME
	p = ttyname(*fd);
#else
	/* XXX If we don't have either what do we do */
#endif
#endif
	if (p) {
	    if (strlcpy(slave, p, slavelength) >= slavelength) {
		    close (*fd);
		    *fd = -1;
		    return PTY_GETPTY_SLAVE_TOOLONG;
	    }
	    return 0;
	}

	if (fstat(*fd, &stb) < 0) {
	    close(*fd);
	    return PTY_GETPTY_FSTAT;
	}
	ptynum = (int)(stb.st_rdev&0xFF);
	snprintf(slavebuf, sizeof(slavebuf), "/dev/ttyp%x", ptynum);
	if (strlen(slavebuf) + 1 > slavelength) {
	    close(*fd);
	    *fd = -1;
	    return PTY_GETPTY_SLAVE_TOOLONG;
	}
	strncpy(slave, slavebuf, slavelength);
	return 0;
    } else {
    	for (cp = "pqrstuvwxyzPQRST";*cp; cp++) {
	    snprintf(slavebuf,sizeof(slavebuf),"/dev/ptyXX");
	    slavebuf[sizeof("/dev/pty") - 1] = *cp;
	    slavebuf[sizeof("/dev/ptyp") - 1] = '0';
	    if (stat(slavebuf, &stb) < 0)
		break;
	    for (i = 0; i < 16; i++) {
		slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i];
		*fd = open(slavebuf, O_RDWR);
		if (*fd < 0) continue;

		/* got pty */
		slavebuf[sizeof("/dev/") - 1] = 't';
		if (strlen(slavebuf) + 1 > slavelength) {
		    close(*fd);
		    *fd = -1;
		    return PTY_GETPTY_SLAVE_TOOLONG;
		}
		strncpy(slave, slavebuf, slavelength);
		return 0;
	    }
	}
	return PTY_GETPTY_NOPTY;
    }
#endif /*HAVE__GETPTY*/
#endif /* HAVE_OPENPTY */
}
Ejemplo n.º 18
0
int get_pty_and_fork(int *fd_master, int *fd_slave)
{
#if defined(__FreeBSD__) || defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__GNU__) || defined(__GLIBC__) || defined(__minix)

	if (openpty(fd_master, fd_slave, NULL, NULL, NULL) == -1)
	{
		error_exit(TRUE, FALSE, "openpty() failed.\n");
		return -1;
	}

	return fork();

#elif defined(sun) || defined(__sun) || defined(AIX) || defined(_HPUX_SOURCE) || defined(OSF1) || defined(scoos)

	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 */
	int ptm;
	char *pts;
	pid_t pid;
#if defined(AIX)
	char *multiplexer = "/dev/ptc";
#else
	char *multiplexer = "/dev/ptmx";
#endif

	ptm = myopen(multiplexer, O_RDWR | O_NOCTTY);
	if (ptm < 0) {
		error_exit(TRUE, FALSE, "Error opening %s.\n", multiplexer);
		return -1;
	}
	*fd_master = ptm;

	pid = fork();
	if (pid == 0)
	{
		if (grantpt(ptm) < 0) error_exit(TRUE, FALSE, "grantpt() failed.\n");
		if (unlockpt(ptm) < 0) error_exit(TRUE, FALSE, "unlockpt() failed.\n");
		setsid(); /* lose old controlling terminal (FvH) */
		pts = ptsname(ptm);
		if (pts == NULL) error_exit(TRUE, FALSE, "Slave pty side name could not be obtained.\n");

		/* Open the slave side. */
		*fd_slave = myopen(pts, O_RDWR | O_NOCTTY);
		if (*fd_slave < 0) error_exit(TRUE, FALSE, "Problem opening slave-side of pseudo tty (file '%s').\n", pts);

#if !defined(AIX) && !defined(scoos)
		/* Push the appropriate streams modules, as described in Solaris pts(7). */
		if (ioctl(*fd_slave, I_PUSH, "ptem") < 0) error_exit(TRUE, FALSE, "ioctl I_PUSH ptem failed.\n");
		if (ioctl(*fd_slave, I_PUSH, "ldterm") < 0) error_exit(TRUE, FALSE, "ioctl I_PUSH ldterm failed.\n");
		(void)ioctl(*fd_slave, I_PUSH, "ttcompat"); /* not on HP-UX? */
#endif
	}

	return pid;

#elif defined(IRIX) || defined(IRIX64)

	char *line = _getpty(fd_master, O_RDWR | O_NDELAY, 0600, 0);
	if (line == NULL) error_exit(TRUE, FALSE, "_getpy() failed.\n");

	*fd_slave = myopen(line, O_RDWR);
	if (*fd_slave < 0) error_exit(TRUE, FALSE, "Error while openening file %s.\n", line);

	return fork();

#else

#error I'm sorry, but I don't know what kind of system this is.
#error Because of that I do not know how to do openpty() on your
#error system. Please contact me at [email protected] and
#error tell me what kind of system you have and please give me
#error the output of
#error man openpty
#error strings `which gcc`
#error strings `which cc`
#error ls -lR /usr/include
#error Thank you in advance and sorry for all the hassle!

#endif
}
Ejemplo n.º 19
0
Archivo: tty.c Proyecto: Distrotech/joe
static unsigned char *getpty(int *ptyfd)
{
	return (unsigned char *)_getpty(ptyfd, O_RDWR, 0600, 0);
}
Ejemplo n.º 20
0
Archivo: lftp_pty.c Proyecto: bpaf/lftp
const char *open_pty(int *ptyfd, int *ttyfd)
{
   const char *name=0;
   void *old_sigchld=signal(SIGCHLD,SIG_DFL);
   *ptyfd=*ttyfd=-1;

#if defined(HAVE_OPENPTY) || defined(BSD4_4)
   /* openpty(3) exists in OSF/1 and some other os'es */
   openpty(ptyfd, ttyfd, NULL, NULL, NULL);
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY
   /*
    * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
    * pty's automagically when needed
    */
   name=_getpty(ptyfd,O_RDWR|O_NOCTTY,0600,0);
#else /* HAVE__GETPTY */
#if defined(HAVE_DEV_PTMX)
   /*
    * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
    * also has bsd-style ptys, but they simply do not work.)
    */
   *ptyfd=open("/dev/ptmx",O_RDWR|O_NOCTTY);
   if(*ptyfd<0)
      goto fail;
   if(grantpt(*ptyfd)<0)
      goto fail;
   if(unlockpt(*ptyfd)<0)
      goto fail;
   name=ptsname(*ptyfd);
#else /* HAVE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC
{
   /* AIX-style pty code. */
   *ptyfd=open("/dev/ptc",O_RDWR|O_NOCTTY);
   if(*ptyfd<0)
      goto fail;
   name=ttyname(*ptyfd);
}
#else /* HAVE_DEV_PTS_AND_PTC */
{
   /* BSD-style pty code. */
   char master[64];
   static char slave[64];
   int i;
   const char *ptymajors="pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
   const char *ptyminors="0123456789abcdef";
   int num_minors=strlen(ptyminors);
   int num_ptys=strlen(ptymajors)*num_minors;

   for(i=0; i<num_ptys; i++)
   {
      sprintf(master,"/dev/pty%c%c",ptymajors[i/num_minors],ptyminors[i%num_minors]);
      sprintf(slave, "/dev/tty%c%c",ptymajors[i/num_minors],ptyminors[i%num_minors]);
      *ptyfd=open(master,O_RDWR|O_NOCTTY);
      if(*ptyfd>=0)
	 break;
      /* Try SCO style naming */
      sprintf(master,"/dev/ptyp%d",i);
      sprintf(slave, "/dev/ttyp%d",i);
      *ptyfd=open(master,O_RDWR|O_NOCTTY);
      if(*ptyfd>=0)
	 break;
   }
   name=slave;
}
#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* HAVE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */

   if(*ptyfd<0)
      goto fail;
   if(name && *ttyfd<0)
      *ttyfd=open(name,O_RDWR|O_NOCTTY);
   if(!name && *ttyfd>=0)
      name=ttyname(*ttyfd);

   if(!name || *ttyfd<0)
      goto fail;

#if defined(HAVE_DEV_PTMX) && defined(I_PUSH) \
 && !defined(HAVE__GETPTY) && !defined(HAVE_OPENPTY)
   ioctl(*ttyfd, I_PUSH, "ptem");
   ioctl(*ttyfd, I_PUSH, "ldterm");
   ioctl(*ttyfd, I_PUSH, "ttcompat");
#endif
#ifdef HAVE_FCHMOD
   fchmod(*ttyfd,0600);
#else
   chmod(name,0600);
#endif
   signal(SIGCHLD,old_sigchld);
   return name;

fail:
   if(*ttyfd>=0)
      close(*ttyfd);
   if(*ptyfd>=0)
      close(*ptyfd);
   signal(SIGCHLD,old_sigchld);
   return 0;
}
Ejemplo n.º 21
0
int main ()
{
  int fd ;
  char *name = _getpty(&fd, O_RDWR, 0600, 0) ;
  return 0 ;
}
Ejemplo n.º 22
0
/* pty_open: A safe version of openpty. 
 * Allocates and opens a pseudo terminal. The new descriptor for the 
 * master side of the pseudo terminal is stored in masterfd. The new 
 * descriptor for the slave side of the pseudo terminal is stored in slavefd. 
 * The device name of the slave side of the pseudo terminal is stored in the 
 * buffer pointed to by slavename which must be able to hold at least 64 
 * characters. slavenamesize is the size of the buffer pointed to by 
 * slavename. No more than slavenamesize bytes will be written into the 
 * buffer pointed to by slavename, including the terminating nul byte. 
 * If slave_termios is not null, it is passed to tcsetattr with the 
 * command TCSANOW to set the terminal attributes of the slave device. 
 * If slave_winsize is not null, it is passed to ioctl with the command 
 * TIOCSWINSZ to set the window size of the slave device. On success, 
 * returns 0. On error, returns -1 with errno set appropriately.
 */
int pty_open(int *masterfd, int *slavefd, char *slavename, size_t slavenamesize,
        const struct termios *slave_termios,
        const struct winsize *slave_winsize)
{
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
    /* openpty(3) exists in OSF/1 and some other os'es */

#ifdef HAVE_TTYNAME_R
    char buf[64], *name = buf;
    int err;
#else
    char *name;
#endif

    if (!masterfd || !slavefd || !slavename || slavenamesize < 64)
        return set_errno(EINVAL);

    /* Open the master and slave descriptors, set ownership and permissions */

    if (openpty(masterfd, slavefd, NULL, NULL, NULL) == -1)
        return -1;

    /* Retrieve the device name of the slave */

#ifdef HAVE_TTYNAME_R
    if ((err = ttyname_r(*slavefd, buf, 64))) {
        close(*masterfd);
        close(*slavefd);
        return set_errno(err);
    }
#else
    if (!(name = ttyname(*slavefd))) {
        close(*masterfd);
        close(*slavefd);
        return set_errno(ENOTTY);
    }
#endif

    /* Return it to the caller */

    if (strlcpy_local(slavename, name, slavenamesize) >= slavenamesize) {
        close(*masterfd);
        close(*slavefd);
        return set_errno(ENOSPC);
    }
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY

    /*
     * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
     * pty's automagically when needed
     */

    char *slave;

    if (!masterfd || !slavefd || !slavename || slavenamesize < 64)
        return set_errno(EINVAL);

    /* Open the master descriptor and get the slave's device name */

    if (!(slave = _getpty(masterfd, O_RDWR, 0622, 0)))
        return -1;

    /* Return it to the caller */

    if (strlcpy_local(slavename, name, slavenamesize) >= slavenamesize) {
        close(*masterfd);
        return set_errno(ENOSPC);
    }

    /* Open the slave descriptor */

    if ((*slavefd = open(slavename, O_RDWR | O_NOCTTY)) == -1) {
        close(*masterfd);
        return -1;
    }
#else /* HAVE__GETPTY */
#if defined(HAVE_DEV_PTMX)

    /*
     * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
     * also has bsd-style ptys, but they simply do not work.)
     */

#ifdef HAVE_PTSNAME_R
    char buf[64], *name = buf;
    int err;
#else
    char *name;
#endif

    if (!masterfd || !slavefd || !slavename || slavenamesize < 64)
        return set_errno(EINVAL);

    /* Open the master descriptor */

    if ((*masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1)
        return -1;

    /* Set slave ownership and permissions to real uid of process */

    if (grantpt(*masterfd) == -1) {
        close(*masterfd);
        return -1;
    }

    /* Unlock the slave so it can be opened */

    if (unlockpt(*masterfd) == -1) {
        close(*masterfd);
        return -1;
    }

    /* Retrieve the device name of the slave */

#ifdef HAVE_PTSNAME_R
    if ((err = ptsname_r(*masterfd, buf, 64))) {
        close(*masterfd);
        return set_errno(err);
    }
#else
    if (!(name = ptsname(*masterfd))) {
        close(*masterfd);
        return set_errno(ENOTTY);
    }
#endif

    /* Return it to the caller */

    if (strlcpy_local(slavename, name, slavenamesize) >= slavenamesize) {
        close(*masterfd);
        return set_errno(ENOSPC);
    }

    /* Open the slave descriptor */

    if ((*slavefd = open(slavename, O_RDWR | O_NOCTTY)) == -1) {
        close(*masterfd);
        return -1;
    }

    /* Turn the slave into a terminal */

#ifndef HAVE_CYGWIN
#ifndef HAVE_LINUX              /* linux does not use the streams module */
    /*
     * Push the appropriate streams modules, as described in Solaris pts(7).
     * HP-UX pts(7) doesn't have ttcompat module.
     */
    if (ioctl(*slavefd, I_PUSH, "ptem") == -1) {
        close(*masterfd);
        close(*slavefd);
        return -1;
    }

    if (ioctl(*slavefd, I_PUSH, "ldterm") == -1) {
        close(*masterfd);
        close(*slavefd);
        return -1;
    }
#ifndef __hpux
    if (ioctl(*slavefd, I_PUSH, "ttcompat") == -1) {
        close(*masterfd);
        close(*slavefd);
        return -1;
    }
#endif
#endif
#endif

#else /* HAVE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC

    /* AIX-style pty code */

#ifdef HAVE_TTYNAME_R
    char buf[64], *name = buf;
    int err;
#else
    char *name;
#endif

    if (!masterfd || !slavefd || !slavename || slavenamesize < 64)
        return set_errno(EINVAL);

    /* Open the master descriptor */

    if ((*masterfd = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1)
        return -1;

    /* Retrieve the device name of the slave */

#ifdef HAVE_TTYNAME_R
    if ((err = ttyname_r(*masterfd, buf, 64))) {
        close(*masterfd);
        return set_errno(err);
    }
#else
    if (!(name = ttyname(*masterfd))) {
        close(*masterfd);
        return set_errno(ENOTTY);
    }
#endif

    /* Return it to the caller */

    if (strlcpy_local(slavename, name, slavenamesize) >= slavenamesize) {
        close(*masterfd);
        return set_errno(ENOSPC);
    }

    /* Open the slave descriptor */

    if ((*slavefd = open(name, O_RDWR | O_NOCTTY)) == -1) {
        close(*masterfd);
        return -1;
    }
#else /* HAVE_DEV_PTS_AND_PTC */

    /* BSD-style pty code */
    const char *const ptymajors =
            "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const char *const ptyminors = "0123456789abcdef";
    int num_minors = strlen(ptyminors);
    int num_ptys = strlen(ptymajors) * num_minors;
    char buf[64];
    int found = 0;
    int i;

    /* Identify the first available pty master device */

    for (i = 0; !found && i < num_ptys; i++) {
        snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
                ptyminors[i % num_minors]);
        snprintf(slavename, slavenamesize, "/dev/tty%c%c",
                ptymajors[i / num_minors], ptyminors[i % num_minors]);

        /* Open the master descriptor */

        if ((*masterfd = open(buf, O_RDWR | O_NOCTTY)) == -1) {
            /* Try SCO style naming */
            snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
            snprintf(slavename, slavenamesize, "/dev/ttyp%d", i);

            if ((*masterfd = open(buf, O_RDWR | O_NOCTTY)) == -1)
                continue;
        }

        /* Set slave ownership and permissions to real uid of process */

        pty_set_owner(slavename, getuid());

        /* Open the slave descriptor */

        if ((*slavefd = open(slavename, O_RDWR | O_NOCTTY)) == -1) {
            close(*masterfd);
            return -1;
        }

        found = 1;
    }

    if (!found)
        return set_errno(ENOENT);

#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* HAVE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */

    /* Set the slave's terminal attributes if requested */

    if (slave_termios && tcsetattr(*slavefd, TCSANOW, slave_termios) == -1) {
        close(*masterfd);
        close(*slavefd);
        return -1;
    }

    /* Set the slave's window size if required */

    if (slave_winsize && ioctl(*slavefd, TIOCSWINSZ, slave_winsize) == -1) {
        close(*masterfd);
        close(*slavefd);
        return -1;
    }

    return 0;
}
Ejemplo n.º 23
0
Archivo: tshd.c Proyecto: 5alt/tsh-sctp
int tshd_runshell( int client )
{
    fd_set rd;
    struct winsize ws;
    char *slave, *temp, *shell;
    int ret, len, pid, pty, tty, n;

    /* request a pseudo-terminal */

#if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF

    if( openpty( &pty, &tty, NULL, NULL, NULL ) < 0 )
    {
        return( 24 );
    }

    slave = ttyname( tty );

    if( slave == NULL )
    {
        return( 25 );
    }

#else
#if defined IRIX

    slave = _getpty( &pty, O_RDWR, 0622, 0 );

    if( slave == NULL )
    {
        return( 26 );
    }

    tty = open( slave, O_RDWR | O_NOCTTY );

    if( tty < 0 )
    {
        return( 27 );
    }

#else
#if defined CYGWIN || defined SUNOS || defined HPUX

    pty = open( "/dev/ptmx", O_RDWR | O_NOCTTY );

    if( pty < 0 )
    {
        return( 28 );
    }

    if( grantpt( pty ) < 0 )
    {
        return( 29 );
    }

    if( unlockpt( pty ) < 0 )
    {
        return( 30 );
    }

    slave = ptsname( pty );

    if( slave == NULL )
    {
        return( 31 );
    }

    tty = open( slave, O_RDWR | O_NOCTTY );

    if( tty < 0 )
    {
        return( 32 );
    }

#if defined SUNOS || defined HPUX

    if( ioctl( tty, I_PUSH, "ptem" ) < 0 )
    {
        return( 33 );
    }

    if( ioctl( tty, I_PUSH, "ldterm" ) < 0 )
    {
        return( 34 );
    }

#if defined SUNOS

    if( ioctl( tty, I_PUSH, "ttcompat" ) < 0 )
    {
        return( 35 );
    }

#endif
#endif
#endif
#endif
#endif

    /* just in case bash is run, kill the history file */

    temp = (char *) malloc( 10 );

    if( temp == NULL )
    {
        return( 36 );
    }

    temp[0] = 'H'; temp[5] = 'I';
    temp[1] = 'I'; temp[6] = 'L';
    temp[2] = 'S'; temp[7] = 'E';
    temp[3] = 'T'; temp[8] = '=';
    temp[4] = 'F'; temp[9] = '\0';

    putenv( temp );

    /* get the TERM environment variable */

    ret = pel_recv_msg( client, message, &len );

    if( ret != PEL_SUCCESS )
    {
        return( 37 );
    }

    message[len] = '\0';

    temp = (char *) malloc( len + 6 );

    if( temp == NULL )
    {
        return( 38 );
    }

    temp[0] = 'T'; temp[3] = 'M';
    temp[1] = 'E'; temp[4] = '=';
    temp[2] = 'R';

    strncpy( temp + 5, (char *) message, len + 1 );

    putenv( temp );

    /* get the window size */

    ret = pel_recv_msg( client, message, &len );

    if( ret != PEL_SUCCESS || len != 4 )
    {
        return( 39 );
    }

    ws.ws_row = ( (int) message[0] << 8 ) + (int) message[1];
    ws.ws_col = ( (int) message[2] << 8 ) + (int) message[3];

    ws.ws_xpixel = 0;
    ws.ws_ypixel = 0;

    if( ioctl( pty, TIOCSWINSZ, &ws ) < 0 )
    {
        return( 40 );
    }

    /* get the system command */

    ret = pel_recv_msg( client, message, &len );

    if( ret != PEL_SUCCESS )
    {
        return( 41 );
    }

    message[len] = '\0';

    temp = (char *) malloc( len + 1 );

    if( temp == NULL )
    {
        return( 42 );
    }

    strncpy( temp, (char *) message, len + 1 );

    /* fork to spawn a shell */

    pid = fork();

    if( pid < 0 )
    {
        return( 43 );
    }

    if( pid == 0 )
    {
        /* close the client socket and the pty (master side) */

        close( client );
        close( pty );

        /* create a new session */

        if( setsid() < 0 )
        {
            return( 44 );
        }

        /* set controlling tty, to have job control */

#if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF

        if( ioctl( tty, TIOCSCTTY, NULL ) < 0 )
        {
            return( 45 );
        }

#else
#if defined CYGWIN || defined SUNOS || defined IRIX || defined HPUX

        {
            int fd;

            fd = open( slave, O_RDWR );

            if( fd < 0 )
            {
                return( 46 );
            }

            close( tty );

            tty = fd;
        }

#endif
#endif

        /* tty becomes stdin, stdout, stderr */

        dup2( tty, 0 );
        dup2( tty, 1 );
        dup2( tty, 2 );

        if( tty > 2 )
        {
            close( tty );
        }

        /* fire up the shell */

        shell = (char *) malloc( 8 );

        if( shell == NULL )
        {
            return( 47 );
        }

        shell[0] = '/'; shell[4] = '/';
        shell[1] = 'b'; shell[5] = 's';
        shell[2] = 'i'; shell[6] = 'h';
        shell[3] = 'n'; shell[7] = '\0';

        execl( shell, shell + 5, "-c", temp, (char *) 0 );

        /* d0h, this shouldn't happen */

        return( 48 );
    }
    else
    {
        /* tty (slave side) not needed anymore */

        close( tty );

        /* let's forward the data back and forth */

        while( 1 )
        {
            FD_ZERO( &rd );
            FD_SET( client, &rd );
            FD_SET( pty, &rd );

            n = ( pty > client ) ? pty : client;

            if( select( n + 1, &rd, NULL, NULL, NULL ) < 0 )
            {
                return( 49 );
            }

            if( FD_ISSET( client, &rd ) )
            {
                ret = pel_recv_msg( client, message, &len );

                if( ret != PEL_SUCCESS )
                {
                    return( 50 );
                }

                if( write( pty, message, len ) != len )
                {
                    return( 51 );
                }
            }

            if( FD_ISSET( pty, &rd ) )
            {
                len = read( pty, message, BUFSIZE );

                if( len == 0 ) break;

                if( len < 0 )
                {
                    return( 52 );
                }

                ret = pel_send_msg( client, message, len );

                if( ret != PEL_SUCCESS )
                {
                    return( 53 );
                }
            }
        }

        return( 54 );
    }

    /* not reached */

    return( 55 );
}
Ejemplo n.º 24
0
int
openpty(int *amaster, int *aslave, char *name, struct termios *termp,
   struct winsize *winp)
{
#if defined(HAVE__GETPTY)
	/*
	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
	 * pty's automagically when needed
	 */
	char *slave;

	if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL)
		return (-1);

	/* Open the slave side. */
	if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) {
		close(*amaster);
		return (-1);
	}
	return (0);

#elif defined(HAVE_DEV_PTMX)
	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 */
	int ptm;
	char *pts;
	mysig_t old_signal;

	if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1)
		return (-1);

	/* XXX: need to close ptm on error? */
	old_signal = signal(SIGCHLD, SIG_DFL);
	if (grantpt(ptm) < 0)
		return (-1);
	signal(SIGCHLD, old_signal);

	if (unlockpt(ptm) < 0)
		return (-1);

	if ((pts = ptsname(ptm)) == NULL)
		return (-1);
	*amaster = ptm;

	/* Open the slave side. */
	if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) {
		close(*amaster);
		return (-1);
	}

	/*
	 * Try to push the appropriate streams modules, as described 
	 * in Solaris pts(7).
	 */
	ioctl(*aslave, I_PUSH, "ptem");
	ioctl(*aslave, I_PUSH, "ldterm");
# ifndef __hpux
	ioctl(*aslave, I_PUSH, "ttcompat");
# endif /* __hpux */

	return (0);

#elif defined(HAVE_DEV_PTS_AND_PTC)
	/* AIX-style pty code. */
	const char *ttname;

	if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1)
		return (-1);
	if ((ttname = ttyname(*amaster)) == NULL)
		return (-1);
	if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) {
		close(*amaster);
		return (-1);
	}
	return (0);

#elif defined(_UNICOS)
	char ptbuf[64], ttbuf[64];
	int i;
	int highpty;

	highpty = 128;
#ifdef _SC_CRAY_NPTY
	if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1)
		highpty = 128;
#endif /* _SC_CRAY_NPTY */

	for (i = 0; i < highpty; i++) {
		snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i);
		snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i);
		if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1)
			continue;
		/* Open the slave side. */
		if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) {
			close(*amaster);
			return (-1);
		}
		return (0);
	}
	return (-1);

#elif defined(BARRELFISH)
    int ptm;
    char *pts;

    /* open master side */
    ptm = posix_openpt(O_RDWR | O_NOCTTY);
    if (ptm < 0) {
        return -1;
    }
    if (grantpt(ptm) < 0) {
        return -1;
    }
    if (unlockpt(ptm) < 0) {
        return -1;
    }
    *amaster = ptm;

    pts = ptsname(ptm);
    if (pts == NULL) {
        return -1;
    }

    /* open slave side */
    *aslave = open(pts, O_RDWR | O_NOCTTY);
    if (*aslave < 0) {
        close(*amaster);
        return -1;
    }

    return 0;
#else
	/* BSD-style pty code. */
	char ptbuf[64], ttbuf[64];
	int i;
	const char *ptymajors = "pqrstuvwxyzabcdefghijklmno"
	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char *ptyminors = "0123456789abcdef";
	int num_minors = strlen(ptyminors);
	int num_ptys = strlen(ptymajors) * num_minors;
	struct termios tio;

	for (i = 0; i < num_ptys; i++) {
		snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", 
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);
		snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c",
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);

		if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) {
			/* Try SCO style naming */
			snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i);
			snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i);
			if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1)
				continue;
		}

		/* Open the slave side. */
		if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) {
			close(*amaster);
			return (-1);
		}
		/* set tty modes to a sane state for broken clients */
		if (tcgetattr(*amaster, &tio) != -1) {
			tio.c_lflag |= (ECHO | ISIG | ICANON);
			tio.c_oflag |= (OPOST | ONLCR);
			tio.c_iflag |= ICRNL;
			tcsetattr(*amaster, TCSANOW, &tio);
		}

		return (0);
	}
	return (-1);
#endif
}
Ejemplo n.º 25
0
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
{
#if defined(HAVE_OPENPTY)
	/* exists in recent (4.4) BSDs and OSF/1 */
	char *name;
	int i;

	i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
	if (i < 0) {
		dropbear_log(LOG_WARNING, 
				"pty_allocate: openpty: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ttyfd);
	if (!name) {
		dropbear_exit("ttyname fails for openpty device");
	}

	strlcpy(namebuf, name, namebuflen);	/* possible truncation */
	return 1;
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY
	/*
	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
	 * pty's automagically when needed
	 */
	char *slave;

	slave = _getpty(ptyfd, O_RDWR, 0622, 0);
	if (slave == NULL) {
		dropbear_log(LOG_WARNING,
				"pty_allocate: _getpty: %.100s", strerror(errno));
		return 0;
	}
	strlcpy(namebuf, slave, namebuflen);
	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		dropbear_log(LOG_WARNING,
				"pty_allocate error: ttyftd open error");
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE__GETPTY */
#if defined(USE_DEV_PTMX)
	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 *
	 * Linux systems may have the /dev/ptmx device, but this code won't work.
	 */
	int ptm;
	char *pts;

	ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
	if (ptm < 0) {
		dropbear_log(LOG_WARNING,
				"pty_allocate: /dev/ptmx: %.100s", strerror(errno));
		return 0;
	}
	if (grantpt(ptm) < 0) {
		dropbear_log(LOG_WARNING,
				"grantpt: %.100s", strerror(errno));
		return 0;
	}
	if (unlockpt(ptm) < 0) {
		dropbear_log(LOG_WARNING,
				"unlockpt: %.100s", strerror(errno));
		return 0;
	}
	pts = ptsname(ptm);
	if (pts == NULL) {
		dropbear_log(LOG_WARNING,
				"Slave pty side name could not be obtained.");
	}
	strlcpy(namebuf, pts, namebuflen);
	*ptyfd = ptm;

	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		dropbear_log(LOG_ERR,
			"error opening pts %.100s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
#ifndef HAVE_CYGWIN
	/*
	 * Push the appropriate streams modules, as described in Solaris pts(7).
	 * HP-UX pts(7) doesn't have ttcompat module.
	 */
	if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) {
		dropbear_log(LOG_WARNING,
				"ioctl I_PUSH ptem: %.100s", strerror(errno));
	}
	if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) {
		dropbear_log(LOG_WARNING,
			"ioctl I_PUSH ldterm: %.100s", strerror(errno));
	}
#ifndef __hpux
	if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) {
		dropbear_log(LOG_WARNING,
			"ioctl I_PUSH ttcompat: %.100s", strerror(errno));
	}
#endif
#endif
	return 1;
#else /* USE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC
	/* AIX-style pty code. */
	const char *name;

	*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
	if (*ptyfd < 0) {
		dropbear_log(LOG_ERR,
			"Could not open /dev/ptc: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ptyfd);
	if (!name) {
		dropbear_exit("ttyname fails for /dev/ptc device");
	}
	strlcpy(namebuf, name, namebuflen);
	*ttyfd = open(name, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		dropbear_log(LOG_ERR,
			"Could not open pty slave side %.100s: %.100s",
		    name, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE_DEV_PTS_AND_PTC */

	/* BSD-style pty code. */
	char buf[64];
	int i;
	const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char *ptyminors = "0123456789abcdef";
	int num_minors = strlen(ptyminors);
	int num_ptys = strlen(ptymajors) * num_minors;
	struct termios tio;

	for (i = 0; i < num_ptys; i++) {
		snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
			 ptyminors[i % num_minors]);
		snprintf(namebuf, namebuflen, "/dev/tty%c%c",
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);

		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
		if (*ptyfd < 0) {
			/* Try SCO style naming */
			snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
			snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
			*ptyfd = open(buf, O_RDWR | O_NOCTTY);
			if (*ptyfd < 0) {
				continue;
			}
		}

		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
		if (*ttyfd < 0) {
			dropbear_log(LOG_ERR,
				"pty_allocate: %.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		/* set tty modes to a sane state for broken clients */
		if (tcgetattr(*ptyfd, &tio) < 0) {
			dropbear_log(LOG_WARNING,
				"ptyallocate: tty modes failed: %.100s", strerror(errno));
		} else {
			tio.c_lflag |= (ECHO | ISIG | ICANON);
			tio.c_oflag |= (OPOST | ONLCR);
			tio.c_iflag |= ICRNL;

			/* Set the new modes for the terminal. */
			if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) {
				dropbear_log(LOG_WARNING,
					"Setting tty modes for pty failed: %.100s",
					strerror(errno));
			}
		}

		return 1;
	}
	dropbear_log(LOG_WARNING, "failed to open any /dev/pty?? devices");
	return 0;
#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* USE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */
}
Ejemplo n.º 26
0
int getpty(int *ptynum)
{
#if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__) /* XXX */
    {
	int master;
	int slave;
	if(openpty(&master, &slave, line, 0, 0) == 0){
	    ptyslavefd = slave;
	    return master;
	}
    }
#endif /* HAVE_OPENPTY .... */
#ifdef HAVE__GETPTY
    {
	int master;
	char *p;
	p = _getpty(&master, O_RDWR, 0600, 1);
	if(p == NULL)
	    return -1;
	strlcpy(line, p, sizeof(Xline));
	return master;
    }
#endif

#ifdef	STREAMSPTY
    {
	char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm",
			  "/dev/ptym/clone", 0 };

	char **q;
	int p;
	for(q=clone; *q; q++){
	    p=open(*q, O_RDWR);
	    if(p >= 0){
#ifdef HAVE_GRANTPT
		grantpt(p);
#endif
#ifdef HAVE_UNLOCKPT
		unlockpt(p);
#endif
		strlcpy(line, ptsname(p), sizeof(Xline));
		really_stream = 1;
		return p;
	    }
	}
    }
#endif /* STREAMSPTY */
#ifndef _CRAY
    {
	int p;
	char *cp, *p1, *p2;
	int i;

#ifndef	__hpux
	snprintf(line, sizeof(Xline), "/dev/ptyXX");
	p1 = &line[8];
	p2 = &line[9];
#else
	snprintf(line, sizeof(Xline), "/dev/ptym/ptyXX");
	p1 = &line[13];
	p2 = &line[14];
#endif


	for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {
	    struct stat stb;

	    *p1 = *cp;
	    *p2 = '0';
	    /*
	     * This stat() check is just to keep us from
	     * looping through all 256 combinations if there
	     * aren't that many ptys available.
	     */
	    if (stat(line, &stb) < 0)
		break;
	    for (i = 0; i < 16; i++) {
		*p2 = "0123456789abcdef"[i];
		p = open(line, O_RDWR);
		if (p > 0) {
#if SunOS == 40
		    int dummy;
#endif

#ifndef	__hpux
		    line[5] = 't';
#else
		    for (p1 = &line[8]; *p1; p1++)
			*p1 = *(p1+1);
		    line[9] = 't';
#endif
		    chown(line, 0, 0);
		    chmod(line, 0600);
#if SunOS == 40
		    if (ioctl(p, TIOCGPGRP, &dummy) == 0
			|| errno != EIO) {
			chmod(line, 0666);
			close(p);
			line[5] = 'p';
		    } else
#endif /* SunOS == 40 */
			return(p);
		}
	    }
	}
    }
#else	/* CRAY */
    {
	extern lowpty, highpty;
	struct stat sb;
	int p;

	for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) {
	    snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum);
	    p = open(myline, 2);
	    if (p < 0)
		continue;
	    snprintf(line, sizeof(Xline), "/dev/ttyp%03d", *ptynum);
	    /*
	     * Here are some shenanigans to make sure that there
	     * are no listeners lurking on the line.
	     */
	    if(stat(line, &sb) < 0) {
		close(p);
		continue;
	    }
	    if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
		chown(line, 0, 0);
		chmod(line, 0600);
		close(p);
		p = open(myline, 2);
		if (p < 0)
		    continue;
	    }
	    /*
	     * Now it should be safe...check for accessability.
	     */
	    if (access(line, 6) == 0)
		return(p);
	    else {
		/* no tty side to pty so skip it */
		close(p);
	    }
	}
    }
#endif	/* CRAY */
    return(-1);
}
Ejemplo n.º 27
0
int forkpty(int *amaster,char *dummy,struct termios *termp, struct winsize *wp)
{
    int master,slave;
    int pid;

#ifdef HAVE__GETPTY
    int filedes[2];
    char *line;

    line = _getpty(&filedes[0], O_RDWR|O_NDELAY, 0600, 0);
    if (0 == line)
        return -1;
    if (0 > (filedes[1] = open(line, O_RDWR)))
    {
        close(filedes[0]);
        return -1;
    }
    master=filedes[0];
    slave=filedes[1];
#elif defined(HAVE_GRANTPT) && (defined(HAVE_GETPT) || defined(HAVE_DEV_PTMX) || defined(HAVE_POSIX_OPENPT))
# ifdef HAVE_PTSNAME
    char *name;
# else
    char name[80];
# endif

# ifdef HAVE_GETPT
    master=getpt();
# elif HAVE_POSIX_OPENPT
    master=posix_openpt(O_RDWR);
# else
    master=open("/dev/ptmx", O_RDWR);
# endif

    if (master<0)
        return -1;

    if (grantpt(master)<0||unlockpt(master)<0)
        goto close_master;

# ifdef HAVE_PTSNAME
    if (!(name=ptsname(master)))
        goto close_master;
# else
    if (ptsname_r(master,name,80))
        goto close_master;
# endif

    slave=open(name,O_RDWR);
    if (slave==-1)
        goto close_master;

# ifdef HAVE_STROPTS_H
    if (isastream(slave))
        if (ioctl(slave, I_PUSH, "ptem")<0
                ||ioctl(slave, I_PUSH, "ldterm")<0)
            goto close_slave;
# endif

    goto ok;

//close_slave:
    close (slave);

close_master:
    close (master);
    return -1;

ok:
#else
  char *p, *q, *l, *d;
  char PtyName[32], TtyName[32];

  strcpy(PtyName, PtyProto);
  strcpy(TtyName, TtyProto);
  for (p = PtyName; *p != 'X'; p++)
    ;
  for (q = TtyName; *q != 'X'; q++)
    ;
  for (l = PTYRANGE0; (*p = *l) != '\0'; l++)
    {
      for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++)
        {
//        tintin_printf(0,"OpenPTY tries '%s'", PtyName);
          if ((master = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
            continue;
          q[0] = *l;
          q[1] = *d;
          if (access(TtyName, R_OK | W_OK))
            {
              close(master);
              continue;
            }
          if ((slave=open(TtyName, O_RDWR|O_NOCTTY))==-1)
	  {
	  	close(master);
	  	continue;
	  }
          goto ok;
        }
    }
  return -1;
  ok:
#endif

    if (termp)
        tcsetattr(master, TCSANOW, termp);
    if (wp)
        ioctl(master,TIOCSWINSZ,wp);
    // let's ignore errors on this ioctl silently

    pid=fork();
    switch (pid)
    {
    case -1:
        close(master);
        close(slave);
        return -1;
    case 0:
        close(master);
        setsid();
        dup2(slave,0);
        dup2(slave,1);
        dup2(slave,2);
        close(slave);
        return 0;
    default:
        close(slave);
        *amaster=master;
        return pid;
    }
}
Ejemplo n.º 28
0
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
{
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
	/* openpty(3) exists in OSF/1 and some other os'es */
	char *name;
	int i;

	i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
	if (i < 0) {
		error("openpty: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ttyfd);
	if (!name)
		fatal("openpty returns device for which ttyname fails.");

	strlcpy(namebuf, name, namebuflen);	/* possible truncation */
	return 1;
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY
	/*
	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
	 * pty's automagically when needed
	 */
	char *slave;

	slave = _getpty(ptyfd, O_RDWR, 0622, 0);
	if (slave == NULL) {
		error("_getpty: %.100s", strerror(errno));
		return 0;
	}
	strlcpy(namebuf, slave, namebuflen);
	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("%.200s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE__GETPTY */
#if defined(HAVE_DEV_PTMX)
	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 */
	int ptm;
	char *pts;
	mysig_t old_signal;

	ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
	if (ptm < 0) {
		error("/dev/ptmx: %.100s", strerror(errno));
		return 0;
	}
	old_signal = mysignal(SIGCHLD, SIG_DFL);
	if (grantpt(ptm) < 0) {
		error("grantpt: %.100s", strerror(errno));
		return 0;
	}
	mysignal(SIGCHLD, old_signal);
	if (unlockpt(ptm) < 0) {
		error("unlockpt: %.100s", strerror(errno));
		return 0;
	}
	pts = ptsname(ptm);
	if (pts == NULL)
		error("Slave pty side name could not be obtained.");
	strlcpy(namebuf, pts, namebuflen);
	*ptyfd = ptm;

	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("%.100s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
#ifndef HAVE_CYGWIN
	/*
	 * Push the appropriate streams modules, as described in Solaris pts(7).
	 * HP-UX pts(7) doesn't have ttcompat module.
	 */
	if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
		error("ioctl I_PUSH ptem: %.100s", strerror(errno));
	if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
		error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
#ifndef __hpux
	if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
		error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
#endif
#endif
	return 1;
#else /* HAVE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC
	/* AIX-style pty code. */
	const char *name;

	*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
	if (*ptyfd < 0) {
		error("Could not open /dev/ptc: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ptyfd);
	if (!name)
		fatal("Open of /dev/ptc returns device for which ttyname fails.");
	strlcpy(namebuf, name, namebuflen);
	*ttyfd = open(name, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("Could not open pty slave side %.100s: %.100s",
		    name, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE_DEV_PTS_AND_PTC */
#ifdef _CRAY
	char buf[64];
  	int i;
  	int highpty;

#ifdef _SC_CRAY_NPTY
	highpty = sysconf(_SC_CRAY_NPTY);
	if (highpty == -1)
		highpty = 128;
#else
	highpty = 128;
#endif

	for (i = 0; i < highpty; i++) {
		snprintf(buf, sizeof(buf), "/dev/pty/%03d", i);
		*ptyfd = open(buf, O_RDWR|O_NOCTTY);
		if (*ptyfd < 0)
			continue;
		snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i);
		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
		if (*ttyfd < 0) {
			error("%.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		return 1;
	}
	return 0;
#else
	/* BSD-style pty code. */
	char buf[64];
	int i;
	const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char *ptyminors = "0123456789abcdef";
	int num_minors = strlen(ptyminors);
	int num_ptys = strlen(ptymajors) * num_minors;
	struct termios tio;

	for (i = 0; i < num_ptys; i++) {
		snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
			 ptyminors[i % num_minors]);
		snprintf(namebuf, namebuflen, "/dev/tty%c%c",
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);

		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
		if (*ptyfd < 0) {
			/* Try SCO style naming */
			snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
			snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
			*ptyfd = open(buf, O_RDWR | O_NOCTTY);
			if (*ptyfd < 0)
				continue;
		}

		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
		if (*ttyfd < 0) {
			error("%.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		/* set tty modes to a sane state for broken clients */
		if (tcgetattr(*ptyfd, &tio) < 0)
			log("Getting tty modes for pty failed: %.100s", strerror(errno));
		else {
			tio.c_lflag |= (ECHO | ISIG | ICANON);
			tio.c_oflag |= (OPOST | ONLCR);
			tio.c_iflag |= ICRNL;

			/* Set the new modes for the terminal. */
			if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
				log("Setting tty modes for pty failed: %.100s", strerror(errno));
		}

		return 1;
	}
	return 0;
#endif /* CRAY */
#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* HAVE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */
}
Ejemplo n.º 29
0
static int
get_pty(int *pty, int *tty, char *ttydev, char *ptydev)
{
#ifdef USE_PRIVSEP
	if (priv_openpty(pty, tty) < 0) {
		return 1;
	}
	return 0;
#elif HAVE_OPENPTY
	if (openpty(pty, tty, NULL, NULL, NULL) == -1) {
		return 1;
	}
	return 0;
#elif defined (SVR4) || defined (USE_PTS)
#if defined (_AIX)
	if ((*pty = open ("/dev/ptc", O_RDWR)) < 0)
#else
	if ((*pty = open ("/dev/ptmx", O_RDWR)) < 0)
#endif
	    return 1;
	grantpt(*pty);
	unlockpt(*pty);
	strcpy(ttydev, (char *)ptsname(*pty));
	if ((*tty = open(ttydev, O_RDWR)) >= 0)
	{
	    (void)ioctl(*tty, I_PUSH, "ttcompat");
	    return 0;
	}
	if (*pty >= 0)
	    close (*pty);
#else /* !SVR4, need lots of code */
#ifdef USE_GET_PSEUDOTTY
	if ((*pty = getpseudotty (&ttydev, &ptydev)) >= 0 &&
	    (*tty = open (ttydev, O_RDWR)) >= 0)
	    return 0;
	if (*pty >= 0)
	    close (*pty);
#else
	static int devindex, letter = 0;

#ifdef sgi
	{
	    char *slave;
	    slave = _getpty (pty, O_RDWR, 0622, 0);
	    if ((*tty = open (slave, O_RDWR)) != -1)
		return 0;
	}
#else
	strcpy (ttydev, "/dev/ttyxx");
	strcpy (ptydev, "/dev/ptyxx");
	while (PTYCHAR1[letter]) {
	    ttydev [strlen(ttydev) - 2]  = ptydev [strlen(ptydev) - 2] =
		    PTYCHAR1 [letter];

	    while (PTYCHAR2[devindex]) {
		ttydev [strlen(ttydev) - 1] = ptydev [strlen(ptydev) - 1] =
			PTYCHAR2 [devindex];
		if ((*pty = open (ptydev, O_RDWR)) >= 0 &&
		    (*tty = open (ttydev, O_RDWR)) >= 0)
		{
			/*
			 * We need to set things up for our next entry
			 * into this function!
			 */
			(void) devindex++;
			return(0);
		}
		if (*pty >= 0)
		    close (*pty);
		devindex++;
	    }
	    devindex = 0;
	    (void) letter++;
	}
#endif /* sgi else not sgi */
#endif /* USE_GET_PSEUDOTTY */
#endif /* SVR4 */
	/*
	 * We were unable to allocate a pty master!  Return an error
	 * condition and let our caller terminate cleanly.
	 */
	return(1);
}
Ejemplo n.º 30
0
static int allocate_master(const char ** slave_name, const char** clone) {
    int master_fd = -1;
    static const char * const clones[] =
    /* Different pty master clone devices */
        {
            "/dev/ptmx",      /* Various systems */
            "/dev/ptm/clone", /* HPUX */
            "/dev/ptc",       /* AIX */
            "/dev/ptmx_bsd"   /* Tru64 */
        };

#ifdef HAVE_GETPT /* glibc */
    master_fd = getpt ();
    if (master_fd >= 0)
        return master_fd;
#endif /* HAVE_GETPT */


#if defined(HAVE_OPENPTY) /* BSD, Tru64, glibc */
    {
        int slave_fd = -1;
        int rc;
        BLOCK_SIGNAL (SIGCHLD);
        rc = openpty (&master_fd, &slave_fd, NULL, NULL, NULL);
        UNBLOCK_SIGNAL (SIGCHLD);
        if (rc == 0)
        {
            *slave_name = ttyname (slave_fd);
            retry_close (slave_fd);
            return master_fd;
        }
        else
        {
            if (master_fd >= 0)
                retry_close (master_fd);
            if (slave_fd >= 0)
                retry_close (slave_fd);
        }
    }
#endif /* HAVE_OPENPTY */

#if defined(HAVE__GETPTY) && defined (O_NDELAY) /* SGI */
    master_fd = -1;
    BLOCK_SIGNAL (SIGCHLD);
    *slave_name = _getpty (&master_fd, O_RDWR | O_NDELAY, 0600, 0);
    UNBLOCK_SIGNAL (SIGCHLD);
    if (master_fd >= 0 && *slave_name != NULL)
        return master_fd;
#endif /* HAVE__GETPTY */

    /* Master clone devices are available on most systems */
    {
        int i;
        for (i = 0; i < countof (clones); i++)
        {
            *clone = clones[i];
            master_fd = open ((char *) *clone, // TODO: retry open
                              O_RDWR | O_NONBLOCK, 0);
            if (master_fd >= 0)
                return master_fd;
        }
        *clone = NULL;
    }
    return -1;
}