⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gaptelnetd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char RCSid[] = "$Header: gaptelnetd.c,v 2.4 86/10/20 12:00:04 root Exp $";#endif/* * server for GAP-style (TransportObject=server,teletype) telnet connections * Note that we support only GAP version 3 *//* $Log:	gaptelnetd.c,v $ * Revision 2.4  86/10/20  12:00:04  root * Fix bug (finally) causing delayed close of connections when UNIX logs out. *  * Revision 2.3  86/10/11  12:39:53  jqj * Fixes from Bill Jackson:  put lower fork in correct tty and process * group -- required for real 4.3 release. *  * Revision 2.2  86/09/12  09:50:28  jqj * Fixes for 4.3bsd: * 	1/ added setpgrp(0,0) to make csh happy (symptom was that chat * sessions would work only if default shell was /bin/sh). * 	2/ change to FD_ macros since ibits and obits can now be more than * 32 bits long (we could have more than 32 open descriptors in principal). *  * Revision 2.1  86/05/16  11:04:00  jqj * fix to correspond to new semantics for enumerations (global) *  * Revision 2.0  85/11/21  07:23:06  jqj * 4.3BSD standard release *  * Revision 1.3  85/11/21  06:53:22  jqj * symbolic values for connection type *  * Revision 1.2  85/11/08  17:17:13  bill * version on bullwinkle *  * Revision 1.3  85/08/05  09:58:00  jqj * fixed for Interlisp -- data from Interlisp appears with dt==0 (wrong!) * also, Interlisp trys to connect to a tty rather than a ttyHost. * increased inactivity timeout to 4 hrs * * Revision 1.2  85/05/23  06:22:18  jqj * *** empty log message *** *  * Revision 1.1  85/05/22  09:46:52  jqj * Initial revision */#include <stdio.h>#include <signal.h>#include <sgtty.h>#include <sys/types.h>#include <sys/time.h>#include <sys/uio.h>#include <sys/socket.h>#include <netns/ns.h>#include <netns/idp.h>#include <netns/sp.h>#include <sys/wait.h>#include <xnscourier/realcourierconnection.h>#include "GAP3.h"#include "gapcontrols.h"#include <xnscourier/except.h>#include <errno.h>#define	BELL	'\07'#define BANNER	"\r\n\r\n4.3 BSD UNIX (%s)\r\n\r\r\n\r"int pty, net;extern CourierConnection *_serverConnection;char buf[sizeof(struct sphdr)+SPPMAXDATA];struct sphdr our_sphdr;struct iovec our_iovec[2] = {{((caddr_t)&our_sphdr), sizeof(our_sphdr)}};/* * I/O data buffers, pointers, and counters. */char	ptyibuf[512], *ptyip = ptyibuf;char	ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf;char	*netip = buf;char	netobuf[512], *nfrontp = netobuf, *nbackp = netobuf;int	pcc, ncc;char	line[12];extern	char **environ;extern	int errno;char *envinit[3];/* * session parameters */Cardinal frametimeout;		/* 0 or time in seconds to wait *//* * This modified version of the server is necessary since GAP specifies * that the telnet data-transfer session occurs after the RPC to create * it has returned! */Server(skipcount,skippedwords)	int skipcount;	Unspecified skippedwords[];{	Cardinal _procedure;	register Unspecified *_buf;	LongCardinal programnum;	Cardinal versionnum;	Cardinal _n;#ifdef DEBUG	BUGOUT("Server: %d %d",skipcount,skippedwords);#endif	for (;;) {		_buf = ReceiveCallMessage(&_procedure, skipcount, skippedwords);		DURING switch (_procedure) {		case 3:			server_GAP3_Delete(_buf);			break;		case 2:			server_GAP3_Create(_buf);			net = _serverConnection->fd;			gaptelnet(); /* returns on connection close */			break;		case 0:			server_GAP3_Reset(_buf);			break;		default:			NoSuchProcedureValue("GAP", _procedure);			break;		} HANDLER {		    Deallocate(_buf);		    switch (Exception.Code) {		    case GAP3_serviceNotFound:		    case GAP3_userNotAuthorized:		    case GAP3_userNotAuthenticated:		    case GAP3_serviceTooBusy:		    case GAP3_terminalAddressInvalid:		    case GAP3_terminalAddressInUse:		    case GAP3_controllerDoesNotExist:		    case GAP3_controllerAlreadyExists:		    case GAP3_gapCommunicationError:		    case GAP3_gapNotExported:		    case GAP3_bugInGAPCode:		    case GAP3_tooManyGateStreams:		    case GAP3_inconsistentParams:		    case GAP3_transmissionMediumUnavailable:		    case GAP3_dialingHardwareProblem:		    case GAP3_noDialingHardware:		    case GAP3_badAddressFormat:		    case GAP3_mediumConnectFailed:		    case GAP3_illegalTransport:		    case GAP3_noCommunicationHardware:		    case GAP3_unimplemented:			_buf = Allocate(0);			SendAbortMessage(Exception.Code-ERROR_OFFSET, 0, _buf);			break;		    default:			_buf = Allocate(0);			SendRejectMessage(unspecifiedError, 0, _buf);			break;		    }		} END_HANDLER;		Deallocate(_buf);		for (;;) {			skipcount = LookAheadCallMsg(&programnum, &versionnum,					skippedwords);			if (skipcount < 0) return(0);	/* timed out */			if (programnum != 3 || versionnum != 3)				ExecCourierProgram(programnum, versionnum,						skipcount, skippedwords);		}  /* loop if can't exec that program */	}}voidGAP3_Delete(session)	GAP3_SessionHandle session; {}voidGAP3_Reset(){}GAP3_CreateResultsGAP3_Create(conn, BDTproc, sessionparams, transports,	    createTimeout, credentials, verifier)	CourierConnection *conn;	int BDTproc;	GAP3_SessionParameterObject sessionparams;	struct {Cardinal length;		GAP3_TransportObject *sequence;	} transports;	GAP3_WaitTime createTimeout;	Authentication1_Credentials credentials;	Authentication1_Verifier verifier;{	GAP3_CreateResults result;	char *c1, *c2, *host;	int t, pid, mypid;	struct sgttyb b;	char *wsname();	struct sockaddr_ns who;	int whosize = sizeof(who);	LongCardinal servicetype;	GAP3_CommParamObject *cp;	GAP3_Duplexity duplexity;	/* fullDuplex, halfDuplex */#ifdef DEBUG	BUGOUT("CREATE");#endif	switch (sessionparams.designator) {	case GAP3_oldTty:	case GAP3_oldTtyHost:		frametimeout = sessionparams.GAP3_oldTtyHost_case.frameTimeout/1000;		/* could set other parameters here */		break;	case GAP3_tty:	case GAP3_ttyHost:		frametimeout = sessionparams.GAP3_ttyHost_case.frameTimeout/1000;		/* could set other parameters here */		break;	default:		raise(GAP3_unimplemented, 0);		/*NOTREACHED*/	}	if (transports.length != 2) {		raise(GAP3_illegalTransport);		/*NOTREACHED*/	}	switch (transports.sequence[0].designator) {	case GAP3_service:		servicetype = transports.sequence[0].GAP3_service_case.id;		switch (servicetype) {		case TTYService_any:		/* 0 */			servicetype = TTYService_sa;		case TTYService_sa:		/* 1 */		case TTYService_exec:		/* 2 */		case TTYService_its:		/* 3 */			break;		default:			raise(GAP3_serviceNotFound, 0);			/*NOTREACHED*/		}		duplexity = GAP3_fullduplex;/* services are allways fulldup */		break;	case GAP3_rs232c:	/* maybe some day */		cp = &transports.sequence[0].GAP3_rs232c_case.commParams;		if (cp->accessDetail.designator == GAP3_directConn) {			duplexity = cp->accessDetail.GAP3_directConn_case.duplex;			servicetype = TTYService_sa; /* fake it */			break;		}		raise(GAP3_noCommunicationHardware, 0);		/*NOTREACHED*/	default:		raise(GAP3_illegalTransport, 0);		/*NOTREACHED*/	}	if (transports.sequence[1].designator != GAP3_teletype)	  raise(GAP3_illegalTransport, 0);	/* ignore createTimeout */	/* ignore credentials and verifier */		for (c1 = "pq"; *c1 != 0; c1++)	  for (c2 = "0123456789abcdef"; *c2 != 0; c2++) {		  sprintf(line, "/dev/pty%c%c", *c1, *c2);		  pty = open(line, 2);		  if (pty < 0) continue;		  line[strlen("/dev/")] = 't';		  t = open(line, 2);		  if (t > 0) goto gotpty;		  close(pty);	  }	raise(GAP3_serviceTooBusy, 0);	/*NOTREACHED*/ gotpty:	getpeername(_serverConnection->fd, &who, &whosize);	host = wsname(who.sns_addr);#ifdef DEBUG	BUGOUT("gotpty <%s> %d <%s>",line, pty, host);#endif	ioctl(t, TIOCGETP, &b);	b.sg_flags = CRMOD|XTABS|ANYP;	ioctl(t, TIOCSETP, &b);	ioctl(pty, TIOCGETP, &b);	if (duplexity == GAP3_fullduplex)	  b.sg_flags |= ECHO;	else	  b.sg_flags &= ~ECHO;	ioctl(pty, TIOCSETP, &b);	/* we do the fork now so we can return failures as REPORTS */	pid = fork();	if (pid < 0) {		close(pty); close(t);		raise(GAP3_serviceTooBusy, 0);		/*NOTREACHED*/	}	else if (pid == 0) {	/* in the execed fork */		sleep(1);	/* let parent get ready for us */		close(_serverConnection->fd); /* close net */		close(pty);		dup2(t, 0);		dup2(t, 1);		dup2(t, 2);		if (t > 2) close(t);		envinit[0] = "TERM=network";		envinit[1] = (char*) 0;		mypid = getpid();		(void) ioctl( 0, TIOCSPGRP, (char *)&mypid );		(void) setpgrp(0, mypid);#ifdef DEBUG		BUGOUT("about to exec /bin/login");#endif		execl("/bin/login","login", "-h", host, 0);#ifdef DEBUG		BUGOUT("exec of /bin/login failed");#endif		perror("/bin/login");		exit(1);		/*NOTREACHED*/	}	close(t);#ifdef DEBUG	BUGOUT("fork successful");#endif	result.session[0] = pid;	return(result);}jmp_buf childdiedbuf;/* * Main loop.  Select from pty and network, and * hand data to telnet receiver finite state machine. * Returns 0 on orderly shutdown, 1 on abnormal shutdown. */gaptelnet(){	int on = 1;	char hostname[32];	int childdied();	fd_set ibits, obits;	register int c;	struct sphdr *si = (struct sphdr *)buf;	static struct timeval timeout = {600,0};	int keepalives = 0;	int i;#ifdef DEBUG	BUGOUT("gaptelnet net=%d,pty=%d",net,pty);#endif	if (setjmp(childdiedbuf) != 0)	  return(0);		/* child died */	signal(SIGCHLD, childdied);	signal(SIGTSTP, SIG_IGN);	ioctl(net, FIONBIO, &on);	ioctl(pty, FIONBIO, &on);	(void) setpgrp(0, 0);	/*	 * Show banner that getty never gave.	 */	gethostname(hostname, sizeof (hostname));	sprintf(nfrontp, BANNER, hostname);	nfrontp += strlen(nfrontp);	/*	 * Send status message indicating we're ready to go	 */	changeSPPopts(net, GAPCTLnone, 1);	sendoobdata(GAPCTLmediumUp);	for (;;) {#ifdef DEBUG		BUGOUT("looping in gaptelnet");#endif		if (ncc < 0 && pcc < 0)			break;		FD_ZERO(&ibits);		FD_ZERO(&obits);		/*		 * Never look for input if there's still		 * stuff in the corresponding output buffer		 */		if (nfrontp - nbackp || pcc > 0)			FD_SET(net, &obits);		else			FD_SET(pty, &ibits);		if (pfrontp - pbackp || ncc > 0)			FD_SET(pty, &obits);		else			FD_SET(net, &ibits);		timeout.tv_sec = 14400;		/* 4 hrs. */		timeout.tv_usec = 0;		if ((c = select(16, &ibits, &obits, 0, &timeout)) < 1) {			if (c < 0) {				if (errno != EINTR) {					sleep(5);				}				continue;			}			/* ASSERT(ibits == 0 && obits == 0); */			/* timeout means no activity for a long time */#ifdef DEBUG			BUGOUT("timeout from select");#endif			if (keepalives++ < 2) {			  /* first time through send warning */				if (nfrontp == nbackp && pcc == 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -