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

📄 utility.c

📁 这是关于远程登陆TELNET 的源代码 已经测试过的。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * From: @(#)utility.c	5.8 (Berkeley) 3/22/91 */char util_rcsid[] =   "$Id: utility.c,v 1.11 1999/12/12 14:59:45 dholland Exp $";#define PRINTOPTIONS#include <stdarg.h>#include <sys/utsname.h>#ifdef AUTHENTICATE#include <libtelnet/auth.h>#endif#include "telnetd.h"/* * utility functions performing io related tasks */voidnetoprintf(const char *fmt, ...){   int len, maxsize;   va_list ap;   int done=0;   while (!done) {      maxsize = sizeof(netobuf) - (nfrontp - netobuf);      va_start(ap, fmt);      len = vsnprintf(nfrontp, maxsize, fmt, ap);      va_end(ap);      if (len<0 || len==maxsize) {	 /* didn't fit */	 netflush();      }      else {	 done = 1;      }   }   nfrontp += len;}/* * ttloop * *	A small subroutine to flush the network output buffer, get some data * from the network, and pass it through the telnet state machine.  We * also flush the pty input buffer (by dropping its data) if it becomes * too full. */voidttloop(void){    DIAG(TD_REPORT, netoprintf("td: ttloop\r\n"););		         if (nfrontp-nbackp) {	netflush();    }    ncc = read(net, netibuf, sizeof(netibuf));    if (ncc < 0) {	syslog(LOG_INFO, "ttloop: read: %m\n");	exit(1);    } else if (ncc == 0) {	syslog(LOG_INFO, "ttloop: peer died: EOF\n");	exit(1);    }    DIAG(TD_REPORT, netoprintf("td: ttloop read %d chars\r\n", ncc););    netip = netibuf;    telrcv();			/* state machine */    if (ncc > 0) {	pfrontp = pbackp = ptyobuf;	telrcv();    }}  /* end of ttloop *//* * Check a descriptor to see if out of band data exists on it. */int stilloob(int s)		/* socket number */{    static struct timeval timeout = { 0, 0 };    fd_set	excepts;    int value;    do {	FD_ZERO(&excepts);	FD_SET(s, &excepts);	value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);    } while ((value == -1) && (errno == EINTR));    if (value < 0) {	fatalperror(pty, "select");    }    if (FD_ISSET(s, &excepts)) {	return 1;    } else {	return 0;    }}void 	ptyflush(void){	int n;	if ((n = pfrontp - pbackp) > 0) {		DIAG((TD_REPORT | TD_PTYDATA),		     netoprintf("td: ptyflush %d chars\r\n", n););		DIAG(TD_PTYDATA, printdata("pd", pbackp, n));		n = write(pty, pbackp, n);	}	if (n < 0) {		if (errno == EWOULDBLOCK || errno == EINTR)			return;		cleanup(0);	}	pbackp += n;	if (pbackp == pfrontp)		pbackp = pfrontp = ptyobuf;}/* * nextitem() * *	Return the address of the next "item" in the TELNET data * stream.  This will be the address of the next character if * the current address is a user data character, or it will * be the address of the character following the TELNET command * if the current address is a TELNET IAC ("I Am a Command") * character. */staticchar *nextitem(char *current){    if ((*current&0xff) != IAC) {	return current+1;    }    switch (*(current+1)&0xff) {    case DO:    case DONT:    case WILL:    case WONT:	return current+3;    case SB:		/* loop forever looking for the SE */	{	    register char *look = current+2;	    for (;;) {		if ((*look++&0xff) == IAC) {		    if ((*look++&0xff) == SE) {			return look;		    }		}	    }	}    default:	return current+2;    }}  /* end of nextitem *//* * netclear() * *	We are about to do a TELNET SYNCH operation.  Clear * the path to the network. * *	Things are a bit tricky since we may have sent the first * byte or so of a previous TELNET command into the network. * So, we have to scan the network buffer from the beginning * until we are up to where we want to be. * *	A side effect of what we do, just to keep things * simple, is to clear the urgent data pointer.  The principal * caller should be setting the urgent data pointer AFTER calling * us in any case. */void netclear(void){    register char *thisitem, *next;    char *good;#define	wewant(p)	((nfrontp > p) && ((*p&0xff) == IAC) && \				((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))#if	defined(ENCRYPT)    thisitem = nclearto > netobuf ? nclearto : netobuf;#else    thisitem = netobuf;#endif    while ((next = nextitem(thisitem)) <= nbackp) {	thisitem = next;    }    /* Now, thisitem is first before/at boundary. */#if	defined(ENCRYPT)    good = nclearto > netobuf ? nclearto : netobuf;#else    good = netobuf;	/* where the good bytes go */#endif    while (nfrontp > thisitem) {	if (wewant(thisitem)) {	    int length;	    next = thisitem;	    do {		next = nextitem(next);	    } while (wewant(next) && (nfrontp > next));	    length = next-thisitem;	    bcopy(thisitem, good, length);	    good += length;	    thisitem = next;	} else {	    thisitem = nextitem(thisitem);	}    }    nbackp = netobuf;    nfrontp = good;		/* next byte to be sent */    neturg = 0;}  /* end of netclear *//* *  netflush *		Send as much data as possible to the network, *	handling requests for urgent data. */extern int not42;voidnetflush(void){    int n;    if ((n = nfrontp - nbackp) > 0) {	DIAG(TD_REPORT,	    { netoprintf("td: netflush %d chars\r\n", n);	      n = nfrontp - nbackp;  /* update count */	    });#if	defined(ENCRYPT)	if (encrypt_output) {		char *s = nclearto ? nclearto : nbackp;		if (nfrontp - s > 0) {			(*encrypt_output)((unsigned char *)s, nfrontp-s);			nclearto = nfrontp;		}	}#endif	/*	 * if no urgent data, or if the other side appears to be an	 * old 4.2 client (and thus unable to survive TCP urgent data),	 * write the entire buffer in non-OOB mode.	 */	if ((neturg == 0) || (not42 == 0)) {	    n = write(net, nbackp, n);	/* normal write */	} else {	    n = neturg - nbackp;	    /*	     * In 4.2 (and 4.3) systems, there is some question about	     * what byte in a sendOOB operation is the "OOB" data.	     * To make ourselves compatible, we only send ONE byte	     * out of band, the one WE THINK should be OOB (though	     * we really have more the TCP philosophy of urgent data	     * rather than the Unix philosophy of OOB data).	     */	    if (n > 1) {		n = send(net, nbackp, n-1, 0);	/* send URGENT all by itself */	    } else {		n = send(net, nbackp, n, MSG_OOB);	/* URGENT data */	    }	}    }    if (n < 0) {	if (errno == EWOULDBLOCK || errno == EINTR)		return;	cleanup(0);    }    nbackp += n;#if	defined(ENCRYPT)    if (nbackp > nclearto)	nclearto = 0;#endif    if (nbackp >= neturg) {	neturg = 0;    }    if (nbackp == nfrontp) {	nbackp = nfrontp = netobuf;#if	defined(ENCRYPT)	nclearto = 0;#endif    }    return;}  /* end of netflush *//* * writenet * * Just a handy little function to write a bit of raw data to the net. * It will force a transmit of the buffer if necessary * * arguments *    ptr - A pointer to a character string to write *    len - How many bytes to write */void writenet(register unsigned char *ptr, register int len){	/* flush buffer if no room for new data) */	if ((&netobuf[BUFSIZ] - nfrontp) < len) {		/* if this fails, don't worry, buffer is a little big */		netflush();	}	bcopy(ptr, nfrontp, len);	nfrontp += len;}  /* end of writenet *//* * miscellaneous functions doing a variety of little jobs follow ... */voidfatal(int f, const char *msg){	char buf[BUFSIZ];	(void) snprintf(buf, sizeof(buf), "telnetd: %s.\r\n", msg);#if	defined(ENCRYPT)	if (encrypt_output) {		/*		 * Better turn off encryption first....		 * Hope it flushes...		 */		encrypt_send_end();		netflush();	}#endif	(void) write(f, buf, (int)strlen(buf));	sleep(1);	/*XXX*/	exit(1);}voidfatalperror(int f, const char *msg){	char buf[BUFSIZ];	snprintf(buf, sizeof(buf), "%s: %s\r\n", msg, strerror(errno));	fatal(f, buf);}char editedhost[32];struct utsname kerninfo;voidedithost(const char *pat, const char *host){	char *res = editedhost;	uname(&kerninfo);	if (!pat)		pat = "";	while (*pat) {		switch (*pat) {		case '#':			if (*host)				host++;			break;		case '@':			if (*host)				*res++ = *host++;			break;		default:			*res++ = *pat;			break;		}		if (res == &editedhost[sizeof editedhost - 1]) {			*res = '\0';			return;		}		pat++;	}	if (*host)		(void) strncpy(res, host,				sizeof editedhost - (res - editedhost) -1);	else		*res = '\0';	editedhost[sizeof editedhost - 1] = '\0';}static char *putlocation;static voidputstr(const char *s){    while (*s) putchr(*s++);}void putchr(int cc){	*putlocation++ = cc;}static char fmtstr[] = { "%H:%M on %A, %d %B %Y" };void putf(const char *cp, char *where){	char *slash;	time_t t;	char db[100];	if (where)	putlocation = where;	while (*cp) {		if (*cp != '%') {			putchr(*cp++);			continue;		}		switch (*++cp) {		case 't':			slash = strrchr(line, '/');			if (slash == NULL)				putstr(line);			else				putstr(slash+1);			break;		case 'h':			putstr(editedhost);			break;		case 'd':			(void)time(&t);			(void)strftime(db, sizeof(db), fmtstr, localtime(&t));			putstr(db);			break;		case '%':			putchr('%');			break;		case 'D':			{				char	buff[128];				if (getdomainname(buff,sizeof(buff)) < 0					|| buff[0] == '\0'					|| strcmp(buff, "(none)") == 0)					break;				putstr(buff);			}			break;		case 'i':			{				char buff[3];				FILE *fp;				int p, c;				if ((fp = fopen(ISSUE_FILE, "r")) == NULL)					break;				p = '\n';				while ((c = fgetc(fp)) != EOF) {					if (p == '\n' && c == '#') {						do {							c = fgetc(fp);						} while (c != EOF && c != '\n');						continue;					} else if (c == '%') {						buff[0] = c;						c = fgetc(fp);						if (c == EOF) break;						buff[1] = c;						buff[2] = '\0';						putf(buff, NULL);					} else {						if (c == '\n') putchr('\r');						putchr(c);						p = c;					}				};				(void) fclose(fp);			}			return; /* ignore remainder of the banner string */			/*NOTREACHED*/		case 's':			putstr(kerninfo.sysname);			break;		case 'm':			putstr(kerninfo.machine);			break;		case 'r':			putstr(kerninfo.release);			break;		case 'v':#ifdef __linux__			putstr(kerninfo.version);#else			puts(kerninfo.version);#endif			break;		}		cp++;	}}#ifdef DIAGNOSTICS/* * Print telnet options and commands in plain text, if possible. */voidprintoption(const char *fmt, int option){	if (TELOPT_OK(option))		netoprintf("%s %s\r\n", fmt, TELOPT(option));	else if (TELCMD_OK(option))		netoprintf("%s %s\r\n", fmt, TELCMD(option));	else		netoprintf("%s %d\r\n", fmt, option);}

⌨️ 快捷键说明

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