/* $Id: fallback.c,v 8.2 2010/02/11 20:54:49 ksb Exp $ * * This is a fake library interface to ptyd (mtr&ksb) * * Mike Rowan (mtr@mace.cc.purdue.edu), KS Braunsdorf (at npcguild.org) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cons.h" #include "machine.h" #if NEED_UNISTD_H #include #endif #if USE_STRINGS #include #else #include #endif #if DO_VIRTUAL && ! HAVE_PTYD extern int errno; #if !HAVE_STRERROR extern char *sys_errlist[], *strchr(); #define strerror(Me) (sys_errlist[Me]) #endif /* Below is the string for finding /dev/ptyXX. For each architecture we * leave some pty's world writable because we don't have source for * everything that uses pty's. For the most part, we'll be trying to * make /dev/ptyq* the "free" pty's. */ #if defined(sun) static char charone[] = "prstuvwxyzPQRSTUVWq"; #else #if defined(dynix) static char charone[] = "prstuvwxyzPQRSTUVWq"; #else #if defined(ultrix) static char charone[] = "prstuvwxyzPQRSTUVWq"; #else /* all the world's a vax ;-) */ static char charone[] = "prstuvwxyzPQRSTUVWq"; #endif #endif #endif static char chartwo[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; #if (defined(_AIX) || defined(PTX4)) static char acMaster[] = "/dev/ptc/XXXXXXXXX"; static char acSlave[] = "/dev/pts/XXXXXXXXX"; #else static char acMaster[] = "/dev/ptyXX"; static char acSlave[] = "/dev/ttyXX"; #endif /* _AIX */ #if !HAVE_GETPSEUDO #ifdef _AIX /* get a pty for the user (emulate the neato sequent call) (mm) */ static int getpseudotty(slave, master) char **master, **slave; { int fd; char *pcName, *pcTmp; if (0 > (fd = open("/dev/ptc", O_RDWR|O_NDELAY, 0))) { return -1; } if ((char *)0 == (pcName = ttyname(fd))) { return -1; } (void)strcpy(acSlave, pcName); *slave = acSlave; (void)strcpy(acMaster, pcName); acMaster[7] = 'c'; *master = acMaster; return fd; } #else #if HAVE_PTSNAME /* get a pty for the user -- emulate the neato sequent call under (gregf) * DYNIX/ptx v4.0 */ static int getpseudotty(slave, master) char **master, **slave; { register int fd; register char *pcName; extern char *ptsname(int); if (-1 != (fd = open("/dev/ptmx", O_RDWR, 0)) || 0 != grantpt(fd) || 0 != unlockpt(fd)) { fprintf(stderr, "%s: ptmx: %s\n", progname, strerror(errno)); close(fd); return -1; } #if HAVE_MASTER_PTY if ((char *)0 == (pcName = ttyname(fd))) { close(fd); return -1; } (void)strcpy(acMaster, pcName); #else (void)strcpy(acMaster, "/dev/null"); #endif *master = acMaster; if ((char *) 0 == (pcName = ptsname(fd))) { close(fd); return -1; } (void)strcpy(acSlave, pcName); *slave = acSlave; return fd; } #else /* get a pty for the user (emulate the neato sequent call) (ksb) */ static int getpseudotty(slave, master) char **master, **slave; { static char *pcOne = charone, *pcTwo = chartwo; auto int fd, iLoop, iIndex = sizeof("/dev/pty")-1; auto char *pcOld1; auto struct stat statBuf; iLoop = 0; pcOld1 = pcOne; for (;;) { if ('\000' == *++pcTwo) { pcTwo = chartwo; if ('\000' == *++pcOne) { pcOne = charone; /* XXX 32 is the magic size of a tty slot in * old-school BSD unix -- ksb */ if ((pcOld1 == pcOne && ++iLoop > 1) || iLoop > 32) return -1; } } acMaster[iIndex] = *pcOne; acMaster[iIndex+1] = *pcTwo; /* Remeber we are root - stat the file * to see if it exists before we open it * for read/write - if it doesn't we don't * have any pty's left in the row */ if (-1 == stat(acMaster, &statBuf) || S_IFCHR != (statBuf.st_mode&S_IFMT)) { pcTwo = "l"; continue; } if (0 > (fd = open(acMaster, O_RDWR|O_NDELAY, 0))) { continue; } acSlave[iIndex] = *pcOne; acSlave[iIndex+1] = *pcTwo; if (-1 == access(acSlave, F_OK)) { (void) close(fd); continue; } break; } *master = acMaster; *slave = acSlave; return fd; } #endif /* PTX version */ #endif /* _AIX */ #endif /* !HAVE_GETPSEUDO */ /* get a Joe pty bacause the daemon is not with us, sadly. (ksb) */ int FallBack(pcSlave, pcMaster) char *pcSlave, *pcMaster; { extern char *ptsname(int); auto int fd; auto char *pcTSlave, *pcTMaster; if (-1 != (fd = open("/dev/ptmx", O_RDWR, 0666))) { if (0 == grantpt(fd) && 0 == unlockpt(fd)) { strcpy(pcSlave, ptsname(fd)); strcpy(pcMaster, "PTMX"); return fd; } close(fd); /* try the old way */ } if (-1 == (fd = getpseudotty(& pcTSlave, & pcTMaster))) { return -1; } (void) strcpy(pcSlave, pcTSlave); (void) strcpy(pcMaster, pcTMaster); return fd; } #endif /* no code if it is not used */