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

📄 conflex.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* conflex.c   Lexical scanner for dhcpd config file... *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *   Internet Systems Consortium, Inc. *   950 Charter Street *   Redwood City, CA 94063 *   <info@isc.org> *   http://www.isc.org/ * * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. * To learn more about Internet Systems Consortium, see * ``http://www.isc.org/''.  To learn more about Vixie Enterprises, * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see * ``http://www.nominum.com''. */#ifndef lintstatic char copyright[] ="$Id: conflex.c,v 1.92.2.7 2004/06/10 17:59:14 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";#endif /* not lint */#include "dhcpd.h"#include <ctype.h>static int get_char PROTO ((struct parse *));static enum dhcp_token get_token PROTO ((struct parse *));static void skip_to_eol PROTO ((struct parse *));static enum dhcp_token read_string PROTO ((struct parse *));static enum dhcp_token read_number PROTO ((int, struct parse *));static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));static enum dhcp_token intern PROTO ((char *, enum dhcp_token));isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)	struct parse **cfile;	int file;	char *inbuf;	unsigned buflen;	const char *name;	int eolp;{	struct parse *tmp;	tmp = dmalloc (sizeof (struct parse), MDL);	if (!tmp)		return ISC_R_NOMEMORY;	memset (tmp, 0, sizeof *tmp);	tmp -> token = 0;	tmp -> tlname = name;	tmp -> lpos = tmp -> line = 1;	tmp -> cur_line = tmp -> line1;	tmp -> prev_line = tmp -> line2;	tmp -> token_line = tmp -> cur_line;	tmp -> cur_line [0] = tmp -> prev_line [0] = 0;	tmp -> warnings_occurred = 0;	tmp -> file = file;	tmp -> eol_token = eolp;	tmp -> bufix = 0;	tmp -> buflen = buflen;	if (inbuf) {		tmp -> bufsiz = 0;		tmp -> inbuf = inbuf;	} else {		tmp -> inbuf = dmalloc (8192, MDL);		if (!tmp -> inbuf) {			dfree (tmp, MDL);			return ISC_R_NOMEMORY;		}		tmp -> bufsiz = 8192;	}	*cfile = tmp;	return ISC_R_SUCCESS;}isc_result_t end_parse (cfile)	struct parse **cfile;{	if ((*cfile) -> bufsiz)		dfree ((*cfile) -> inbuf, MDL);	dfree (*cfile, MDL);	*cfile = (struct parse *)0;	return ISC_R_SUCCESS;}static int get_char (cfile)	struct parse *cfile;{	/* My kingdom for WITH... */	int c;	if (cfile -> bufix == cfile -> buflen) {		if (cfile -> file != -1) {			cfile -> buflen =				read (cfile -> file,				      cfile -> inbuf, cfile -> bufsiz);			if (cfile -> buflen == 0) {				c = EOF;				cfile -> bufix = 0;			} else if (cfile -> buflen < 0) {				c = EOF;				cfile -> bufix = cfile -> buflen = 0;			} else {				c = cfile -> inbuf [0];				cfile -> bufix = 1;			}		} else			c = EOF;	} else {		c = cfile -> inbuf [cfile -> bufix];		cfile -> bufix++;	}	if (!cfile -> ugflag) {		if (c == EOL) {			if (cfile -> cur_line == cfile -> line1) {					cfile -> cur_line = cfile -> line2;				cfile -> prev_line = cfile -> line1;			} else {				cfile -> cur_line = cfile -> line1;				cfile -> prev_line = cfile -> line2;			}			cfile -> line++;			cfile -> lpos = 1;			cfile -> cur_line [0] = 0;		} else if (c != EOF) {			if (cfile -> lpos <= 80) {				cfile -> cur_line [cfile -> lpos - 1] = c;				cfile -> cur_line [cfile -> lpos] = 0;			}			cfile -> lpos++;		}	} else		cfile -> ugflag = 0;	return c;		}static enum dhcp_token get_token (cfile)	struct parse *cfile;{	int c;	enum dhcp_token ttok;	static char tb [2];	int l, p, u;	do {		l = cfile -> line;		p = cfile -> lpos;		u = cfile -> ugflag;		c = get_char (cfile);#ifdef OLD_LEXER		if (c == '\n' && p == 1 && !u		    && cfile -> comment_index < sizeof cfile -> comments)			cfile -> comments [cfile -> comment_index++] = '\n';#endif		if (!(c == '\n' && cfile -> eol_token)		    && isascii (c) && isspace (c))			continue;		if (c == '#') {#ifdef OLD_LEXER			if (cfile -> comment_index < sizeof cfile -> comments)			    cfile -> comments [cfile -> comment_index++] = '#';#endif			skip_to_eol (cfile);			continue;		}		if (c == '"') {			cfile -> lexline = l;			cfile -> lexchar = p;			ttok = read_string (cfile);			break;		}		if ((isascii (c) && isdigit (c)) || c == '-') {			cfile -> lexline = l;			cfile -> lexchar = p;			ttok = read_number (c, cfile);			break;		} else if (isascii (c) && isalpha (c)) {			cfile -> lexline = l;			cfile -> lexchar = p;			ttok = read_num_or_name (c, cfile);			break;		} else if (c == EOF) {			ttok = END_OF_FILE;			cfile -> tlen = 0;			break;		} else {			cfile -> lexline = l;			cfile -> lexchar = p;			tb [0] = c;			tb [1] = 0;			cfile -> tval = tb;			cfile -> tlen = 1;			ttok = c;			break;		}	} while (1);	return ttok;}enum dhcp_token next_token (rval, rlen, cfile)	const char **rval;	unsigned *rlen;	struct parse *cfile;{	int rv;	if (cfile -> token) {		if (cfile -> lexline != cfile -> tline)			cfile -> token_line = cfile -> cur_line;		cfile -> lexchar = cfile -> tlpos;		cfile -> lexline = cfile -> tline;		rv = cfile -> token;		cfile -> token = 0;	} else {		rv = get_token (cfile);		cfile -> token_line = cfile -> cur_line;	}	if (rval)		*rval = cfile -> tval;	if (rlen)		*rlen = cfile -> tlen;#ifdef DEBUG_TOKENS	fprintf (stderr, "%s:%d ", cfile -> tval, rv);#endif	return rv;}enum dhcp_token peek_token (rval, rlen, cfile)	const char **rval;	unsigned int *rlen;	struct parse *cfile;{	int x;	if (!cfile -> token) {		cfile -> tlpos = cfile -> lexchar;		cfile -> tline = cfile -> lexline;		cfile -> token = get_token (cfile);		if (cfile -> lexline != cfile -> tline)			cfile -> token_line = cfile -> prev_line;		x = cfile -> lexchar;		cfile -> lexchar = cfile -> tlpos;		cfile -> tlpos = x;		x = cfile -> lexline;		cfile -> lexline = cfile -> tline;		cfile -> tline = x;	}	if (rval)		*rval = cfile -> tval;	if (rlen)		*rlen = cfile -> tlen;#ifdef DEBUG_TOKENS	fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);#endif	return cfile -> token;}static void skip_to_eol (cfile)	struct parse *cfile;{	int c;	do {		c = get_char (cfile);		if (c == EOF)			return;#ifdef OLD_LEXER		if (cfile -> comment_index < sizeof (cfile -> comments))			comments [cfile -> comment_index++] = c;#endif		if (c == EOL) {			return;		}	} while (1);}static enum dhcp_token read_string (cfile)	struct parse *cfile;{	int i;	int bs = 0;	int c;	int value;	int hex;	for (i = 0; i < sizeof cfile -> tokbuf; i++) {	      again:		c = get_char (cfile);		if (c == EOF) {			parse_warn (cfile, "eof in string constant");			break;		}		if (bs == 1) {			switch (c) {			      case 't':				cfile -> tokbuf [i] = '\t';				break;			      case 'r':				cfile -> tokbuf [i] = '\r';				break;			      case 'n':				cfile -> tokbuf [i] = '\n';				break;			      case 'b':				cfile -> tokbuf [i] = '\b';				break;			      case '0':			      case '1':			      case '2':			      case '3':				hex = 0;				value = c - '0';				++bs;				goto again;			      case 'x':				hex = 1;				value = 0;				++bs;				goto again;			      default:				cfile -> tokbuf [i] = c;				bs = 0;				break;			}			bs = 0;		} else if (bs > 1) {			if (hex) {				if (c >= '0' && c <= '9') {					value = value * 16 + (c - '0');				} else if (c >= 'a' && c <= 'f') {					value = value * 16 + (c - 'a' + 10);				} else if (c >= 'A' && c <= 'F') {					value = value * 16 + (c - 'A' + 10);				} else {					parse_warn (cfile,						    "invalid hex digit: %x",						    c);					bs = 0;					continue;				}				if (++bs == 4) {					cfile -> tokbuf [i] = value;					bs = 0;				} else					goto again;			} else {				if (c >= '0' && c <= '9') {					value = value * 8 + (c - '0');				} else {				    if (value != 0) {					parse_warn (cfile,						    "invalid octal digit %x",						    c);					continue;				    } else					cfile -> tokbuf [i] = 0;				    bs = 0;				}				if (++bs == 4) {					cfile -> tokbuf [i] = value;					bs = 0;				} else					goto again;			}		} else if (c == '\\') {			bs = 1;			goto again;		} else if (c == '"')			break;		else			cfile -> tokbuf [i] = c;	}	/* Normally, I'd feel guilty about this, but we're talking about	   strings that'll fit in a DHCP packet here... */	if (i == sizeof cfile -> tokbuf) {		parse_warn (cfile,			    "string constant larger than internal buffer");		--i;	}	cfile -> tokbuf [i] = 0;	cfile -> tlen = i;	cfile -> tval = cfile -> tokbuf;	return STRING;}static enum dhcp_token read_number (c, cfile)	int c;	struct parse *cfile;{	int seenx = 0;	int i = 0;	int token = NUMBER;	cfile -> tokbuf [i++] = c;	for (; i < sizeof cfile -> tokbuf; i++) {		c = get_char (cfile);		if (!seenx && c == 'x') {			seenx = 1;#ifndef OLD_LEXER		} else if (isascii (c) && !isxdigit (c) &&			   (c == '-' || c == '_' || isalpha (c))) {			token = NAME;		} else if (isascii (c) && !isdigit (c) && isxdigit (c)) {			token = NUMBER_OR_NAME;#endif		} else if (!isascii (c) || !isxdigit (c)) {			if (c != EOF) {				cfile -> bufix--;				cfile -> ugflag = 1;			}			break;		}		cfile -> tokbuf [i] = c;	}	if (i == sizeof cfile -> tokbuf) {		parse_warn (cfile,			    "numeric token larger than internal buffer");		--i;	}	cfile -> tokbuf [i] = 0;	cfile -> tlen = i;	cfile -> tval = cfile -> tokbuf;	return token;}static enum dhcp_token read_num_or_name (c, cfile)	int c;	struct parse *cfile;{	int i = 0;	enum dhcp_token rv = NUMBER_OR_NAME;	cfile -> tokbuf [i++] = c;	for (; i < sizeof cfile -> tokbuf; i++) {		c = get_char (cfile);		if (!isascii (c) ||		    (c != '-' && c != '_' && !isalnum (c))) {			if (c != EOF) {				cfile -> bufix--;				cfile -> ugflag = 1;			}			break;		}		if (!isxdigit (c))			rv = NAME;		cfile -> tokbuf [i] = c;	}	if (i == sizeof cfile -> tokbuf) {		parse_warn (cfile, "token larger than internal buffer");		--i;	}	cfile -> tokbuf [i] = 0;	cfile -> tlen = i;	cfile -> tval = cfile -> tokbuf;	return intern (cfile -> tval, rv);}static enum dhcp_token intern (atom, dfv)	char *atom;	enum dhcp_token dfv;{	if (!isascii (atom [0]))		return dfv;	switch (tolower (atom [0])) {	      case '-':		if (atom [1] == 0)			return MINUS;		break;	      case 'a':		if (!strncasecmp (atom + 1, "uth", 3)) {			if (!strncasecmp (atom + 3, "uthenticat", 10)) {				if (!strcasecmp (atom + 13, "ed"))					return AUTHENTICATED;				if (!strcasecmp (atom + 13, "ion"))					return AUTHENTICATION;				break;			}			if (!strcasecmp (atom + 1, "uthoritative"))				return AUTHORITATIVE;			break;		}		if (!strcasecmp (atom + 1, "nd"))			return AND;		if (!strcasecmp (atom + 1, "ppend"))			return APPEND;		if (!strcasecmp (atom + 1, "llow"))			return ALLOW;		if (!strcasecmp (atom + 1, "lias"))			return ALIAS;		if (!strcasecmp (atom + 1, "lgorithm"))			return ALGORITHM;		if (!strcasecmp (atom + 1, "bandoned"))			return TOKEN_ABANDONED;		if (!strcasecmp (atom + 1, "dd"))			return TOKEN_ADD;		if (!strcasecmp (atom + 1, "ll"))			return ALL;		if (!strcasecmp (atom + 1, "t"))			return AT;		if (!strcasecmp (atom + 1, "rray"))			return ARRAY;		if (!strcasecmp (atom + 1, "ddress"))			return ADDRESS;		if (!strcasecmp (atom + 1, "ctive"))			return TOKEN_ACTIVE;		break;	      case 'b':		if (!strcasecmp (atom + 1, "ackup"))			return TOKEN_BACKUP;		if (!strcasecmp (atom + 1, "ootp"))			return TOKEN_BOOTP;		if (!strcasecmp (atom + 1, "inding"))			return BINDING;

⌨️ 快捷键说明

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