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

📄 sys_term.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	request.signal = SIGCLD;	request.pid = getpid();#endif#ifdef BFTPDAEMON	/*	 * Are we working as the bftp daemon?	 */	if (bftpd) {		SCPYN(request.exec_name, BFTPPATH);	}#endif /* BFTPDAEMON */	if (write(i, (char *)&request, sizeof(request)) < 0) {		char tbuf[128];		(void) sprintf(tbuf, "Can't write to %s\n", INIT_FIFO);		fatalperror(net, tbuf);	}	(void) close(i);	(void) signal(SIGALRM, nologinproc);	for (i = 0; ; i++) {		char tbuf[128];		alarm(15);		n = read(pty, ptyip, BUFSIZ);		if (i == 3 || n >= 0 || !gotalarm)			break;		gotalarm = 0;		sprintf(tbuf, "telnetd: waiting for /etc/init to start login process on %s\r\n", line);		(void) write(net, tbuf, strlen(tbuf));	}	if (n < 0 && gotalarm)		fatal(net, "/etc/init didn't start login process");	pcc += n;	alarm(0);	(void) signal(SIGALRM, SIG_DFL);	return;#endif	/* NEWINIT */}char	*envinit[3];extern char **environ;	voidinit_env(){	extern char *getenv();	char **envp;	envp = envinit;	if (*envp = getenv("TZ"))		*envp++ -= 3;#if	defined(CRAY) || defined(__hpux)	else		*envp++ = "TZ=GMT0";#endif	*envp = 0;	environ = envinit;}#ifndef	NEWINIT/* * start_login(host) * * Assuming that we are now running as a child processes, this * function will turn us into the login process. */	voidstart_login(host, autologin, name)	char *host;	int autologin;	char *name;{	register char *cp;	register char **argv;	char **addarg();	extern char *getenv();#ifdef	UTMPX	register int pid = getpid();	struct utmpx utmpx;#endif#ifdef SOLARIS	char *term;	char termbuf[64];#endif#ifdef	UTMPX	/*	 * Create utmp entry for child	 */	bzero(&utmpx, sizeof(utmpx));	SCPYN(utmpx.ut_user, ".telnet");	SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1);	utmpx.ut_pid = pid;	utmpx.ut_id[0] = 't';	utmpx.ut_id[1] = 'n';	utmpx.ut_id[2] = SC_WILDC;	utmpx.ut_id[3] = SC_WILDC;	utmpx.ut_type = LOGIN_PROCESS;	(void) time(&utmpx.ut_tv.tv_sec);	if (makeutx(&utmpx) == NULL)		fatal(net, "makeutx failed");#endif	/*	 * -h : pass on name of host.	 *		WARNING:  -h is accepted by login if and only if	 *			getuid() == 0.	 * -p : don't clobber the environment (so terminal type stays set).	 *	 * -f : force this login, he has already been authenticated	 */	argv = addarg(0, "login");#if	!defined(NO_LOGIN_H)# if	defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)	/*	 * Don't add the "-h host" option if we are going	 * to be adding the "-r host" option down below...	 */	if ((auth_level < 0) || (autologin != AUTH_VALID))# endif	{		argv = addarg(argv, "-h");		argv = addarg(argv, host);#ifdef	SOLARIS		/*		 * SVR4 version of -h takes TERM= as second arg, or -		 */		term = getenv("TERM");		if (term == NULL || term[0] == 0) {			term = "-";		} else {			strcpy(termbuf, "TERM=");			strncat(termbuf, term, sizeof(termbuf) - 6);			term = termbuf;		}		argv = addarg(argv, term);#endif	}#endif#if	!defined(NO_LOGIN_P)	argv = addarg(argv, "-p");#endif#ifdef	BFTPDAEMON	/*	 * Are we working as the bftp daemon?  If so, then ask login	 * to start bftp instead of shell.	 */	if (bftpd) {		argv = addarg(argv, "-e");		argv = addarg(argv, BFTPPATH);	} else #endif#if	defined (SecurID)	/*	 * don't worry about the -f that might get sent.	 * A -s is supposed to override it anyhow.	 */	if (require_SecurID)		argv = addarg(argv, "-s");#endif#if	defined (AUTHENTICATION)	if (auth_level >= 0 && autologin == AUTH_VALID) {# if	!defined(NO_LOGIN_F)		argv = addarg(argv, "-f");		argv = addarg(argv, name);# else#  if defined(LOGIN_R)		/*		 * We don't have support for "login -f", but we		 * can fool /bin/login into thinking that we are		 * rlogind, and allow us to log in without a		 * password.  The rlogin protocol expects		 *	local-user\0remote-user\0term/speed\0		 */		if (pty > 2) {			register char *cp;			char speed[128];			int isecho, israw, xpty, len;			extern int def_rspeed;#  ifndef LOGIN_HOST			/*			 * Tell login that we are coming from "localhost".			 * If we passed in the real host name, then the			 * user would have to allow .rhost access from			 * every machine that they want authenticated			 * access to work from, which sort of defeats			 * the purpose of an authenticated login...			 * So, we tell login that the session is coming			 * from "localhost", and the user will only have			 * to have "localhost" in their .rhost file.			 */#			define LOGIN_HOST "localhost"#  endif			argv = addarg(argv, "-r");			argv = addarg(argv, LOGIN_HOST);			xpty = pty;# ifndef  STREAMSPTY			pty = 0;# else			ttyfd = 0;# endif			init_termbuf();			isecho = tty_isecho();			israw = tty_israw();			if (isecho || !israw) {				tty_setecho(0);		/* Turn off echo */				tty_setraw(1);		/* Turn on raw */				set_termbuf();			}			len = strlen(name)+1;			write(xpty, name, len);			write(xpty, name, len);			sprintf(speed, "%s/%d", (cp = getenv("TERM")) ? cp : "",				(def_rspeed > 0) ? def_rspeed : 9600);			len = strlen(speed)+1;			write(xpty, speed, len);			if (isecho || !israw) {				init_termbuf();				tty_setecho(isecho);				tty_setraw(israw);				set_termbuf();				if (!israw) {					/*					 * Write a newline to ensure					 * that login will be able to					 * read the line...					 */					write(xpty, "\n", 1);				}			}			pty = xpty;		}#  else		argv = addarg(argv, name);#  endif# endif	} else#endif	if (getenv("USER")) {		argv = addarg(argv, getenv("USER"));#if	defined(LOGIN_ARGS) && defined(NO_LOGIN_P)		{			register char **cpp;			for (cpp = environ; *cpp; cpp++)				argv = addarg(argv, *cpp);		}#endif		/*		 * Assume that login will set the USER variable		 * correctly.  For SysV systems, this means that		 * USER will no longer be set, just LOGNAME by		 * login.  (The problem is that if the auto-login		 * fails, and the user then specifies a different		 * account name, he can get logged in with both		 * LOGNAME and USER in his environment, but the		 * USER value will be wrong.		 */		unsetenv("USER");	}#if	defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)	if (pty > 2)		close(pty);#endif	closelog();	execv(_PATH_LOGIN, argv);	syslog(LOG_ERR, "%s: %m\n", _PATH_LOGIN);	fatalperror(net, _PATH_LOGIN);	/*NOTREACHED*/}	char **addarg(argv, val)	register char **argv;	register char *val;{	register char **cpp;	if (argv == NULL) {		/*		 * 10 entries, a leading length, and a null		 */		argv = (char **)malloc(sizeof(*argv) * 12);		if (argv == NULL)			return(NULL);		*argv++ = (char *)10;		*argv = (char *)0;	}	for (cpp = argv; *cpp; cpp++)		;	if (cpp == &argv[(int)argv[-1]]) {		--argv;		*argv = (char *)((int)(*argv) + 10);		argv = (char **)realloc(argv, (int)(*argv) + 2);		if (argv == NULL)			return(NULL);		argv++;		cpp = &argv[(int)argv[-1] - 10];	}	*cpp++ = val;	*cpp = 0;	return(argv);}#endif	/* NEWINIT *//* * cleanup() * * This is the routine to call when we are all through, to * clean up anything that needs to be cleaned up. */	/* ARGSUSED */	voidcleanup(sig)	int sig;{#ifndef	PARENT_DOES_UTMP# if (BSD > 43) || defined(convex)	char *p;	p = line + sizeof("/dev/") - 1;	if (logout(p))		logwtmp(p, "", "");	(void)chmod(line, 0666);	(void)chown(line, 0, 0);	*p = 'p';	(void)chmod(line, 0666);	(void)chown(line, 0, 0);	(void) shutdown(net, 2);	exit(1);# else	void rmut();	rmut();	vhangup();	/* XXX */	(void) shutdown(net, 2);	exit(1);# endif#else	/* PARENT_DOES_UTMP */# ifdef	NEWINIT	(void) shutdown(net, 2);	exit(1);# else	/* NEWINIT */#  ifdef CRAY	static int incleanup = 0;	register int t;	/*	 * 1: Pick up the zombie, if we are being called	 *    as the signal handler.	 * 2: If we are a nested cleanup(), return.	 * 3: Try to clean up TMPDIR.	 * 4: Fill in utmp with shutdown of process.	 * 5: Close down the network and pty connections.	 * 6: Finish up the TMPDIR cleanup, if needed.	 */	if (sig == SIGCHLD)		while (waitpid(-1, 0, WNOHANG) > 0)			;	/* VOID */	t = sigblock(sigmask(SIGCHLD));	if (incleanup) {		sigsetmask(t);		return;	}	incleanup = 1;	sigsetmask(t);	if (secflag) {		/*		 *	We need to set ourselves back to a null		 *	label to clean up.		 */		setulvl(sysv.sy_minlvl);		setucmp((long)0);	}	t = cleantmp(&wtmp);	setutent();	/* just to make sure */#  endif /* CRAY */	rmut(line);	close(pty);	(void) shutdown(net, 2);#  ifdef CRAY	if (t == 0)		cleantmp(&wtmp);#  endif /* CRAY */	exit(1);# endif	/* NEWINT */#endif	/* PARENT_DOES_UTMP */}#if defined(PARENT_DOES_UTMP) && !defined(NEWINIT)/* * _utmp_sig_rcv * utmp_sig_init * utmp_sig_wait *	These three functions are used to coordinate the handling of *	the utmp file between the server and the soon-to-be-login shell. *	The server actually creates the utmp structure, the child calls *	utmp_sig_wait(), until the server calls utmp_sig_notify() and *	signals the future-login shell to proceed. */static int caught=0;		/* NZ when signal intercepted */static void (*func)();		/* address of previous handler */	void_utmp_sig_rcv(sig)	int sig;{	caught = 1;	(void) signal(SIGUSR1, func);}	voidutmp_sig_init(){	/*	 * register signal handler for UTMP creation	 */	if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1)		fatalperror(net, "telnetd/signal");}	voidutmp_sig_reset(){	(void) signal(SIGUSR1, func);	/* reset handler to default */}# ifdef __hpux# define sigoff() /* do nothing */# define sigon() /* do nothing */# endif	voidutmp_sig_wait(){	/*	 * Wait for parent to write our utmp entry.	 */	sigoff();	while (caught == 0) {		pause();	/* wait until we get a signal (sigon) */		sigoff();	/* turn off signals while we check caught */	}	sigon();		/* turn on signals again */}	voidutmp_sig_notify(pid){	kill(pid, SIGUSR1);}# ifdef CRAYstatic int gotsigjob = 0;	/*ARGSUSED*/	voidsigjob(sig)	int sig;{	register int jid;	register struct jobtemp *jp;	while ((jid = waitjob(NULL)) != -1) {		if (jid == 0) {			return;		}		gotsigjob++;		jobend(jid, NULL, NULL);	}}/* * Clean up the TMPDIR that login created. * The first time this is called we pick up the info * from the utmp.  If the job has already gone away, * then we'll clean up and be done.  If not, then * when this is called the second time it will wait * for the signal that the job is done. */	intcleantmp(wtp)	register struct utmp *wtp;{	struct utmp *utp;	static int first = 1;	register int mask, omask, ret;	extern struct utmp *getutid P((const struct utmp *_Id));	mask = sigmask(WJSIGNAL);	if (first == 0) {		omask = sigblock(mask);		while (gotsigjob == 0)			sigpause(omask);		return(1);	}	first = 0;	setutent();	/* just to make sure */	utp = getutid(wtp);	if (utp == 0) {		syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR");		return(-1);	}	/*	 * Nothing to clean up if the user shell was never started.	 */	if (utp->ut_type != USER_PROCESS || utp->ut_jid == 0)		return(1);	/*	 * Block the WJSIGNAL while we are in jobend().	 */	omask = sigblock(mask);	ret = jobend(utp->ut_jid, utp->ut_tpath, utp->ut_user);	sigsetmask(omask);	return(ret);}	intjobend(jid, path, user)	register int jid;	register char *path;	register char *user;{	static int saved_jid = 0;	static char saved_path[sizeof(wtmp.ut_tpath)+1];	static char saved_user[sizeof(wtmp.ut_user)+1];	if (path) {		strncpy(saved_path, path, sizeof(wtmp.ut_tpath));		strncpy(saved_user, user, sizeof(wtmp.ut_user));		saved_path[sizeof(saved_path)] = '\0';		saved_user[sizeof(saved_user)] = '\0';	}	if (saved_jid == 0) {		saved_jid = jid;		return(0);	}	cleantmpdir(jid, saved_path, saved_user);	return(1);}/* * Fork a child process to clean up the TMPDIR */cleantmpdir(jid, tpath, user)	register int jid;	register char *tpath;	register char *user;{	switch(fork()) {	case -1:		syslog(LOG_ERR, "TMPDIR cleanup(%s): fork() failed: %m\n",							tpath);		break;	case 0:		execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);		syslog(LOG_ERR, "TMPDIR cleanup(%s): execl(%s) failed: %m\n",							tpath, CLEANTMPCMD);		exit(1);	default:		/*		 * Forget about child.  We will exit, and		 * /etc/init will pick it up.		 */		break;	}}# endif /* CRAY */#endif	/* defined(PARENT_DOES_UTMP) && !defined(NEWINIT) *//* * rmut() * * This is the function called by cleanup() to * remove the utmp entry for this person. */#ifdef	UTMPX	voidrmut(){	register f;	int found = 0;	struct utmp *u, *utmp;	int nutmp;	struct stat statbf;	struct utmpx *utxp, utmpx;	/*	 * This updates the utmpx and utmp entries and make a wtmp/x entry	 */	SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1);	utxp = getutxline(&utmpx);	if (utxp) {		utxp->ut_type = DEAD_PROCESS;		utxp->ut_exit.e_termination = 0;		utxp->ut_exit.e_exit = 0;		(void) time(&utmpx.ut_tv.tv_sec);		utmpx.ut_tv.tv_usec = 0;		modutx(utxp);	}	endutxent();}  /* end of rmut */#endif#if	!defined(UTMPX) && !(defined(CRAY) || defined(__hpux)) && BSD <= 43	voidrmut(){	register f;	int found = 0;	struct utmp *u, *utmp;	int nutmp;	struct stat statbf;	f = open(utmpf, O_RDWR);	if (f >= 0) {		(void) fstat(f, &statbf);		utmp = (struct utmp *)malloc((unsigned)statbf.st_size);		if (!utmp)			syslog(LOG_ERR, "utmp malloc failed");		if (statbf.st_size && utmp) {			nutmp = read(f, (char *)utmp, (int)statbf.st_size);			nutmp /= sizeof(struct utmp);					for (u = utmp ; u < &utmp[nutmp] ; u++) {				if (SCMPN(u->ut_line, line+5) ||				    u->ut_name[0]==0)					continue;				(void) lseek(f, ((long)u)-((long)utmp), L_SET);				SCPYN(u->ut_name, "");				SCPYN(u->ut_host, "");				(void) time(&u->ut_time);				(void) write(f, (char *)u, sizeof(wtmp));				found++;			}		}		(void) close(f);	}	if (found) {		f = open(wtmpf, O_WRONLY|O_APPEND);		if (f >= 0) {			SCPYN(wtmp.ut_line, line+5);			SCPYN(wtmp.ut_name, "");			SCPYN(wtmp.ut_host, "");			(void) time(&wtmp.ut_time);			(void) write(f, (char *)&wtmp, sizeof(wtmp));			(void) close(f);		}	}	(void) chmod(line, 0666);	(void) chown(line, 0, 0);	line[strlen("/dev/")] = 'p';	(void) chmod(line, 0666);	(void) chown(line, 0, 0);}  /* end of rmut */#endif	/* CRAY */#ifdef __hpuxrmut (line)char *line;{	struct utmp utmp;	struct utmp *utptr;	int fd;			/* for /etc/wtmp */	utmp.ut_type = USER_PROCESS;	(void) strncpy(utmp.ut_id, line+12, sizeof(utmp.ut_id));	(void) setutent();	utptr = getutid(&utmp);	/* write it out only if it exists */	if (utptr) {		utptr->ut_type = DEAD_PROCESS;		utptr->ut_time = time((long *) 0);		(void) pututline(utptr);		/* set wtmp entry if wtmp file exists */		if ((fd = open(wtmpf, O_WRONLY | O_APPEND)) >= 0) {			(void) write(fd, utptr, sizeof(utmp));			(void) close(fd);		}	}	(void) endutent();	(void) chmod(line, 0666);	(void) chown(line, 0, 0);	line[14] = line[13];	line[13] = line[12];	line[8] = 'm';	line[9] = '/';	line[10] = 'p';	line[11] = 't';	line[12] = 'y';	(void) chmod(line, 0666);	(void) chown(line, 0, 0);}#endif

⌨️ 快捷键说明

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