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

📄 sync-rw.c

📁 Magic C++!的源代码
💻 C
字号:
/* sync-rw.c -- Magic C++ sync program between socket and tty    (Mostly) portable public-domain implementation   -- Copyright(C) 2003 Magicunix Infomation Technology Limited    This file is part of magicd.   magicd is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public   License as published by the Free Software Foundation; either   version 2 of the License, or (at your option) any later version.	    For details, see the Magic C++ World-Wide-Web page,    `http://www.magicunix.com',   or send a mail to the Magic C++ developers <support@magicunix.com>. */#include <stdio.h>#include <stdlib.h>#include <string.h> #include <termios.h>#include <sys/ioctl.h>#include <unistd.h>#include "tcp.h"#include <time.h>#include <setjmp.h>#include <sys/types.h>#include <sys/wait.h>#include "config.h"#include "tools.h"#include "errno.h" #define TIMEOUT  10/* Function declarations. */void outa_here(), setup_tty();int release_licencecnt(char *clientip);int clearuputmpx();extern int childpid, newfd, telnet;extern int doutmp;extern char remotehost[];int writen(register int fd, register char *ptr, register int nbytes);int get_pty_master();void dropctty();int get_pty_slave();int tty_reset(int fd);int tty_sane(int fd);int login_exec(char *args[], struct passwd *pw);int utmp1(char *line, char name[], char *host,time_t  date, int cleanup);static jmp_buf timejmp3;void time_jump3(int n){	(void) longjmp(timejmp3, 1);}/* * Read a stream socket one line at a time, and write each line back * to another stream socket./* * Return when the connection is terminated. */extern int newfd;extern int login;extern int telnet_col;extern int telnet_row;extern int debug;void killed2( int sig ){	util_log("close newfd = %d\n",newfd );	close ( newfd );}static int at_cr=0;		/* State of telnet input */int getlicence = 0;int sync_rw(sockfd, streamfd , clientip)int	sockfd;    /* network connection file descriptor */int 	streamfd;  /* pty file descriptor */char *clientip;{ 	extern 	int errno;	int i ;	int	n;	char	line[BUFSIZ];	fd_set	readfds;	struct Buf_Len received, *newbuflen; 	char dupline[BUFSIZ]; 	int mapped=0; 	int j; 	int first; 	int cr_cnt = 0; /*cnt of 'cr'*/ 	struct winsize	size;	/* Zero out fdset for select() */	FD_ZERO(&readfds); 	/* 	 * Now do that I/O thang. 	 */	/*setup size of terminal*/	if( telnet_row != 0 && telnet_col != 0 )	{		if( debug )			util_log("try to setup tty size\n");		size.ws_row = telnet_row;		size.ws_col = telnet_col;			/*I don't know why sometimes the former success */		/*and sometime the later success*/		/*so I set winsz twice.*/		if (ioctl(streamfd , TIOCSWINSZ, (char *) &size) < 0)		{			util_err_log("TIOCSWINSZ (streamfd) error",__FILE__,__LINE__,errno);			if (ioctl(0, TIOCSWINSZ, (char *) &size) < 0)			{					util_err_log("TIOCSWINSZ (0) error",__FILE__,__LINE__,errno);			}		}	}	first = 1;	if( signal( SIGTERM , killed2 ) == SIG_ERR )	{		util_err_log( "Can not catch SIGTERM!\n",__FILE__,__LINE__,errno);	}	if( setjmp(timejmp3) == 1) 	{		util_err_log("Read from tty time out!\n",__FILE__ , __LINE__,errno );		util_log("The client :%s has left\n",clientip );#ifdef HAVE_UTMPX_H		clearuputmpx(); #endif		if( getlicence )			release_licencecnt(clientip);		exit(3);	}		for ( ; ; )	{				FD_SET(sockfd, &readfds);  		FD_SET(streamfd, &readfds);				select(10, &readfds, 0, 0, NULL);				if ( FD_ISSET(sockfd, &readfds) )		{ 						if ( (n=read(sockfd, line, BUFSIZ)) <= 0 )			{				if (n == 0)				{#ifdef HAVE_UTMPX_H					clearuputmpx();#endif					util_log("The client :%s Disconnect \n",clientip );					if( getlicence )						release_licencecnt(clientip);					exit(0);  /* connection terminated */				}				else if (n < 0) 				{#ifdef HAVE_UTMPX_H					clearuputmpx();#endif					util_err_log("socket read error",__FILE__,__LINE__,errno);					util_log("The client :%s has left\n",clientip );					if( getlicence )						release_licencecnt(clientip);					exit(3);				}			}			if(debug)			{				util_log("read from socket:\n");				/*convert line to a string which can be output*/				util_checkline( line , n );			}			memcpy((void*)received.buffer, (void *)line, n);			received.len=n;			if ( telnet )				newbuflen=negotiate(sockfd, &received ,clientip);			else				newbuflen=(&received);				if(debug)				util_checkline( newbuflen->buffer , newbuflen->len );			if ( telnet )			{  /* Map cr-null, cr-lf to cr */				for ( i=0, j=0; i<newbuflen->len; ++i )				{  					if ( at_cr )					{ 						at_cr=0;						cr_cnt++;						switch (newbuflen->buffer[i])						{							case '\0':							case '\n':								mapped=1;								continue;							default:  								break;						}					}					if ( newbuflen->buffer[i] == '\r' )						at_cr=1;					line[j++]=newbuflen->buffer[i];				}				/* Only bother re-copying if we mapped a NUL */				if ( mapped )				{					strncpy(newbuflen->buffer, line, j);					newbuflen->len=j;					mapped=0;				}			}			if( debug )			{				util_log("write to tty:\n");				util_checkline( newbuflen->buffer , newbuflen->len );			}			if (writen(streamfd, newbuflen->buffer, newbuflen->len)				 != newbuflen->len)			{				if( getlicence )					release_licencecnt(clientip);				return(-1);			}		}		if ( FD_ISSET(streamfd, &readfds) )		{			n=read(streamfd, line, BUFSIZ);			if ( n == 0 )			{#ifdef HAVE_UTMPX_H				clearuputmpx();		#endif				if( getlicence )						release_licencecnt(clientip);				exit(0);			}			else if (n < 0)			{				if ( errno == EIO )				{					/*第一次进入设置超时*/					if( first == 1)					{						signal(SIGALRM, time_jump3); 						alarm(TIMEOUT);						first = 0;					}					continue;				}				else 				{#ifdef HAVE_UTMPX_H					clearuputmpx();#endif					util_err_log("pty read error", __FILE__,__LINE__ , errno);					if( getlicence )						release_licencecnt(clientip);					exit(3);				}			}			if(debug)			{				util_log("read from tty\n ");				util_checkline( line , n );			}			first = 1;			alarm(0);			if(debug)			{				util_log("write to socket:\n ");				util_checkline(line , n );			}				if (writen(sockfd, line, n) != n) 			{				util_log("write sockfd error");				if( getlicence )					release_licencecnt(clientip);				exit(3);			}		}	}}/* * Initialize a pty, fork a command running under it, and then  * return the master file descriptor */int setup(argv, pw)char *argv[];struct passwd *pw;{	int master_fd, slave_fd;	int flags;	/*struct sigaction  act,oact;*/	if ( (master_fd=get_pty_master()) < 0 ) {		util_log("get_pty_master() error\n");		exit(3);	} 	if(debug)		util_log("Enter setup\n");/*#if defined(SOLARIS)  || defined( FREEBSD )*/	if( signal( SIGCLD , outa_here ) == SIG_ERR )	{		util_err_log( "Can not signal!\n",__FILE__,__LINE__,errno);		exit(3);	}/*	#else	if( signal( SIGCLD , SIG_IGN ) == SIG_ERR )	{		util_err_log( "Can not signal!\n",__FILE__,__LINE__,errno);		exit(3);	}#endif*/	if ( (childpid=fork()) < 0 ) 	{		util_log("fork error\n");		exit(3);	}	else if ( childpid == 0 )	{		dropctty();		/* Lose controlling tty */		/* Gain slave as controlling tty */		if ( (slave_fd=get_pty_slave()) < 0 ) 		{			util_log("get_pty_slave()\n");			exit(3);		}#if defined(TIOCSCTTY) && !defined(CIBAUD)		if ( ioctl(slave_fd, TIOCSCTTY, NULL) < 0 )			util_log("TIOCSCTTY error\n");#endif  /* BSD */		/* Rearrange file descriptors */		close(0); 		dup(slave_fd);		close(1); 		dup(slave_fd);		close(master_fd); 		if ( ! netdebug )			close(2), dup(slave_fd);		close(slave_fd);		/* Reset the terminal */		if ( tty_reset(0) < 0 )			(void) tty_sane(0);#ifdef SIGTSTP  /* Prevent non-job-control programs from dying on SIGTSTP */        signal(SIGTSTP, SIG_IGN);#endif       		if ( login_exec(argv, pw) < 0 ) 		{			util_log("login_exec() error\n");			exit(255);		}		/* NOTREACHED */	}		dropctty();		/* Lose controlling tty */	setup_tty(pw);		/* Change ownership of the tty and log utmp */	return(master_fd);}/* These functions take care of the tty */extern char tty_name[];		/* from misc.c */extern int doutmp;		/* from tcpserv.c */char *log_name=NULL;int ttyowner=0;			/* The owner of the tty */void setup_tty(pw)struct passwd *pw;{		struct stat sb;	time_t now;	int newowner;	struct winsize	size;	int nrow = 0;	int ncol = 0;	/* Make sure the tty exists */	if ( stat(tty_name, &sb) < 0 )		return;	else		ttyowner=sb.st_uid;		if ( doutmp ) 	/* Set up the user to log in utmp */	{		if ( pw )			log_name=pw->pw_name;		else if ( (pw=(struct passwd *)getpwuid(getuid())) != NULL )			log_name=pw->pw_name;		else			log_name="nobody";		(void) time(&now); 		/*(void) utmp1(tty_name, log_name, remotehost, now, 0);*/	}		if ( pw )		newowner=pw->pw_uid;	else if ( (pw=(struct passwd *)getpwuid(getuid())) != NULL )		newowner=pw->pw_uid;	else		newowner=0;	/* chown to root as last resort */		(void) chmod(tty_name, 0620);	(void) chown(tty_name, newowner, sb.st_gid);	}/* Cleanup function */char clientip[16];void outa_here(int sig){		struct stat sb;	time_t now;	int status;	int pid;	if ( childpid )		kill(childpid, SIGHUP);	if ( stat(tty_name, &sb) == 0 )	{		if ( doutmp && log_name )		{			(void) time(&now);			/*(void) utmp1(tty_name, log_name, NULL, now, 1);*/		}		(void) chmod(tty_name, 0666);		(void) chown(tty_name, ttyowner, sb.st_gid);	}	close( 2 );	close( newfd );#ifdef HAVE_UTMPX_H	clearuputmpx();#endif	util_log("The client :%s has left\n",clientip );	if( ( pid = wait( &status ) ) < 0 )		util_err_log( "wait error!",__FILE__,__LINE__ , errno );	exit(0);}

⌨️ 快捷键说明

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