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

📄 rlogin.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983, 1990, 1993 *	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 lintstatic char copyright[] ="@(#) Copyright (c) 1983, 1990, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)rlogin.c	8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * rlogin - remote login */#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/wait.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <errno.h>#include <fcntl.h>#include <netdb.h>#include <pwd.h>#include <setjmp.h>#include <sgtty.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#ifdef __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#ifdef KERBEROS#include <kerberosIV/des.h>#include <kerberosIV/krb.h>#include "krb.h"CREDENTIALS cred;Key_schedule schedule;int use_kerberos = 1, doencrypt;char dst_realm_buf[REALM_SZ], *dest_realm = NULL;#endif#ifndef TIOCPKT_WINDOW#define	TIOCPKT_WINDOW	0x80#endif/* concession to Sun */#ifndef SIGUSR1#define	SIGUSR1	30#endifint eight, litout, rem;int noescape;u_char escapechar = '~';char *speeds[] = {	"0", "50", "75", "110", "134", "150", "200", "300", "600", "1200",	"1800", "2400", "4800", "9600", "19200", "38400"};#ifdef OLDSUNstruct winsize {	unsigned short ws_row, ws_col;	unsigned short ws_xpixel, ws_ypixel;};#else#define	get_window_size(fd, wp)	ioctl(fd, TIOCGWINSZ, wp)#endifstruct	winsize winsize;void		catch_child __P((int));void		copytochild __P((int));__dead void	doit __P((long));__dead void	done __P((int));void		echo __P((char));u_int		getescape __P((char *));void		lostpeer __P((int));void		mode __P((int));void		msg __P((char *));void		oob __P((int));int		reader __P((int));void		sendwindow __P((void));void		setsignal __P((int));void		sigwinch __P((int));void		stop __P((char));__dead void	usage __P((void));void		writer __P((void));void		writeroob __P((int));#ifdef	KERBEROSvoid		warning __P((const char *, ...));#endif#ifdef OLDSUNint		get_window_size __P((int, struct winsize *));#endifintmain(argc, argv)	int argc;	char *argv[];{	extern char *optarg;	extern int optind;	struct passwd *pw;	struct servent *sp;	struct sgttyb ttyb;	long omask;	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':			noescape = 0;			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 (ioctl(0, TIOCGETP, &ttyb) == 0) {		(void)strcat(term, "/");		(void)strcat(term, speeds[(int)ttyb.sg_ospeed]);	}	(void)get_window_size(0, &winsize);	(void)signal(SIGPIPE, lostpeer);	/* will use SIGUSR1 for window size hack, so hold it off */	omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));	/*	 * We set SIGURG and SIGUSR1 below so that an	 * incoming signal will be held pending rather than being	 * discarded. Note that these routines will be ready to get	 * a signal by the time that they are unblocked below.	 */	(void)signal(SIGURG, copytochild);	(void)signal(SIGUSR1, writeroob);#ifdef KERBEROStry_connect:	if (use_kerberos) {		struct hostent *hp;		/* Fully qualify hostname (needed for krb_realmofhost). */		hp = gethostbyname(host);		if (hp != NULL && !(host = strdup(hp->h_name))) {			(void)fprintf(stderr, "rlogin: %s\n",			    strerror(ENOMEM));			exit(1);		}		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 (dflag &&	    setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)		(void)fprintf(stderr, "rlogin: setsockopt: %s.\n",		    strerror(errno));	one = IPTOS_LOWDELAY;	if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0)		perror("rlogin: setsockopt TOS (ignored)");	(void)setuid(uid);	doit(omask);	/*NOTREACHED*/}int child, defflags, deflflags, tabflag;char deferase, defkill;struct tchars deftc;struct ltchars defltc;struct tchars notc = { -1, -1, -1, -1, -1, -1 };struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };voiddoit(omask)	long omask;{	struct sgttyb sb;	(void)ioctl(0, TIOCGETP, (char *)&sb);	defflags = sb.sg_flags;	tabflag = defflags & TBDELAY;	defflags &= ECHO | CRMOD;	deferase = sb.sg_erase;	defkill = sb.sg_kill;	(void)ioctl(0, TIOCLGET, &deflflags);	(void)ioctl(0, TIOCGETC, &deftc);	notc.t_startc = deftc.t_startc;	notc.t_stopc = deftc.t_stopc;	(void)ioctl(0, TIOCGLTC, &defltc);	(void)signal(SIGINT, SIG_IGN);	setsignal(SIGHUP);	setsignal(SIGQUIT);	child = fork();	if (child == -1) {		(void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno));		done(1);	}	if (child == 0) {		mode(1);		if (reader(omask) == 0) {			msg("connection closed.");			exit(0);		}		sleep(1);		msg("\007connection closed.");		exit(1);	}	/*	 * We may still own the socket, and may have a pending SIGURG (or might	 * receive one soon) that we really want to send to the reader.  When	 * one of these comes in, the trap copytochild simply copies such	 * signals to the child. We can now unblock SIGURG and SIGUSR1	 * that were set above.	 */	(void)sigsetmask(omask);	(void)signal(SIGCHLD, catch_child);	writer();	msg("closed connection.");	done(0);}/* trap a signal, unless it is being ignored. */voidsetsignal(sig)	int sig;{	int omask = sigblock(sigmask(sig));	if (signal(sig, exit) == SIG_IGN)		(void)signal(sig, SIG_IGN);	(void)sigsetmask(omask);}__dead voiddone(status)	int status;{	int w, wstatus;	mode(0);	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);	}	exit(status);}int dosigwinch;/* * This is called when the reader process gets the out-of-band (urgent) * request to turn on the window-changing protocol. */voidwriteroob(signo)	int signo;{	if (dosigwinch == 0) {		sendwindow();		(void)signal(SIGWINCH, sigwinch);	}	dosigwinch = 1;}voidcatch_child(signo)	int signo;{	union wait status;	int pid;	for (;;) {		pid = wait3((int *)&status, WNOHANG|WUNTRACED, NULL);		if (pid == 0)			return;		/* if the child (reader) dies, just quit */		if (pid < 0 || (pid == child && !WIFSTOPPED(status)))			done((int)(status.w_termsig | status.w_retcode));	}	/* NOTREACHED */}/* * writer: write to remote: 0 -> line. * ~.				terminate

⌨️ 快捷键说明

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