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

📄 telnet.c

📁 Magic C++!的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* telnet.c -- Magic C++ telnet server process   (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 <unistd.h>#include <setjmp.h>#include <tcp.h>#include <termios.h>#include <errno.h>#include "config.h"#include "tools.h" #include "telnet.h"#include "prompt.h"#include "writetmp.h"#include "login.h"#include "text_search.h"int istelnet=0;		/* Is this a telnet connection? */static int g_licencemax = 2;int g_licence;extern int debug ;  /*magicd.c*//* Routine to initialize the telnet options.  The structure of   the arguments is hardcoded, be sure to get it right. */#define NORMAL 		0#define AT_IAC 		1#define AT_IAC_A	2#define LOGINTIMEOUT 3000/*usec*/static jmp_buf timejmp2;void time_jump2(int n){	(void) longjmp(timejmp2, 1);}/*return -1 for error, 0 for normal login,1 for express login*/static int status=NORMAL;  	/* Current status of telnet negotiation */static int OPTIONS[126];int init_telnet(sockfd, will_echo,clientip)int sockfd;int will_echo;char *clientip;{	int i;	char sendstr[6];	char ch;	int n;	int ret;	istelnet=1;	/* Initialize istelnet to not a telnet connection */	/* Send initializing negotiations */	/*sent two command one time*/	status=NORMAL;	sendstr[0]=IAC;	sendstr[1]=WILL;	sendstr[2]=TELOPT_SGA;	for ( i=0; i<=126; ++i )	{		switch (i) 		{			case TELOPT_ECHO: if ( will_echo )						OPTIONS[i]=WILL;					  else                        OPTIONS[i]=WONT;					  break;			case TELOPT_SGA:  OPTIONS[i]=WILL;					  break;			default: OPTIONS[i]=WONT;		}	}	sendstr[3]=IAC;	sendstr[4]=OPTIONS[TELOPT_ECHO];	sendstr[5]=TELOPT_ECHO;	sendstr[6]=IAC;	sendstr[7]=WILL;	sendstr[8]=TELOPT_USER_EX_LOGIN;	if(debug)		util_log("*************Begin A sessin****************\n");	writen(sockfd, sendstr, 9);	/*设置超时*/	if( setjmp(timejmp2) == 1)	{		util_err_log("Wait control char time out!\n",__FILE__ , __LINE__,errno );		util_log("The client :%s has left\n",clientip );		exit(3);	}	signal(SIGALRM, time_jump2); 	alarm(TIMEOUT);	/*accept return characters*/	/*frontend return  back 'DO' when it is magic c++ frontend,otherwise it's DONT*/	for( i = 0 ; i < 9 ; i ++ )	{		n = read(sockfd, &ch, 1);		if (n == 0)		{			util_log("Wait init char failed!\n");						exit(0);  /* connection terminated */		}           		else if (n < 0) 		{			util_err_log("socket read error", __FILE__,__LINE__,errno);			exit(3);		}		if( i == 7 )		{			if( ch == DO )			{				util_log("Foreground ask for express login\n");				ret = 1;			}			else			{				util_log("It is normal telnet client\n");				ret = 0;					}		}	}     	alarm(0);	return ret;}/* Routine to perform telnet negotiation. It takes a Buf_Len    structure and a socket file descriptor.  It checks the buffer    for telnet negotiation, negotiates, and returns a Buf_Len    structure with the modified buffer  */struct Buf_Len modified;char sent[2];	/* The negotiation sent */char reply[2];	/* The negotiation reply */char oldsent[2];  /*the character sent to frontend last time*/struct Buf_Len *negotiate(sockfd, recvd ,clientip)int sockfd;struct Buf_Len *recvd;char *clientip;{ 	int i, j=0;	char dupline[8192];	modified.len=0;	reply[0] = IAC;	sent[0] = IAC;		for ( i=0; i<recvd->len; ++i )	{		switch (status)		{			case AT_IAC:				status=AT_IAC_A;				sent[1]=recvd->buffer[i];				if( sent[ 1 ] == NOP )					status = NORMAL;				break; 			case AT_IAC_A:					status=NORMAL;								sent[2]=recvd->buffer[i];					if ( sent[1] == (char)DO )				{					/*process user-define protocol */					if( sent[2] > 100 && sent[2] < 120 )					{						user_process(sockfd , sent[2] , clientip );					}										else					{												reply[1]=OPTIONS[sent[2]];						reply[2]=sent[2];									reply[0] = IAC;											write(sockfd, reply, 3);												memset( oldsent , 0 , sizeof( oldsent ));						strcpy( oldsent , sent );											}							}				break;			case NORMAL:					switch (recvd->buffer[i])				{ 						case IAC: 						 		if ( ! istelnet )								istelnet=1;							  status=AT_IAC;							  continue;													default: 							status=NORMAL;														  modified.buffer[j++]=recvd->buffer[i];							  ++modified.len;							  break;					}					break;			default: fprintf(stderr,"status error: %d\r\n",status);				 break;		}	}	return(&modified);}int user_process(int sockfd , char dowhat , char *clientip ){	switch( dowhat )	{	case APPLYLICENCE:		return apply_license(sockfd , clientip);		break;	case GET_FILE_INFO:		return get_files_info(sockfd,clientip);		break;	case QUERY_PATH:		return query_path(sockfd,clientip);		break;	case RELEASE_LICENCE:		return release_licence(sockfd,clientip);		break;	default :		 util_err_log("user_process" , __FILE__ , __LINE__ , 0);		 return -1;		 break;	}}extern int getlicence;/*apply*/int apply_license(int sockfd, char *clientip){	int permit = WONT;		reply[ 0 ] = IAC;	util_log("Client :%s is Applying a Licence \n",clientip );	if( getlicence == 0)	{		/*add global successfully*/		if( util_add_global(g_licencemax) == 0 )		{			permit = WILL;			getlicence = 1;		}	}	reply[ 1 ] = permit;	reply[ 2 ] = APPLYLICENCE;	if( permit == WILL )		util_log("Client: %s Applied Licence successfully!\n",clientip);	else		util_log("Client: %s Applied Licence failed!\n", clientip);	write(sockfd, reply, 3);	if( permit == WILL )		return 0;	else		return -1;}/*get time and size of multiple files*/int get_files_info(int sockfd, char *clientip){	char filesinfo[ 102400 ];	char fileinfo[36];	char files[ 102400 ];	char filetime[ 14 ];	long filesize = 0;	char filename[200];	char szBuf[10240];	int n ;	char *file = NULL;	if( debug )		util_log("enter get files_info\n");	reply[ 0 ] = IAC;	reply[ 1 ] = WILL;	reply[ 2 ] = GET_FILE_INFO;	write(sockfd, reply, 3);	memset( filesinfo , 0 ,sizeof( filesinfo ));	memset( files , 0 , sizeof( files ));	memset( filetime ,  0 , sizeof( filetime ));	memset( fileinfo ,  0 , sizeof( fileinfo ));		memset( filename , 0 , sizeof( filename ));	/*timeout setup*/	if( setjmp(timejmp2) == 1)	{		util_err_log("Wait terminate flag time out!\n",__FILE__ , __LINE__,errno );		util_log("The client :%s has left\n",clientip );		exit(3);	}	signal(SIGALRM, time_jump2); 	alarm(TIMEOUT);	while( 1 )	{				memset(szBuf , 0 , sizeof(szBuf));		if ( (n=read(sockfd, szBuf, sizeof(szBuf))) <= 0 )		{			if (n == 0)				exit(0);  /* connection terminated */			else if (n < 0) 			{				util_err_log("socket read error", __FILE__,__LINE__,errno);				exit(3);			}		}		/*receive continuous '\n' */		strcat (files ,szBuf );		if( szBuf[ n - 1 ] == '\n' && szBuf[ n - 2 ] == '\n' )			break;	}	alarm(0);	if(debug)	{		util_log("n=%d\n",n );		util_log("buf=");		util_checkline(szBuf , n);	}	file = (char *)strtok( files, "\n" );   	while( file != NULL )   	{		if(debug)	    	util_log( "request query a file :%s\n",file );    	memset( filetime ,  0 , sizeof( filetime ));       	memset( fileinfo ,  0 , sizeof( fileinfo ));       	memset( filename , 0 , sizeof( filename ));       	n = strlen( file );       	strcpy( filename , file );     	filesize = util_getfileinfo(filename,  filetime );     	/*can not get file information ,fill it by 'F'*/     	if( filesize == -1 )     	{     		memset( fileinfo , 'F' , 34);     		fileinfo[ 34 ] = '\n';     	}       	else     		sprintf( fileinfo , "%14s%020ld\n",filetime , filesize );

⌨️ 快捷键说明

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