#include "com_err.h"
#include "libpty.h"
#include "pty-int.h"
#include "k5-platform.h"
long
ptyint_getpty_ext(int *fd, char *slave, int 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;
#endif
#ifdef HAVE_OPENPTY
int slavefd;
if(openpty(fd, &slavefd, slave, (struct termios *) 0,
(struct winsize *) 0)) return 1;
close(slavefd);
return 0;
#else
#ifdef HAVE__GETPTY
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
*fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY);
#ifdef HAVE_STREAMS
if (*fd < 0) *fd = open("/dev/ptmx",O_RDWR|O_NDELAY);
#endif
if (*fd < 0) *fd = open("/dev/ptc", O_RDWR|O_NDELAY);
if (*fd < 0) *fd = open("/dev/pty", O_RDWR|O_NDELAY);
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
#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);
sprintf(slavebuf, "/dev/ttyp%x", ptynum);
if (strlen(slavebuf) > slavelength - 1) {
close(*fd);
*fd = -1;
return PTY_GETPTY_SLAVE_TOOLONG;
}
strncpy(slave, slavebuf, slavelength);
return 0;
} else {
for (cp = "pqrstuvwxyzPQRST";*cp; cp++) {
sprintf(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;
slavebuf[sizeof("/dev/") - 1] = 't';
if (strlen(slavebuf) > slavelength -1) {
close(*fd);
*fd = -1;
return PTY_GETPTY_SLAVE_TOOLONG;
}
strncpy(slave, slavebuf, slavelength);
return 0;
}
}
return PTY_GETPTY_NOPTY;
}
#endif
#endif
}
long
pty_getpty(int *fd, char *slave, int slavelength)
{
return ptyint_getpty_ext(fd, slave, slavelength, 1);
}