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

📄 rlogin.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1983, 1990 The Regents of the University of California. * 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. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1983, 1990 The Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lint#ifdef IDstatic char sccsid[] = "@(#)rlogin.c	5.33 (Berkeley) 3/1/91";#endif#endif /* not lint *//* * $Source: mit/rlogin/RCS/rlogin.c,v $ * $Header: mit/rlogin/RCS/rlogin.c,v 5.2 89/07/26 12:11:21 kfall *	Exp Locker: kfall $ *//* * rlogin - remote login */#include <sys/ioctl.h>#include <sys/types.h>#include <sys/wait.h>#include <net/netlib.h>#include <net/hton.h>#include <net/gen/in.h>#include <net/gen/netdb.h>#include <net/gen/tcp.h>#include <net/gen/tcp_io.h>#include <termios.h>#include <setjmp.h>#include <errno.h>#include <pwd.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <assert.h>#include <ctype.h>#include <fcntl.h>#include <signal.h>#include <stdlib.h>#if __minixtypedef unsigned char u_char;#endif#ifdef KERBEROS#include <kerberosIV/des.h>#include <kerberosIV/krb.h>CREDENTIALS cred;Key_schedule schedule;int use_kerberos = 1, doencrypt;char dst_realm_buf[REALM_SZ], *dest_realm = NULL;extern char *krb_realmofhost();#endif#ifndef TIOCPKT_WINDOW#define	TIOCPKT_WINDOW	0x80#endif/* concession to Sun */#ifndef SIGUSR1#define	SIGUSR1	30#endif/* standard Minix doesn't really have SIGCHLD */#if __minix && !__minix_vmd#undef SIGCHLD#define SIGCHLD SIGTERM#endifextern int errno;int eight, litout, rem;int noescape;u_char escapechar = '~';struct speed{	speed_t speed;	char *name;} speeds[] = {	{ B0, "0" }, { B50, "50" }, { B75, "75" }, { B110, "110" }, 	{ B134, "134" }, { B150, "150" }, { B200, "200" }, { B300, "300" }, 	{ B600, "600" }, { B1200, "1200" }, { B1800, "1800" }, 	{ B2400, "2400" }, { B4800, "4800" }, { B9600, "9600" }, 	{ B19200, "19200" }, { B38400, "38400" }, { B57600, "57600" },	{ B115200, "115200" },	{ -1, NULL },};#if __minix_vmd/* flow control variables */int more2read_0;int inprogress_0;int more2write_1;int inprogress_1;int more2read_rem;int inprogress_rd_rem;int more2write_rem;int inprogress_wr_rem;/* write to remote */size_t wr_rem_size;size_t wr_rem_offset;size_t extra_wr_rem_size;size_t extra_wr_rem_offset;char *extra_wr_rem;size_t extra_wr_rem_new_size;char *extra_wr_rem_new;#endif /* __minix_vmd */struct	winsize winsize;#define	get_window_size(fd, wp)	ioctl(fd, TIOCGWINSZ, wp)extern int main _ARGS(( int argc, char **argv ));static void usage _ARGS(( void ));static u_char getescape _ARGS(( char *p ));static char *speeds2str _ARGS(( speed_t speed ));static void lostpeer _ARGS(( int sig ));static void doit _ARGS(( void ));static void setsignal _ARGS(( int sig, void (*act)(int sig) ));static void msg _ARGS(( char *str ));static void done _ARGS(( int status ));#if !__minix_vmdstatic int reader _ARGS(( void ));#endifstatic void mode _ARGS(( int f ));#if __minix_vmdstatic void mark_async _ARGS(( int fd ));static void init_0 _ARGS(( void ));static void init_1 _ARGS(( void ));static void init_rd_rem _ARGS(( void ));static void init_wr_rem _ARGS(( void ));static void restart_0 _ARGS(( void ));static void restart_1 _ARGS(( void ));static void restart_rd_rem _ARGS(( void ));static void restart_wr_rem _ARGS(( void ));static void completed_0 _ARGS(( int result, int error ));static void completed_1 _ARGS(( int result, int error ));static void completed_rd_rem _ARGS(( int result, int error ));static void completed_wr_rem _ARGS(( int result, int error ));static void do_urg _ARGS(( int urg_byte ));#endif#if !__minix_vmdstatic void catch_child _ARGS(( int sig ));static void writer _ARGS(( void ));#endifstatic void echo _ARGS(( int c ));#if __minix_vmdstatic void finish _ARGS(( void ));static void sendwindow _ARGS(( void ));static void sigwinch _ARGS(( int sig ));static void subshell _ARGS(( void ));#endifint main(argc, argv)	int argc;	char **argv;{	extern char *optarg;	extern int optind;	struct passwd *pw;	struct servent *sp;	struct termios ttyb;#if __minix_vmd	nwio_tcpopt_t tcpopt;	int error;#endif	int argoff, ch, dflag, one, uid;	char *host, *p, *user, term[1024];	argoff = dflag = 0;	one = 1;	host = user = NULL;	if (p = rindex(argv[0], '/'))		++p;	else		p = argv[0];	if (strcmp(p, "rlogin"))		host = p;	/* handle "rlogin host flags" */	if (!host && argc > 2 && argv[1][0] != '-') {		host = argv[1];		argoff = 1;	}#ifdef KERBEROS#define	OPTIONS	"8EKLde:k:l:x"#else#define	OPTIONS	"8EKLde:l:"#endif	while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF)		switch(ch) {		case '8':			eight = 1;			break;		case 'E':			noescape = 1;			break;		case 'K':#ifdef KERBEROS			use_kerberos = 0;#endif			break;		case 'L':			litout = 1;			break;		case 'd':			dflag = 1;			break;		case 'e':			escapechar = getescape(optarg);			break;#ifdef KERBEROS		case 'k':			dest_realm = dst_realm_buf;			(void)strncpy(dest_realm, optarg, REALM_SZ);			break;#endif		case 'l':			user = optarg;			break;#ifdef CRYPT#ifdef KERBEROS		case 'x':			doencrypt = 1;			des_set_key(cred.session, schedule);			break;#endif#endif		case '?':		default:			usage();		}	optind += argoff;	argc -= optind;	argv += optind;	/* if haven't gotten a host yet, do so */	if (!host && !(host = *argv++))		usage();	if (*argv)		usage();	if (!(pw = getpwuid(uid = getuid()))) {		(void)fprintf(stderr, "rlogin: unknown user id.\n");		exit(1);	}	if (!user)		user = pw->pw_name;	sp = NULL;#ifdef KERBEROS	if (use_kerberos) {		sp = getservbyname((doencrypt ? "eklogin" : "klogin"), "tcp");		if (sp == NULL) {			use_kerberos = 0;			warning("can't get entry for %s/tcp service",			    doencrypt ? "eklogin" : "klogin");		}	}#endif	if (sp == NULL)		sp = getservbyname("login", "tcp");	if (sp == NULL) {		(void)fprintf(stderr, "rlogin: login/tcp: unknown service.\n");		exit(1);	}	(void)strcpy(term, (p = getenv("TERM")) ? p : "network");	if (tcgetattr(0, &ttyb) == 0) {		(void)strcat(term, "/");		(void)strcat(term, speeds2str(cfgetospeed(&ttyb)));	}	(void)get_window_size(0, &winsize);	(void)signal(SIGPIPE, lostpeer);#ifdef KERBEROStry_connect:	if (use_kerberos) {		rem = KSUCCESS;		errno = 0;		if (dest_realm == NULL)			dest_realm = krb_realmofhost(host);#ifdef CRYPT		if (doencrypt)			rem = krcmd_mutual(&host, sp->s_port, user, term, 0,			    dest_realm, &cred, schedule);		else#endif /* CRYPT */			rem = krcmd(&host, sp->s_port, user, term, 0,			    dest_realm);		if (rem < 0) {			use_kerberos = 0;			sp = getservbyname("login", "tcp");			if (sp == NULL) {				(void)fprintf(stderr,				    "rlogin: unknown service login/tcp.\n");				exit(1);			}			if (errno == ECONNREFUSED)				warning("remote host doesn't support Kerberos");			if (errno == ENOENT)				warning("can't provide Kerberos auth data");			goto try_connect;		}	} else {#ifdef CRYPT		if (doencrypt) {			(void)fprintf(stderr,			    "rlogin: the -x flag requires Kerberos authentication.\n");			exit(1);		}#endif /* CRYPT */		rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);	}#else	rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);#endif /* KERBEROS */	if (rem < 0)		exit(1);#if __minix_vmd	/* Enable BSD compatibility for urgent data. */	tcpopt.nwto_flags= NWTO_BSD_URG;	error= ioctl(rem, NWIOSTCPOPT, &tcpopt);	if (error == -1)	{		fprintf(stderr, "rlogin: NWIOSTCPOPT failed: %s\n",			strerror(errno));	}#endif	(void)setuid(uid);	doit();	/*NOTREACHED*/}struct termios defattr, rawattr;#if __minix_vmdint mustsendwindow;#elseint child;#endifstatic voiddoit(){	struct termios sb;#if !__minix_vmd	int r;#else	asio_fd_set_t fd_set;	struct fwait fw;	int result;#endif	(void)tcgetattr(0, &sb);	defattr = sb;	rawattr = sb;	rawattr.c_iflag &= ~(ICRNL | IGNCR | INLCR | ISTRIP | IXOFF | IXON | 							PARMRK | IXANY);	rawattr.c_oflag &= ~(OPOST);	rawattr.c_lflag &= ~(ECHONL | ECHO | ICANON | IEXTEN | ISIG);	(void)signal(SIGINT, SIG_IGN);	setsignal(SIGHUP, exit);	setsignal(SIGQUIT, exit);#if !__minix_vmd	child = fork();	if (child == -1) {		(void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno));		done(1);	}	if (child == 0) {		mode(1);		r = reader();		if (r == 0) {			msg("connection closed.");#if __minix && !__minix_vmd			kill(getppid(), SIGCHLD);#endif			exit(0);		}		sleep(1);		msg("\007connection closed.");#if __minix && !__minix_vmd		kill(getppid(), SIGCHLD);#endif		exit(1);	}	(void)signal(SIGCHLD, catch_child);	writer();#else /* __minix_vmd */	mode(1);	/* mark the file descriptors 0, 1, and rem as asynchronous. */	mark_async(0);	mark_async(1);	mark_async(rem);	init_0();	init_1();	init_rd_rem();	init_wr_rem();	for (;;)	{		ASIO_FD_ZERO(&fd_set);		fw.fw_flags= 0;		fw.fw_bits= fd_set.afds_bits;		fw.fw_maxfd= ASIO_FD_SETSIZE;		if (more2read_0 && !inprogress_0)		{			restart_0();			fw.fw_flags |= FWF_NONBLOCK;		}		if (more2write_1 && !inprogress_1)		{			restart_1();			fw.fw_flags |= FWF_NONBLOCK;		}		if (more2read_rem && !inprogress_rd_rem)		{			restart_rd_rem();			fw.fw_flags |= FWF_NONBLOCK;		}		if (more2write_rem && !inprogress_wr_rem)		{			restart_wr_rem();			fw.fw_flags |= FWF_NONBLOCK;		}		if (more2read_0 && inprogress_0)			ASIO_FD_SET(0, ASIO_READ, &fd_set);		if (more2write_1 && inprogress_1)			ASIO_FD_SET(1, ASIO_WRITE, &fd_set);		if (more2read_rem && inprogress_rd_rem)			ASIO_FD_SET(rem, ASIO_READ, &fd_set);		if (more2write_rem && inprogress_wr_rem)			ASIO_FD_SET(rem, ASIO_WRITE, &fd_set);		for (;;)		{			result= fwait(&fw);			if (result == -1 && (errno == EAGAIN || 							errno == EINTR))			{				break;			}			if (result == -1)			{				fprintf(stderr, "fwait failed (%s)\n", 							strerror(errno));				exit(1);			}			assert(result == 0);#if 0printf("fwait: fw_fw= %d, fw_operation= %d, fw_result= %d, fw.fw_errno= %d\n",	fw.fw_fd, fw.fw_operation, fw.fw_result, fw.fw_errno);#endif			if (fw.fw_fd == 0 && fw.fw_operation == ASIO_READ)			{				completed_0(fw.fw_result, fw.fw_errno);			}			else if (fw.fw_fd == 1 && 					fw.fw_operation == ASIO_WRITE)			{				completed_1(fw.fw_result, fw.fw_errno);			}			else if (fw.fw_fd == rem && 					fw.fw_operation == ASIO_READ)			{				completed_rd_rem(fw.fw_result, fw.fw_errno);			}			else if (fw.fw_fd == rem && 					fw.fw_operation == ASIO_WRITE)			{				completed_wr_rem(fw.fw_result, fw.fw_errno);			}			else			{				fprintf(stderr,			"strange result from fwait: fd= %d, operation= %d\n",					fw.fw_fd, fw.fw_operation);				exit(1);			}			if (!(fw.fw_flags & FWF_MORE))				break;		}		if (mustsendwindow)		{			mustsendwindow= 0;			sendwindow();		}	}#endif /* __minix_vmd */	msg("connection closed.");	done(0);}/* trap a signal, unless it is being ignored. */static voidsetsignal(sig, act)	int sig;	void (*act) _ARGS(( int sig ));{	if (signal(sig, act) == SIG_IGN)		(void)signal(sig, SIG_IGN);}static voiddone(status)	int status;{	int w, wstatus;	mode(0);#if !__minix_vmd	if (child > 0) {		/* make sure catch_child does not snap it up */		(void)signal(SIGCHLD, SIG_DFL);		if (kill(child, SIGKILL) >= 0)			while ((w = wait(&wstatus)) > 0 && w != child);	}#endif	exit(status);}int dosigwinch;#if !__minixvoid sigwinch();#endif

⌨️ 快捷键说明

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