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

📄 rlogin.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		completed_1(result, errno);		return;	}	completed_1(offset, 0);}static voidrestart_rd_rem(){	size_t offset;	int result, error;	assert(!inprogress_rd_rem);	rd_rem_offset= 0;	offset= 0;	while (offset < RD_REM_BUFSIZE)	{		result= read(rem, rd_rem_buf+offset, RD_REM_BUFSIZE-offset);		if (result > 0)		{			offset += result;			assert(offset <= RD_REM_BUFSIZE);			continue;		}		error= errno;		if (offset != 0)			completed_rd_rem(offset, 0);		rd_rem_offset= offset;		if (result == -1 && error == EINPROGRESS)		{			inprogress_rd_rem= 1;			return;		}		completed_rd_rem(result, error);		return;	}	completed_rd_rem(offset, 0);}static voidrestart_wr_rem(){	size_t offset;	int result, error;	assert(!inprogress_wr_rem);	if (extra_wr_rem_new != NULL && extra_wr_rem == NULL)	{		extra_wr_rem= extra_wr_rem_new;		extra_wr_rem_size= extra_wr_rem_new_size;		extra_wr_rem_offset= 0;		extra_wr_rem_new= NULL;		extra_wr_rem_new_size= 0;	}	if (extra_wr_rem != NULL)	{		offset= 0;		while (offset < extra_wr_rem_size)		{			result= write(rem, 				extra_wr_rem+extra_wr_rem_offset+offset, 						extra_wr_rem_size-offset);			if (result > 0)			{				assert (result <= extra_wr_rem_size-offset);				offset += result;				continue;			}			error= errno;			if (offset != 0)				completed_wr_rem(offset, 0);			if (result == -1 && errno == EINPROGRESS)			{				inprogress_wr_rem= 1;				return;			}			completed_wr_rem(result, errno);			return;		}		completed_wr_rem(offset, 0);	}	if (wr_rem_size == 0)		return;	offset= 0;	while (offset < wr_rem_size)	{		result= write(rem, rd_0_buf+wr_rem_offset+offset, 							wr_rem_size-offset);		if (result > 0)		{			assert (result <= wr_rem_size-offset);			offset += result;			continue;		}		error= errno;		if (offset != 0)			completed_wr_rem(offset, 0);		if (result == -1 && errno == EINPROGRESS)		{			inprogress_wr_rem= 1;			return;		}		completed_wr_rem(result, errno);		return;	}	completed_wr_rem(offset, 0);}static voidcompleted_0(result, error)	int result;	int error;{	static int bol= 0, local= 0;	char *iptr, *optr;	int i;	u_char c;	inprogress_0= 0;	if (result > 0)	{		assert(rd_0_offset > 0);		wr_rem_offset= 1;		iptr= rd_0_buf+rd_0_offset;		optr= rd_0_buf+wr_rem_offset;		for (i= 0; i<result; iptr++, i++)		{			c= *iptr;			if (bol)			{				bol= 0;				if (!noescape && c == escapechar)				{					local= 1;					continue;				}			}			else if (local)			{				local= 0;				if (c == '.' || (c != _POSIX_VDISABLE &&					c == defattr.c_cc[VEOF]))				{					echo(c);					finish();					/* NOTREACHED */				}				if (c == '!')				{					subshell();					continue;				}				if (c != escapechar)				{					if (optr < iptr)					{						*(optr++)= escapechar;					}					else					{						assert(optr == iptr);						assert(iptr == rd_0_buf+								rd_0_offset);						assert(rd_0_offset > 0);						wr_rem_offset--;						optr[-1]= escapechar;					}				}			}			*(optr++)= c;			bol= (c != _POSIX_VDISABLE) && 				(c == defattr.c_cc[VKILL] ||				c == defattr.c_cc[VEOF] ||				c == defattr.c_cc[VINTR] ||				c == defattr.c_cc[VSUSP] ||				c == '\r' || c == '\n');		}		wr_rem_size += optr-rd_0_buf-wr_rem_offset;		if (wr_rem_size != 0)		{			more2read_0= 0;			more2write_rem= 1;		}		return;	}	fprintf(stderr, "completed_0: %d, %d\n", result, error);	abort();}static voidcompleted_1(result, error)	int result;	int error;{	inprogress_1= 0;	if (result > 0)	{		if (extra_1 != NULL)		{			assert (result <= extra_1_size);			extra_1_size -= result;			extra_1_offset += result;			if (extra_1_size == 0)			{				more2write_1= 0;				more2read_rem= 1;				free(extra_1);				extra_1= NULL;			}			return;		}		assert (result <= wr_1_size);		wr_1_size -= result;		wr_1_offset += result;		if (wr_1_size == 0)		{			more2write_1= 0;			more2read_rem= 1;		}		return;	}	fprintf(stderr, "completed_1: %d, %d\n", result, error);	abort();}static voidcompleted_rd_rem(result, error)	int result;	int error;{	nwio_tcpopt_t tcpopt;	char *new_buf;	size_t keep_size;	u_char urg_byte;	int i;	inprogress_rd_rem= 0;	if (result > 0)	{		if (rd_rem_urg)		{#if DEBUGfprintf(stderr, "\n\r%d urg bytes\n\r", result);#endif			if (urg_1_size > MAX_EXTRA_1_NEW_SIZE)			{				keep_size= MAX_EXTRA_1_NEW_SIZE/2;				memmove(urg_1, urg_1+urg_1_size-keep_size, 					keep_size);				urg_1_size= keep_size;			}			new_buf= realloc(urg_1, urg_1_size+result);			if (new_buf == NULL)			{				fprintf(stderr, 					"rlogin: warning realloc %d failed\n",					urg_1_size+result);				return;			}			memcpy(new_buf+urg_1_size, 				rd_rem_buf+rd_rem_offset, result);			urg_1= new_buf;			urg_1_size += result;			return;		}		more2read_rem= 0;		more2write_1= 1;		wr_1_size= result;		wr_1_offset= rd_rem_offset;		return;	}	if (result == -1 && error == EURG)	{#if DEBUGfprintf(stderr, "\n\rEURG\n\r");#endif		rd_rem_urg= 1;		tcpopt.nwto_flags= NWTO_RCV_URG;		result= ioctl(rem, NWIOSTCPOPT, &tcpopt);		if (result == -1)		{			fprintf(stderr, 				"rlogin: NWIOSTCPOPT on %d failed (%s)\n",				rem, strerror(errno));			exit(1);		}		return;	}	if (result == -1 && error == ENOURG)	{#if DEBUGfprintf(stderr, "\n\rENOURG\n\r");#endif		rd_rem_urg= 0;		tcpopt.nwto_flags= NWTO_RCV_NOTURG;		result= ioctl(rem, NWIOSTCPOPT, &tcpopt);		if (result == -1)		{			fprintf(stderr, 				"rlogin: NWIOSTCPOPT on %d failed (%s)\n",				rem, strerror(errno));			exit(1);		}		if (urg_1_size != 0)		{			urg_byte= urg_1[urg_1_size-1];			urg_1_size--;			do_urg(urg_byte);			if (urg_1_size == 0)				return;			if (extra_1_new_size + urg_1_size > MAX_EXTRA_1_NEW_SIZE)			{				extra_1_new_size= 0;				free(extra_1_new);				extra_1_new= NULL;			}			if (extra_1_new_size != 0)			{				new_buf= realloc(extra_1_new, 					extra_1_new_size+urg_1_size);				if (new_buf == 0)				{					extra_1_new_size= 0;					free(extra_1_new);					extra_1_new= NULL;				}				else				{					extra_1_new= new_buf;					memcpy(extra_1_new+extra_1_new_size,						urg_1, urg_1_size);					extra_1_new_size += urg_1_size;					urg_1_size= 0;					free(urg_1);					urg_1= NULL;				}			}			if (extra_1_new_size == 0)			{				extra_1_new_size= urg_1_size;				extra_1_new= urg_1;				urg_1_size= 0;				urg_1= NULL;			}			more2read_rem= 0;			more2write_1= 1;		}		return;	}	if (result == -1 && error == EINTR)	{		/* Never mind. */		return;	}	if (result == 0)	{		msg("connection closed.");		done(0);	}	fprintf(stderr, "completed_rd_rem: %d, %d\n", result, error);	abort();}static voidcompleted_wr_rem(result, error)	int result;	int error;{	inprogress_wr_rem= 0;	if (result > 0)	{		if (extra_wr_rem != NULL)		{			assert (result <= extra_wr_rem_size);			extra_wr_rem_size -= result;			extra_wr_rem_offset += result;			if (extra_wr_rem_size == 0)			{				free(extra_wr_rem);				extra_wr_rem= NULL;				if (wr_rem_size == 0)				{					more2write_rem= 0;					more2read_0= 1;				}			}			return;		}		assert (result <= wr_rem_size);		wr_rem_size -= result;		wr_rem_offset += result;		if (wr_rem_size == 0)		{			more2write_rem= 0;			more2read_0= 1;		}		return;	}	fprintf(stderr, "completed_wr_rem: %d, %d\n", result, error);	abort();}static voiddo_urg(urg_byte)	int urg_byte;{#if DEBUG	fprintf(stderr, "rlogin: warning got urg_byte 0x%x\r\n", urg_byte);#endif	if (urg_byte & TIOCPKT_WINDOW)	{		if (dosigwinch == 0)		{			sendwindow();			signal(SIGWINCH, sigwinch);		}		dosigwinch= 1;	}}static voidecho(c)	int c;{	u_char c1;	char *new_buf;	new_buf= realloc(extra_1_new, extra_1_new_size+6);	if (new_buf == NULL)		return;	extra_1_new= new_buf;	new_buf= extra_1_new+extra_1_new_size;	c1= escapechar;	if (c1 < ' ')	{		*new_buf++= '^';		*new_buf++= c1 + '@';	}	else if (c1 == 0x7f)	{		*new_buf++= '^';		*new_buf++= '?';	}	else		*new_buf++= c1;	if (c < ' ')	{		*new_buf++= '^';		*new_buf++= c + '@';	}	else if (c == 0x7f)	{		*new_buf++= '^';		*new_buf++= '?';	}	else		*new_buf++= c;	*new_buf++= '\r';	*new_buf++= '\n';	extra_1_new_size= new_buf-extra_1_new;	more2write_1= 1;}static voidfinish(){	done(0);}static char cmdbuf[256];static voidsubshell(){	/* Start a subshell. Based on the first character of the command,	 * the tcp connection will be present at fd 3 ('+'), or at	 * fd 0 and fd 1 ('=')	 */	int r, pid, stat, len;	char *shell, *cmd;	/* cancel the reads and writes that are in progress. */	if (inprogress_0)	{		r= fcancel(0, ASIO_READ);		if (r != 0) abort();	}	if (inprogress_1)	{		r= fcancel(1, ASIO_WRITE);		if (r != 0) abort();	}	if (inprogress_rd_rem)	{		r= fcancel(rem, ASIO_READ);		if (r != 0) abort();	}	if (inprogress_wr_rem)	{		r= fcancel(rem, ASIO_WRITE);		if (r != 0) abort();	}	mode(0);	pid= fork();	if (pid == -1) abort();	if (pid != 0)	{		r= waitpid(pid, &stat, 0);		if (r != pid) abort();#if DEBUG		fprintf(stderr, "stat: 0x%x\n", stat);#endif		mode(1);		return;	}	(void)signal(SIGINT, SIG_DFL);	shell= getenv("SHELL");	if (shell == NULL)		shell= "/bin/sh";	printf("~!\ncommand [%s]: ", shell);	cmd= fgets(cmdbuf, sizeof(cmdbuf), stdin);	if (cmd == NULL)		exit(0);#if DEBUG	printf("got command '%s'\n", cmd);#endif	/* Strip the trailing newline */	len= strlen(cmd);	if (len > 0 && cmd[len-1] == '\n')		cmd[len-1]= '\0';	else		printf("\n");	/* Skip leading white space */	while (*cmd != '\0' && isspace(*cmd))		cmd++;	if (*cmd == '+')	{		if (rem != 3)		{			dup2(rem, 3);			close(rem);		}		cmd++;	}	else if (*cmd == '=')	{		dup2(rem, 0);		dup2(rem, 1);		close(rem);		cmd++;	}	else		close(rem);	if (*cmd == '\0')	{		r= execl(shell, shell, NULL);	}	else	{		r= execl("/bin/sh", "sh", "-c", cmd, NULL);	}	printf("exec failed: %d, %d\n", r, errno);	exit(0);}#endif /* __minix_vmd */

⌨️ 快捷键说明

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