diff options
Diffstat (limited to 'crypto/kerberosIV/appl/bsd/forkpty.c')
-rw-r--r-- | crypto/kerberosIV/appl/bsd/forkpty.c | 477 |
1 files changed, 0 insertions, 477 deletions
diff --git a/crypto/kerberosIV/appl/bsd/forkpty.c b/crypto/kerberosIV/appl/bsd/forkpty.c deleted file mode 100644 index 891fb91fb2a28..0000000000000 --- a/crypto/kerberosIV/appl/bsd/forkpty.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "bsd_locl.h" - -#ifndef HAVE_FORKPTY - -RCSID("$Id: forkpty.c,v 1.57 1999/12/02 16:58:28 joda Exp $"); - -/* Only CRAY is known to have problems with forkpty(). */ -#if defined(CRAY) -static int forkpty_ok = 0; -#else -static int forkpty_ok = 1; -#endif - -#ifndef HAVE_PTSNAME -static char *ptsname(int fd) -{ -#ifdef HAVE_TTYNAME - return ttyname(fd); -#else - return NULL; -#endif -} -#endif - -#ifndef HAVE_GRANTPT -#define grantpt(fdm) (0) -#endif - -#ifndef HAVE_UNLOCKPT -#define unlockpt(fdm) (0) -#endif - -#ifndef HAVE_VHANGUP -#define vhangup() (0) -#endif - -#ifndef HAVE_REVOKE -static -void -revoke(char *line) -{ - int slave; - RETSIGTYPE (*ofun)(); - - if ( (slave = open(line, O_RDWR)) < 0) - return; - - ofun = signal(SIGHUP, SIG_IGN); - vhangup(); - signal(SIGHUP, ofun); - /* - * Some systems (atleast SunOS4) want to have the slave end open - * at all times to prevent a race in the child. Login will close - * it so it should really not be a problem. However for the - * paranoid we use the close on exec flag so it will only be open - * in the parent. Additionally since this will be the controlling - * tty of rlogind the final vhangup() in rlogind should hangup all - * processes. A working revoke would of course have been prefered - * though (sigh). - */ - fcntl(slave, F_SETFD, 1); - /* close(slave); */ -} -#endif - - -static int pty_major, pty_minor; - -static void -pty_scan_start(void) -{ - pty_major = -1; - pty_minor = 0; -} - -static char *bsd_1 = "0123456789abcdefghijklmnopqrstuv"; -/* there are many more */ -static char *bsd_2 = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -static int -pty_scan_next(char *buf, size_t sz) -{ -#ifdef CRAY - if(++pty_major >= sysconf(_SC_CRAY_NPTY)) - return -1; - snprintf(buf, sz, "/dev/pty/%03d", pty_major); -#else - if(++pty_major == strlen(bsd_1)){ - pty_major = 0; - if(++pty_minor == strlen(bsd_2)) - return -1; - } -#ifdef __hpux - snprintf(buf, sz, "/dev/ptym/pty%c%c", bsd_2[pty_major], bsd_1[pty_minor]); -#else - snprintf(buf, sz, "/dev/pty%c%c", bsd_2[pty_major], bsd_1[pty_minor]); -#endif /* __hpux */ -#endif /* CRAY */ - return 0; -} - -static void -pty_scan_tty(char *buf, size_t sz) -{ -#ifdef CRAY - snprintf(buf, sz, "/dev/ttyp%03d", pty_major); -#elif defined(__hpux) - snprintf(buf, sz, "/dev/pty/tty%c%c", bsd_2[pty_major], bsd_1[pty_minor]); -#else - snprintf(buf, sz, "/dev/tty%c%c", bsd_2[pty_major], bsd_1[pty_minor]); -#endif -} - -static int -ptym_open_streams_flavor(char *pts_name, - size_t pts_name_sz, - int *streams_pty) -{ - /* Try clone device master ptys */ - const char *const clone[] = { "/dev/ptc", "/dev/ptmx", - "/dev/ptm", "/dev/ptym/clone", 0 }; - int fdm; - const char *const *q; - - for (q = clone; *q; q++) { - fdm = open(*q, O_RDWR); - if (fdm >= 0) - break; - } - if (fdm >= 0) { - char *ptr1; - if ((ptr1 = ptsname(fdm)) != NULL) /* Get slave's name */ - /* Return name of slave */ - strlcpy(pts_name, ptr1, pts_name_sz); - else { - close(fdm); - return(-4); - } - if (grantpt(fdm) < 0) { /* Grant access to slave */ - close(fdm); - return(-2); - } - if (unlockpt(fdm) < 0) { /* Clear slave's lock flag */ - close(fdm); - return(-3); - } - return(fdm); /* return fd of master */ - } - return -1; -} - -static int -ptym_open_bsd_flavor(char *pts_name, size_t pts_name_sz, int *streams_pty) -{ - int fdm; - char ptm[MaxPathLen]; - - pty_scan_start(); - - while (pty_scan_next(ptm, sizeof(ptm)) != -1) { - fdm = open(ptm, O_RDWR); - if (fdm < 0) - continue; -#if SunOS == 40 - /* Avoid a bug in SunOS4 ttydriver */ - if (fdm > 0) { - int pgrp; - if ((ioctl(fdm, TIOCGPGRP, &pgrp) == -1) - && (errno == EIO)) - /* All fine */; - else { - close(fdm); - continue; - } - } -#endif - pty_scan_tty(pts_name, sizeof(ptm)); -#if CRAY - /* this is some magic from the telnet code */ - { - struct stat sb; - if(stat(pts_name, &sb) < 0) { - close(fdm); - continue; - } - if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) { - chown(pts_name, 0, 0); - chmod(pts_name, 0600); - close(fdm); - fdm = open(ptm, 2); - if (fdm < 0) - continue; - } - } - /* - * Now it should be safe...check for accessability. - */ - if (access(pts_name, 6) != 0){ - /* no tty side to pty so skip it */ - close(fdm); - continue; - } -#endif - return fdm; /* All done! */ - } - - /* We failed to find BSD style pty */ - errno = ENOENT; - return -1; -} - -/* - * - * Open a master pty either using the STREAM flavor or the BSD flavor. - * Depending on if there are any free ptys in the different classes we - * need to try both. Normally try STREAMS first and then BSD. - * - * Kludge alert: Under HP-UX 10 and perhaps other systems STREAM ptys - * doesn't get initialized properly so we try them in different order - * until the problem has been resolved. - * - */ -static int -ptym_open(char *pts_name, size_t pts_name_sz, int *streams_pty) -{ - int fdm; - -#ifdef HAVE__GETPTY - { - char *p = _getpty(&fdm, O_RDWR, 0600, 1); - if (p) { - *streams_pty = 1; - strlcpy (pts_name, p, pts_name_sz); - return fdm; - } - } -#endif - -#ifdef STREAMSPTY - fdm = ptym_open_streams_flavor(pts_name, pts_name_sz, streams_pty); - if (fdm >= 0) - { - *streams_pty = 1; - return fdm; - } -#endif - - fdm = ptym_open_bsd_flavor(pts_name, pts_name_sz, streams_pty); - if (fdm >= 0) - { - *streams_pty = 0; - return fdm; - } - -#ifndef STREAMSPTY - fdm = ptym_open_streams_flavor(pts_name, pts_name_sz, streams_pty); - if (fdm >= 0) - { - *streams_pty = 1; - return fdm; - } -#endif - - return -1; -} - -static int -maybe_push_modules(int fd, char **modules) -{ -#ifdef I_PUSH - char **p; - int err; - - for(p=modules; *p; p++){ - err=ioctl(fd, I_FIND, *p); - if(err == 1) - break; - if(err < 0 && errno != EINVAL) - return -17; - /* module not pushed or does not exist */ - } - /* p points to null or to an already pushed module, now push all - modules before this one */ - - for(p--; p >= modules; p--){ - err = ioctl(fd, I_PUSH, *p); - if(err < 0 && errno != EINVAL) - return -17; - } -#endif - return 0; -} - -static int -ptys_open(int fdm, char *pts_name, int streams_pty) -{ - int fds; - - if (streams_pty) { - /* Streams style slave ptys */ - if ( (fds = open(pts_name, O_RDWR)) < 0) { - close(fdm); - return(-5); - } - - { - char *ttymodules[] = { "ttcompat", "ldterm", "ptem", NULL }; - char *ptymodules[] = { "pckt", NULL }; - - if(maybe_push_modules(fds, ttymodules)<0){ - close(fdm); - close(fds); - return -6; - } - if(maybe_push_modules(fdm, ptymodules)<0){ - close(fdm); - close(fds); - return -7; - } - } - } else { - /* BSD style slave ptys */ - struct group *grptr; - int gid; - if ( (grptr = getgrnam("tty")) != NULL) - gid = grptr->gr_gid; - else - gid = -1; /* group tty is not in the group file */ - - /* Grant access to slave */ - if (chown(pts_name, getuid(), gid) < 0) - fatal(0, "chown slave tty failed", 1); - if (chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP) < 0) - fatal(0, "chmod slave tty failed", 1); - - if ( (fds = open(pts_name, O_RDWR)) < 0) { - close(fdm); - return(-1); - } - } - return(fds); -} - -int -forkpty_truncate(int *ptrfdm, - char *slave_name, - size_t slave_name_sz, - struct termios *slave_termios, - struct winsize *slave_winsize) -{ - int fdm, fds, streams_pty; - pid_t pid; - char pts_name[20]; - - if (!forkpty_ok) - fatal(0, "Protocol not yet supported, use telnet", 0); - - if ( (fdm = ptym_open(pts_name, sizeof(pts_name), &streams_pty)) < 0) - return -1; - - if (slave_name != NULL) - /* Return name of slave */ - strlcpy(slave_name, pts_name, slave_name_sz); - - pid = fork(); - if (pid < 0) - return(-1); - else if (pid == 0) { /* Child */ - if (setsid() < 0) - fatal(0, "setsid() failure", errno); - - revoke(slave_name); - -#if defined(NeXT) || defined(ultrix) - /* The NeXT is severely broken, this makes things slightly - * better but we still doesn't get a working pty. If there - * where a TIOCSCTTY we could perhaps fix things but... The - * same problem also exists in xterm! */ - if (setpgrp(0, 0) < 0) - fatal(0, "NeXT kludge failed setpgrp", errno); -#endif - - /* SVR4 acquires controlling terminal on open() */ - if ( (fds = ptys_open(fdm, pts_name, streams_pty)) < 0) - return -1; - close(fdm); /* All done with master in child */ - -#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(__hpux) - /* 44BSD way to acquire controlling terminal */ - /* !CIBAUD to avoid doing this under SunOS */ - if (ioctl(fds, TIOCSCTTY, (char *) 0) < 0) - return -1; -#endif -#if defined(NeXT) - { - int t = open("/dev/tty", O_RDWR); - if (t < 0) - fatal(0, "Failed to open /dev/tty", errno); - close(fds); - fds = t; - } -#endif - /* Set slave's termios and window size */ - if (slave_termios != NULL) { - if (tcsetattr(fds, TCSANOW, slave_termios) < 0) - return -1; - } -#ifdef TIOCSWINSZ - if (slave_winsize != NULL) { - if (ioctl(fds, TIOCSWINSZ, slave_winsize) < 0) - return -1; - } -#endif - /* slave becomes stdin/stdout/stderr of child */ - if (dup2(fds, STDIN_FILENO) != STDIN_FILENO) - return -1; - if (dup2(fds, STDOUT_FILENO) != STDOUT_FILENO) - return -1; - if (dup2(fds, STDERR_FILENO) != STDERR_FILENO) - return -1; - if (fds > STDERR_FILENO) - close(fds); - return(0); /* child returns 0 just like fork() */ - } - else { /* Parent */ - *ptrfdm = fdm; /* Return fd of master */ - return(pid); /* Parent returns pid of child */ - } -} - -int -forkpty(int *ptrfdm, - char *slave_name, - struct termios *slave_termios, - struct winsize *slave_winsize) -{ - return forkpty_truncate (ptrfdm, - slave_name, - MaxPathLen, - slave_termios, - slave_winsize); -} - -#endif /* HAVE_FORKPTY */ |