int PseudoTTY (char pty_name[]) { int fd; char *slave, *master; fd = getpseudotty(&slave, &master); if (fd < 0) return fd; safeStrCpy(pty_name, slave, sizeof(pty_name)/sizeof(pty_name[0])); return fd; }
int OpenPTY(char **ttyn) { char *m, *s; register int f; if ((f = getpseudotty(&s, &m)) < 0) return -1; #ifdef _SEQUENT_ fvhangup(s); #endif strncpy(PtyName, m, sizeof(PtyName)); strncpy(TtyName, s, sizeof(TtyName)); initmaster(f); *ttyn = TtyName; return f; }
int OpenPTY(char **ttyn) { char *m, *s; int f; /* used for opening a new pty-pair: */ static char PtyName[32]; static char TtyName[32]; if ((f = getpseudotty(&s, &m)) < 0) return -1; #ifdef _SEQUENT_ fvhangup(s); #endif vim_strncpy((char_u *)PtyName, (char_u *)m, sizeof(PtyName) - 1); vim_strncpy((char_u *)TtyName, (char_u *)s, sizeof(TtyName) - 1); initmaster(f); *ttyn = TtyName; return f; }
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); }
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 }
int main(int argc, char **argv, char **envp) { struct in_addr inetaddr; int callmgr_sock = -1; char ptydev[PTYMAX], ttydev[TTYMAX]; int pty_fd = -1; int gre_fd = -1; static volatile pid_t child_pid; u_int16_t call_id, peer_call_id; #ifdef EMBED openlog(argv[0],LOG_PID,LOG_USER); #endif if (argc < 2) usage(argv[0]); /* Step 1: Get IP address for the hostname in argv[1] */ for (;;) { inetaddr = get_ip_address(argv[1]); if(inetaddr.s_addr != 0) break; sleep(RESPAWN_DELAY); } /* * open the GRE socket early so that we do not get * ENOPROTOOPT errors if the other end responds too * quickly to our initial connection */ gre_fd = socket(AF_INET, SOCK_RAW, PPTP_PROTO); if (gre_fd < 0) { pptp_error("socket: %s\n", strerror(errno)); sleep(RESPAWN_DELAY); exit(1); } for (;;) { /* Step 2: Open connection to call manager * (Launch call manager if necessary.) */ callmgr_sock = open_callmgr(inetaddr, argc,argv,envp); if(callmgr_sock < 0){ close(gre_fd); pptp_error("Could not open connection to call manager - terminating"); sleep(RESPAWN_DELAY); exit(1); } pptp_debug("callmgr opened - fd = %x", callmgr_sock); /* Step 5: Exchange PIDs, get call ID */ if (get_call_id(callmgr_sock, getpid(), &call_id, &peer_call_id) >= 0) break; close(callmgr_sock); } /* Step 3: Find an open pty/tty pair. */ pty_fd = getpseudotty(ttydev, ptydev); if (pty_fd < 0) { close(gre_fd); close(callmgr_sock); pptp_error("Could not find free pty."); sleep(RESPAWN_DELAY); exit(1); } pptp_debug("got a free ttydev"); /* Step 4: fork and wait. */ signal(SIGUSR1, do_nothing); /* don't die */ switch (child_pid = vfork()) { case -1: signal(SIGUSR1, SIG_DFL); pptp_debug("vfork failed %s", strerror(errno)); sleep(RESPAWN_DELAY); goto shutdown; case 0: /* I'm the child! */ // signal(SIGUSR1, SIG_DFL); pptp_debug("entered child"); pptp_debug("callids established.."); close(callmgr_sock); close(gre_fd); close(pty_fd); launch_pppd(ttydev, argc-2, argv+2); /* launch pppd */ sleep(RESPAWN_DELAY); exit(1); /* in case launch_pppd returns */ break; default: /* parent */ /* * There is still a very small race condition here. If a signal * occurs after signaled is checked but before pause is called, * things will hang. */ #if 0 if (!signaled) { pause(); /* wait for the signal */ } pptp_error("Error %s", strerror(errno)); #endif /*0*/ break; } #if 0 /* Step 5b: Send signal to wake up pppd task */ kill(parent_pid, SIGUSR1); sleep(2); #endif /*0*/ if (sigsetjmp(env, 1)!=0) goto shutdown; signal(SIGINT, sighandler); signal(SIGTERM, sighandler); signal(SIGKILL, sighandler); { char buf[128]; snprintf(buf, sizeof(buf), "pptp: GRE-to-PPP gateway on %s", ptydev); inststr(argc,argv,envp, buf); } /* Step 6: Do GRE copy until close. */ pptp_gre_copy(peer_call_id, call_id, pty_fd, gre_fd, inetaddr); shutdown: /* Make sure pppd exits as well */ if (child_pid > 0) kill(child_pid, SIGTERM); if (gre_fd != -1) close(gre_fd); if (pty_fd != -1) close(pty_fd); if (callmgr_sock != -1) close(callmgr_sock); exit(0); }