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

📄 slc.c

📁 linux下常用的网络工具的代码
💻 C
字号:
/* * Copyright (c) 1989, 1993 *	The 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. * 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. */#ifndef lintstatic char sccsid[] = "@(#)slc.c	8.2 (Berkeley) 5/30/95";#endif /* not lint */#include "telnetd.h"/* * local variables */static unsigned char	*def_slcbuf = (unsigned char *)0;static int		def_slclen = 0;static int		slcchange;	/* change to slc is requested */static unsigned char	*slcptr;	/* pointer into slc buffer */static unsigned char	slcbuf[NSLC*6];	/* buffer for slc negotiation *//* * send_slc * * Write out the current special characters to the client. */voidsend_slc(){	register int i;	/*	 * Send out list of triplets of special characters	 * to client.  We only send info on the characters	 * that are currently supported.	 */	for (i = 1; i <= NSLC; i++) {		if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)			continue;		add_slc((unsigned char)i, slctab[i].current.flag,							slctab[i].current.val);	}}  /* end of send_slc *//* * default_slc * * Set pty special characters to all the defaults. */voiddefault_slc(){	register int i;	for (i = 1; i <= NSLC; i++) {		slctab[i].current.val = slctab[i].defset.val;		if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE))			slctab[i].current.flag = SLC_NOSUPPORT;		else			slctab[i].current.flag = slctab[i].defset.flag;		if (slctab[i].sptr) {			*(slctab[i].sptr) = slctab[i].defset.val;		}	}	slcchange = 1;}  /* end of default_slc *//* * get_slc_defaults * * Initialize the slc mapping table. */	voidget_slc_defaults(){	register int i;	init_termbuf();	for (i = 1; i <= NSLC; i++) {		slctab[i].defset.flag =			spcset(i, &slctab[i].defset.val, &slctab[i].sptr);		slctab[i].current.flag = SLC_NOSUPPORT;		slctab[i].current.val = 0;	}}  /* end of get_slc_defaults *//* * add_slc * * Add an slc triplet to the slc buffer. */voidadd_slc(register char func, register char flag, register cc_t val){	if ((*slcptr++ = (unsigned char)func) == 0xff)		*slcptr++ = 0xff;	if ((*slcptr++ = (unsigned char)flag) == 0xff)		*slcptr++ = 0xff;	if ((*slcptr++ = (unsigned char)val) == 0xff)		*slcptr++ = 0xff;}  /* end of add_slc *//* * start_slc * * Get ready to process incoming slc's and respond to them. * * The parameter getit is non-zero if it is necessary to grab a copy * of the terminal control structures. */voidstart_slc(register int getit){	slcchange = 0;	if (getit)		init_termbuf();	(void) sprintf((char *)slcbuf, "%c%c%c%c",					IAC, SB, TELOPT_LINEMODE, LM_SLC);	slcptr = slcbuf + 4;}  /* end of start_slc *//* * end_slc * * Finish up the slc negotiation.  If something to send, then send it. */intend_slc(register unsigned char **bufp){	register int len;	void netflush();	/*	 * If a change has occured, store the new terminal control	 * structures back to the terminal driver.	 */	if (slcchange) {		set_termbuf();	}	/*	 * If the pty state has not yet been fully processed and there is a	 * deferred slc request from the client, then do not send any	 * sort of slc negotiation now.  We will respond to the client's	 * request very soon.	 */	if (def_slcbuf && (terminit() == 0)) {		return(0);	}	if (slcptr > (slcbuf + 4)) {		if (bufp) {			*bufp = &slcbuf[4];			return(slcptr - slcbuf - 4);		} else {			(void) sprintf((char *)slcptr, "%c%c", IAC, SE);			slcptr += 2;			len = slcptr - slcbuf;			net_output_datalen(slcbuf, len);			netflush();  /* force it out immediately */			DEBUG(debug_options, 1,                              printsub('>', slcbuf+2, len-2));		}	}	return (0);}  /* end of end_slc *//* * process_slc * * Figure out what to do about the client's slc */voidprocess_slc(register unsigned char func, register unsigned char flag, register cc_t val){	register int hislevel, mylevel, ack;	/*	 * Ensure that we know something about this function	 */	if (func > NSLC) {		add_slc(func, SLC_NOSUPPORT, 0);		return;	}	/*	 * Process the special case requests of 0 SLC_DEFAULT 0	 * and 0 SLC_VARIABLE 0.  Be a little forgiving here, don't	 * worry about whether the value is actually 0 or not.	 */	if (func == 0) {		if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {			default_slc();			send_slc();		} else if (flag == SLC_VARIABLE) {			send_slc();		}		return;	}	/*	 * Appears to be a function that we know something about.  So	 * get on with it and see what we know.	 */	hislevel = flag & SLC_LEVELBITS;	mylevel = slctab[func].current.flag & SLC_LEVELBITS;	ack = flag & SLC_ACK;	/*	 * ignore the command if:	 * the function value and level are the same as what we already have;	 * or the level is the same and the ack bit is set	 */	if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {		return;	} else if (ack) {		/*		 * If we get here, we got an ack, but the levels don't match.		 * This shouldn't happen.  If it does, it is probably because		 * we have sent two requests to set a variable without getting		 * a response between them, and this is the first response.		 * So, ignore it, and wait for the next response.		 */		return;	} else {		change_slc(func, flag, val);	}}  /* end of process_slc *//* * change_slc * * Process a request to change one of our special characters. * Compare client's request with what we are capable of supporting. */voidchange_slc(register char func, register char flag, register cc_t val){	register int hislevel, mylevel;	hislevel = flag & SLC_LEVELBITS;	mylevel = slctab[func].defset.flag & SLC_LEVELBITS;	/*	 * If client is setting a function to NOSUPPORT	 * or DEFAULT, then we can easily and directly	 * accomodate the request.	 */	if (hislevel == SLC_NOSUPPORT) {		slctab[func].current.flag = flag;		slctab[func].current.val = (cc_t)_POSIX_VDISABLE;		flag |= SLC_ACK;		add_slc(func, flag, val);		return;	}	if (hislevel == SLC_DEFAULT) {		/*		 * Special case here.  If client tells us to use		 * the default on a function we don't support, then		 * return NOSUPPORT instead of what we may have as a		 * default level of DEFAULT.		 */		if (mylevel == SLC_DEFAULT) {			slctab[func].current.flag = SLC_NOSUPPORT;		} else {			slctab[func].current.flag = slctab[func].defset.flag;		}		slctab[func].current.val = slctab[func].defset.val;		add_slc(func, slctab[func].current.flag,						slctab[func].current.val);		return;	}	/*	 * Client wants us to change to a new value or he	 * is telling us that he can't change to our value.	 * Some of the slc's we support and can change,	 * some we do support but can't change,	 * and others we don't support at all.	 * If we can change it then we have a pointer to	 * the place to put the new value, so change it,	 * otherwise, continue the negotiation.	 */	if (slctab[func].sptr) {		/*		 * We can change this one.		 */		slctab[func].current.val = val;		*(slctab[func].sptr) = val;		slctab[func].current.flag = flag;		flag |= SLC_ACK;		slcchange = 1;		add_slc(func, flag, val);	} else {		/*		* It is not possible for us to support this		* request as he asks.		*		* If our level is DEFAULT, then just ack whatever was		* sent.		*		* If he can't change and we can't change,		* then degenerate to NOSUPPORT.		*		* Otherwise we send our level back to him, (CANTCHANGE		* or NOSUPPORT) and if CANTCHANGE, send		* our value as well.		*/		if (mylevel == SLC_DEFAULT) {			slctab[func].current.flag = flag;			slctab[func].current.val = val;			flag |= SLC_ACK;		} else if (hislevel == SLC_CANTCHANGE &&				    mylevel == SLC_CANTCHANGE) {			flag &= ~SLC_LEVELBITS;			flag |= SLC_NOSUPPORT;			slctab[func].current.flag = flag;		} else {			flag &= ~SLC_LEVELBITS;			flag |= mylevel;			slctab[func].current.flag = flag;			if (mylevel == SLC_CANTCHANGE) {				slctab[func].current.val =					slctab[func].defset.val;				val = slctab[func].current.val;			}		}		add_slc(func, flag, val);	}}  /* end of change_slc *//* * check_slc * * Check the special characters in use and notify the client if any have * changed.  Only those characters that are capable of being changed are * likely to have changed.  If a local change occurs, kick the support level * and flags up to the defaults. */voidcheck_slc(){	register int i;	for (i = 1; i <= NSLC; i++) {		if (i == SLC_EOF && term_change_eof ())		  continue;		if (slctab[i].sptr &&				(*(slctab[i].sptr) != slctab[i].current.val)) {			slctab[i].current.val = *(slctab[i].sptr);			if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE)				slctab[i].current.flag = SLC_NOSUPPORT;			else				slctab[i].current.flag = slctab[i].defset.flag;			add_slc((unsigned char)i, slctab[i].current.flag,						slctab[i].current.val);		}	}}  /* check_slc *//* * do_opt_slc * * Process an slc option buffer.  Defer processing of incoming slc's * until after the terminal state has been processed.  Save the first slc * request that comes along, but discard all others. * * ptr points to the beginning of the buffer, len is the length. */voiddo_opt_slc(register unsigned char *ptr, register int len){	register unsigned char func, flag;	cc_t val;	register unsigned char *end = ptr + len;	if (terminit()) {  /* go ahead */		while (ptr < end) {			func = *ptr++;			if (ptr >= end) break;			flag = *ptr++;			if (ptr >= end) break;			val = (cc_t)*ptr++;			process_slc(func, flag, val);		}	} else {		/*		 * save this slc buffer if it is the first, otherwise dump		 * it.		 */		if (def_slcbuf == (unsigned char *)0) {			def_slclen = len;			def_slcbuf = (unsigned char *)malloc((unsigned)len);			if (def_slcbuf == (unsigned char *)0)				return;  /* too bad */			memmove(def_slcbuf, ptr, len);		}	}}  /* end of do_opt_slc *//* * deferslc * * Do slc stuff that was deferred. */voiddeferslc(){	if (def_slcbuf) {		start_slc(1);		do_opt_slc(def_slcbuf, def_slclen);		(void) end_slc(0);		free(def_slcbuf);		def_slcbuf = (unsigned char *)0;		def_slclen = 0;	}}  /* end of deferslc */

⌨️ 快捷键说明

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