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

📄 gap2d.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char RCSid[] = "$Header: gap2d.c,v 2.0 85/11/21 07:23:00 jqj Exp $";#endif/* * server for GAP-style (TransportObject=server,teletype) telnet connections * Note that we support only GAP version 2, although a server for version 3 * exists.  The version 2 server has not been tested as thoroughly as has the * version 3; it does NOT support RESERVE functionality. *//* $Log:	gap2d.c,v $ * Revision 2.0  85/11/21  07:23:00  jqj * 4.3BSD standard release *  * Revision 1.2  85/05/23  06:22:18  jqj * *** empty log message *** *  * 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 "GAP2.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%s"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];char wsenv[50];/* * 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_GAP2_Delete(_buf);			break;		case 2:			server_GAP2_Create(_buf);			net = _serverConnection->fd;			gaptelnet(); /* returns on connection close */			break;		case 0:			server_GAP2_Reset(_buf);			break;		default:			NoSuchProcedureValue("GAP", _procedure);			break;		} HANDLER {		    Deallocate(_buf);		    switch (Exception.Code) {		    case GAP2_terminalAddressInvalid:		    case GAP2_terminalAddressInUse:		    case GAP2_controllerDoesNotExist:		    case GAP2_controllerAlreadyExists:		    case GAP2_gapCommunicationError:		    case GAP2_gapNotExported:		    case GAP2_bugInGAPCode:		    case GAP2_tooManyGateStreams:		    case GAP2_inconsistentParams:		    case GAP2_transmissionMediumUnavailable:		    case GAP2_dialingHardwareProblem:		    case GAP2_noDialingHardware:		    case GAP2_badAddressFormat:		    case GAP2_mediumConnectFailed:		    case GAP2_illegalTransport:		    case GAP2_noCommunicationHardware:		    case GAP2_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 != 2)				ExecCourierProgram(programnum, versionnum,						skipcount, skippedwords);		}  /* loop if can't exec that program */	}}voidGAP2_Delete(session)	GAP2_SessionHandle session; {}voidGAP2_Reset(){}GAP2_CreateResultsGAP2_Create(conn, BDTproc, sessionparams, transports,	    createTimeout)	CourierConnection *conn;	int BDTproc;	GAP2_SessionParameterObject sessionparams;	struct {Cardinal length;		GAP2_TransportObject *sequence;	} transports;	GAP2_WaitTime createTimeout;{	GAP2_CreateResults result;	char *c1, *c2, *host;	int t, pid;	struct sgttyb b;	char *xntoa(), *wsname();	struct sockaddr_ns who;	int whosize = sizeof(who);	LongCardinal servicetype;	GAP2_CommParamObject *cp;	GAP2_Duplexity duplexity;	/* fullDuplex, halfDuplex */#ifdef DEBUG	BUGOUT("CREATE");#endif	switch (sessionparams.designator) {	case ttyHost:		frametimeout = sessionparams.ttyHost_case.frameTimeout/1000;		/* could set other parameters here */		break;	default:		raise(GAP2_unimplemented, 0);		/*NOTREACHED*/	}	if (transports.length != 2) {		raise(GAP2_illegalTransport);		/*NOTREACHED*/	}	switch (transports.sequence[0].designator) {	case rs232c:	/* maybe some day */		cp = &transports.sequence[0].rs232c_case.commParams;		if (cp->accessDetail.designator == directConn) {			duplexity = cp->duplex;			servicetype = 0; /* fake it */			break;		}		raise(GAP2_noCommunicationHardware, 0);		/*NOTREACHED*/	default:		raise(GAP2_illegalTransport, 0);		/*NOTREACHED*/	}	if (transports.sequence[1].designator != teletype)	  raise(GAP2_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(GAP2_tooManyGateStreams, 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 == 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(GAP2_tooManyGateStreams, 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";		(void)sprintf(wsenv, "WORKSTATION=%s", xntoa(who.sns_addr));		envinit[1] = wsenv;		envinit[2] = (char*) 0;#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();	int ibits = 0, obits = 0;	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);	/*	 * 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		ibits = obits = 0;		/*		 * Never look for input if there's still		 * stuff in the corresponding output buffer		 */		if (nfrontp - nbackp || pcc > 0)			obits |= (1 << net);		else			ibits |= (1 << pty);		if (pfrontp - pbackp || ncc > 0)			obits |= (1 << pty);		else			ibits |= (1 << net);		if (ncc < 0 && pcc < 0)			break;		timeout.tv_sec = 600;		timeout.tv_usec = 0;		select(16, &ibits, &obits, 0, &timeout);		if (ibits == 0 && obits == 0) {			/* timeout means no activity for a long time */#ifdef DEBUG			BUGOUT("timeout from select");#endif			if (keepalives++ < 2) {			  /* first 2 times through send warning */				if (nfrontp == nbackp && pcc == 0) {					/* but only if not blocked on output */#define WARNING "\r\nYou've been idle much too long.  Respond or log off.\r\n"					strcpy(nfrontp, WARNING);					nfrontp += sizeof(WARNING);				}				sleep(5);				continue;			}#ifdef DEBUG			BUGOUT("keepalive expired -- calling cleanup");#endif			/* keepalive count has expired */			cleanup();			return(1);		}		/*		 * Something to read from the network...		 */		if (ibits & (1 << net)) {			ncc = read(net, buf, sizeof(buf));#ifdef DEBUG			BUGOUT("read from net %d",ncc);

⌨️ 快捷键说明

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