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

📄 utelnetd.c

📁 linux下telnet服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				if (chr == '\n') fputc('\r', stdout);				fputc(chr, stdout);			}			fclose(fp);		}#endif		/* exec shell, with correct argv and env */		execv(loginpath, argv_init);	        /* NOT REACHED */		perror_msg_and_die("execv");	}	ts->shell_pid = pid;	return ts;}static voidfree_session(struct tsession *ts){	struct tsession *t = sessions;	/* Unlink this telnet session from the session list.  */	if(t == ts)		sessions = ts->next;	else {		while(t->next != ts)			t = t->next;		t->next = ts->next;	}	free(ts->buf1);	free(ts->buf2);	kill(ts->shell_pid, SIGKILL);	wait4(ts->shell_pid, NULL, 0, NULL);	close(ts->ptyfd);	close(ts->sockfd);	if(ts->ptyfd == maxfd || ts->sockfd == maxfd)		maxfd--;	if(ts->ptyfd == maxfd || ts->sockfd == maxfd)		maxfd--;	free(ts);}int main(int argc, char **argv){	struct sockaddr_in sa;	int master_fd;	fd_set rdfdset, wrfdset;	int selret;	int on = 1;	int portnbr = 23;	int c, ii;	int daemonize = 0;	char *interface_name = NULL;	struct ifreq interface;#ifdef USE_SYSLOG	char *appname;	appname = strrchr (argv [0], '/');	if (!appname) appname = argv [0];	    else appname++;#endif	/* check if user supplied a port number */	for (;;) {		c = getopt( argc, argv, "i:p:l:hd");		if (c == EOF) break;		switch (c) {			case 'p':				portnbr = atoi(optarg);				break;			case 'i':				interface_name = strdup(optarg);				break;			case 'l':				loginpath = strdup(optarg);				break;			case 'd':				daemonize = 1;				break;			case 'h': 			default:				show_usage();				exit(1);		}	}	if (!loginpath) {		loginpath = SHELLPATH;		if (access(loginpath, X_OK) < 0) loginpath = "/bin/sh";	}	  	if (access(loginpath, X_OK) < 0) {		/* workaround: error_msg_and_die has doesn't understand 		   variable argument lists yet */		fprintf(stderr,"\"%s\"",loginpath);		perror_msg_and_die(" is no valid executable!\n");	}	printf("telnetd: starting\n");	printf("  port: %i; interface: %s; login program: %s\n",		portnbr, (interface_name)?interface_name:"any", loginpath);	argv_init[0] = loginpath;	sessions = 0;	/* Grab a TCP socket.  */	master_fd = socket(AF_INET, SOCK_STREAM, 0);	if (master_fd < 0) {		perror("socket");		return 1;	}	(void)setsockopt(master_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));	/* Set it to listen to specified port */	memset((void *)&sa, 0, sizeof(sa));	sa.sin_family = AF_INET;	sa.sin_port = htons(portnbr);	/* Set it to listen on the specified interface */	if (interface_name) {		strcpy(interface.ifr_name, interface_name);		/* use ioctl() here as BSD does not have setsockopt() */		if (ioctl(master_fd, SIOCGIFADDR, &interface) < 0) {			printf("Please check the NIC you specified with -i option\n");			perror("ioctl SIOCGFADDR");			return 1;		}		sa.sin_addr = ((struct sockaddr_in *)(&interface.ifr_addr))->sin_addr;	} else 		sa.sin_addr.s_addr = htonl(INADDR_ANY);	if (bind(master_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {		perror("bind");		return 1;	}	if (listen(master_fd, 1) < 0) {		perror("listen");		return 1;	}	if (daemonize) 	{		DEBUG_OUT("  daemonizing\n");		if (daemon(0, 1) < 0) perror_msg_and_die("daemon");	}#ifdef USE_SYSLOG	openlog(appname , LOG_NDELAY | LOG_PID, LOG_DAEMON);		syslog(LOG_INFO, "%s (port: %i, ifname: %s, login: %s) startup succeeded\n"\	    , appname, portnbr, (interface_name)?interface_name:"any", loginpath);	closelog();#endif	maxfd = master_fd;	do {		struct tsession *ts;		FD_ZERO(&rdfdset);		FD_ZERO(&wrfdset);		/* select on the master socket, all telnet sockets and their		 * ptys if there is room in their respective session buffers.		 */		FD_SET(master_fd, &rdfdset);		ts = sessions;		while (ts) {			/* buf1 is used from socket to pty			 * buf2 is used from pty to socket			 */			if (ts->size1 > 0) {				FD_SET(ts->ptyfd, &wrfdset);  /* can write to pty */			}			if (ts->size1 < BUFSIZE) {				FD_SET(ts->sockfd, &rdfdset); /* can read from socket */			}			if (ts->size2 > 0) {				FD_SET(ts->sockfd, &wrfdset); /* can write to socket */			}			if (ts->size2 < BUFSIZE) {				FD_SET(ts->ptyfd, &rdfdset);  /* can read from pty */			}			ts = ts->next;		}		selret = select(maxfd + 1, &rdfdset, &wrfdset, 0, 0);		if (!selret)			break;		/* First check for and accept new sessions.  */		if (FD_ISSET(master_fd, &rdfdset)) {			int fd, salen;			salen = sizeof(sa);				if ((fd = accept(master_fd, (struct sockaddr *)&sa,					 &salen)) < 0) {				continue;			} else {				/* Create a new session and link it into our active list. */				struct tsession *new_ts;#ifdef USE_SYSLOG				openlog(appname , LOG_NDELAY, LOG_DAEMON);					syslog(LOG_INFO, "connection from: %s\n", inet_ntoa(sa.sin_addr));				closelog();#endif				new_ts = make_new_session(fd);				if (new_ts) {					new_ts->next = sessions;					sessions = new_ts;					if (fd > maxfd)						maxfd = fd;				} else {					close(fd);				}			}		}		/* Then check for data tunneling.  */		ts = sessions;		while (ts) { /* For all sessions...  */			int maxlen, w, r;			struct tsession *next = ts->next; /* in case we free ts. */			if (ts->size1 && FD_ISSET(ts->ptyfd, &wrfdset)) {			    int processed, num_totty;			    char *ptr;				/* Write to pty from buffer 1.  */								maxlen = MIN(BUFSIZE - ts->wridx1,					     ts->size1);				ptr = remove_iacs(ts->buf1 + ts->wridx1, maxlen, 					&processed, &num_totty);						/* the difference between processed and num_totty				   is all the iacs we removed from the stream.				   Adjust buf1 accordingly. */				ts->wridx1 += processed - num_totty;				ts->size1 -= processed - num_totty;				w = write(ts->ptyfd, ptr, num_totty);				if (w < 0) {					perror("write");					free_session(ts);					ts = next;					continue;				}				ts->wridx1 += w;				ts->size1 -= w;				if (ts->wridx1 == BUFSIZE)					ts->wridx1 = 0;			}			if (ts->size2 && FD_ISSET(ts->sockfd, &wrfdset)) {				/* Write to socket from buffer 2.  */				maxlen = MIN(BUFSIZE - ts->wridx2,					     ts->size2);				w = write(ts->sockfd, ts->buf2 + ts->wridx2, maxlen);				if (w < 0) {					perror("write");					free_session(ts);					ts = next;					continue;				}				ts->wridx2 += w;				ts->size2 -= w;				if (ts->wridx2 == BUFSIZE)					ts->wridx2 = 0;			}			if (ts->size1 < BUFSIZE && FD_ISSET(ts->sockfd, &rdfdset)) {				/* Read from socket to buffer 1. */				maxlen = MIN(BUFSIZE - ts->rdidx1,					     BUFSIZE - ts->size1);				r = read(ts->sockfd, ts->buf1 + ts->rdidx1, maxlen);				if (!r || (r < 0 && errno != EINTR)) {					free_session(ts);					ts = next;					continue;				}				if(!*(ts->buf1 + ts->rdidx1 + r - 1)) {					r--;					if(!r)						continue;				}				ts->rdidx1 += r;				ts->size1 += r;				if (ts->rdidx1 == BUFSIZE)					ts->rdidx1 = 0;			}			if (ts->size2 < BUFSIZE && FD_ISSET(ts->ptyfd, &rdfdset)) {				/* Read from pty to buffer 2.  */				maxlen = MIN(BUFSIZE - ts->rdidx2,					     BUFSIZE - ts->size2);				r = read(ts->ptyfd, ts->buf2 + ts->rdidx2, maxlen);				if (!r || (r < 0 && errno != EINTR)) {					free_session(ts);					ts = next;					continue;				}				for (ii=0; ii < r; ii++)				  if (*(ts->buf2 + ts->rdidx2 + ii) == 3)				    fprintf(stderr, "found <CTRL>-<C> in data!\n");				ts->rdidx2 += r;				ts->size2 += r;				if (ts->rdidx2 == BUFSIZE)					ts->rdidx2 = 0;			}			if (ts->size1 == 0) {				ts->rdidx1 = 0;				ts->wridx1 = 0;			}			if (ts->size2 == 0) {				ts->rdidx2 = 0;				ts->wridx2 = 0;			}			ts = next;		}	} while (1);	return 0;}

⌨️ 快捷键说明

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