📄 telnet.c
字号:
/* 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 + -