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

📄 parse.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (token == ARRAY) {		token = next_token (&val, (unsigned *)0, cfile);		if (token != OF) {			parse_warn (cfile, "expecting \"of\".");			skip_to_semi (cfile);			return 0;		}		arrayp = 1;		token = next_token (&val, (unsigned *)0, cfile);	}	if (token == LBRACE) {		recordp = 1;		token = next_token (&val, (unsigned *)0, cfile);	}	/* At this point we're expecting a data type. */      next_type:	if (has_encapsulation) {		parse_warn (cfile,			    "encapsulate must always be the last item.");		skip_to_semi (cfile);		return 0;	}	switch (token) {	      case ARRAY:		if (arrayp) {			parse_warn (cfile, "no nested arrays.");			skip_to_rbrace (cfile, recordp);			if (recordp)				skip_to_semi (cfile);			return 0;		}		token = next_token (&val, (unsigned *)0, cfile);		if (token != OF) {			parse_warn (cfile, "expecting \"of\".");			skip_to_semi (cfile);			return 0;		}		arrayp = recordp + 1;		token = next_token (&val, (unsigned *)0, cfile);		if ((recordp) && (token == LBRACE)) {			parse_warn (cfile,				    "only uniform array inside record.");			skip_to_rbrace (cfile, recordp + 1);			skip_to_semi (cfile);			return 0;		}		goto next_type;	      case BOOLEAN:		type = 'f';		break;	      case INTEGER:		is_signed = 1;	      parse_integer:		token = next_token (&val, (unsigned *)0, cfile);		if (token != NUMBER) {			parse_warn (cfile, "expecting number.");			skip_to_rbrace (cfile, recordp);			if (recordp)				skip_to_semi (cfile);			return 0;		}		switch (atoi (val)) {		      case 8:			type = is_signed ? 'b' : 'B';			break;		      case 16:			type = is_signed ? 's' : 'S';			break;		      case 32:			type = is_signed ? 'l' : 'L';			break;		      default:			parse_warn (cfile,				    "%s bit precision is not supported.", val);			skip_to_rbrace (cfile, recordp);			if (recordp)				skip_to_semi (cfile);			return 0;		}		break;	      case SIGNED:		is_signed = 1;	      parse_signed:		token = next_token (&val, (unsigned *)0, cfile);		if (token != INTEGER) {			parse_warn (cfile, "expecting \"integer\" keyword.");			skip_to_rbrace (cfile, recordp);			if (recordp)				skip_to_semi (cfile);			return 0;		}		goto parse_integer;	      case UNSIGNED:		is_signed = 0;		goto parse_signed;	      case IP_ADDRESS:		type = 'I';		break;	      case DOMAIN_NAME:		type = 'd';		goto no_arrays;	      case TEXT:		type = 't';	      no_arrays:		if (arrayp) {			parse_warn (cfile, "arrays of text strings not %s",				    "yet supported.");			skip_to_rbrace (cfile, recordp);			if (recordp)				skip_to_semi (cfile);			return 0;		}		no_more_in_record = 1;		break;	      case STRING_TOKEN:		type = 'X';		goto no_arrays;	      case ENCAPSULATE:		token = next_token (&val, (unsigned *)0, cfile);		if (!is_identifier (token)) {			parse_warn (cfile,				    "expecting option space identifier");			skip_to_semi (cfile);			return 0;		}		if (strlen (val) + tokix + 2 > sizeof (tokbuf))			goto toobig;		tokbuf [tokix++] = 'E';		strcpy (&tokbuf [tokix], val);		tokix += strlen (val);		type = '.';		has_encapsulation = 1;		break;	      default:		parse_warn (cfile, "unknown data type %s", val);		skip_to_rbrace (cfile, recordp);		if (recordp)			skip_to_semi (cfile);		return 0;	}	if (tokix == sizeof tokbuf) {	      toobig:		parse_warn (cfile, "too many types in record.");		skip_to_rbrace (cfile, recordp);		if (recordp)			skip_to_semi (cfile);		return 0;	}	tokbuf [tokix++] = type;	if (recordp) {		token = next_token (&val, (unsigned *)0, cfile);		if (arrayp > recordp) {			if (tokix == sizeof tokbuf) {				parse_warn (cfile,					    "too many types in record.");				skip_to_rbrace (cfile, 1);				skip_to_semi (cfile);				return 0;			}			arrayp = 0;			tokbuf[tokix++] = 'a';		}		if (token == COMMA) {			if (no_more_in_record) {				parse_warn (cfile,					    "%s must be at end of record.",					    type == 't' ? "text" : "string");				skip_to_rbrace (cfile, 1);				if (recordp)					skip_to_semi (cfile);				return 0;			}			token = next_token (&val, (unsigned *)0, cfile);			goto next_type;		}		if (token != RBRACE) {			parse_warn (cfile, "expecting right brace.");			skip_to_rbrace (cfile, 1);			if (recordp)				skip_to_semi (cfile);			return 0;		}	}	if (!parse_semi (cfile)) {		parse_warn (cfile, "semicolon expected.");		skip_to_semi (cfile);		if (recordp)			skip_to_semi (cfile);		return 0;	}	if (has_encapsulation && arrayp) {		parse_warn (cfile,			    "Arrays of encapsulations don't make sense.");		return 0;	}	if (has_encapsulation && tokbuf [0] == 'E')		has_encapsulation = 0;	s = dmalloc (tokix +		     (arrayp ? 1 : 0) +		     (has_encapsulation ? 1 : 0) + 1, MDL);	if (!s)		log_fatal ("no memory for option format.");	if (has_encapsulation)		s [0] = 'e';	memcpy (s + has_encapsulation, tokbuf, tokix);	tokix += has_encapsulation;	if (arrayp)		s [tokix++] = (arrayp > recordp) ? 'a' : 'A';	s [tokix] = 0;	option -> format = s;	if (option -> universe -> options [option -> code]) {		/* XXX Free the option, but we can't do that now because they		   XXX may start out static. */	}	option -> universe -> options [option -> code] = option;	option_hash_add (option -> universe -> hash,			 (const char *)option -> name,			 0, option, MDL);	return 1;}/* * base64 :== NUMBER_OR_STRING */int parse_base64 (data, cfile)	struct data_string *data;	struct parse *cfile;{	enum dhcp_token token;	const char *val;	int i, j, k;	unsigned acc = 0;	static unsigned char		from64 [] = {64, 64, 64, 64, 64, 64, 64, 64,  /*  \"#$%&' */			     64, 64, 64, 62, 64, 64, 64, 63,  /* ()*+,-./ */			     52, 53, 54, 55, 56, 57, 58, 59,  /* 01234567 */			     60, 61, 64, 64, 64, 64, 64, 64,  /* 89:;<=>? */			     64, 0, 1, 2, 3, 4, 5, 6,	      /* @ABCDEFG */			     7, 8, 9, 10, 11, 12, 13, 14,     /* HIJKLMNO */			     15, 16, 17, 18, 19, 20, 21, 22,  /* PQRSTUVW */			     23, 24, 25, 64, 64, 64, 64, 64,  /* XYZ[\]^_ */			     64, 26, 27, 28, 29, 30, 31, 32,  /* 'abcdefg */			     33, 34, 35, 36, 37, 38, 39, 40,  /* hijklmno */			     41, 42, 43, 44, 45, 46, 47, 48,  /* pqrstuvw */			     49, 50, 51, 64, 64, 64, 64, 64}; /* xyz{|}~  */	struct string_list *bufs = (struct string_list *)0,			   *last = (struct string_list *)0,			   *t;	int cc = 0;	int terminated = 0;		/* It's possible for a + or a / to cause a base64 quantity to be	   tokenized into more than one token, so we have to parse them all	   in before decoding. */	do {		unsigned l;		token = next_token (&val, &l, cfile);		t = dmalloc (l + sizeof *t, MDL);		if (!t)			log_fatal ("no memory for base64 buffer.");		memset (t, 0, (sizeof *t) - 1);		memcpy (t -> string, val, l + 1);		cc += l;		if (last)			last -> next = t;		else			bufs = t;		last = t;		token = peek_token (&val, (unsigned *)0, cfile);	} while (token == NUMBER_OR_NAME || token == NAME || token == EQUAL ||		 token == NUMBER || token == PLUS || token == SLASH ||		 token == STRING);	data -> len = cc;	data -> len = (data -> len * 3) / 4;	if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {		parse_warn (cfile, "can't allocate buffer for base64 data.");		data -> len = 0;		data -> data = (unsigned char *)0;		return 0;	}			j = k = 0;	for (t = bufs; t; t = t -> next) {	    for (i = 0; t -> string [i]; i++) {		unsigned foo = t -> string [i];		if (terminated && foo != '=') {			parse_warn (cfile,				    "stuff after base64 '=' terminator: %s.",				    &t -> string [i]);			goto bad;		}		if (foo < ' ' || foo > 'z') {		      bad64:			parse_warn (cfile,				    "invalid base64 character %d.",				    t -> string [i]);		      bad:			data_string_forget (data, MDL);			goto out;		}		if (foo == '=')			terminated = 1;		else {			foo = from64 [foo - ' '];			if (foo == 64)				goto bad64;			acc = (acc << 6) + foo;			switch (k % 4) {			      case 0:				break;			      case 1:				data -> buffer -> data [j++] = (acc >> 4);				acc = acc & 0x0f;				break;							      case 2:				data -> buffer -> data [j++] = (acc >> 2);				acc = acc & 0x03;				break;			      case 3:				data -> buffer -> data [j++] = acc;				acc = 0;				break;			}		}		k++;	    }	}	if (k % 4) {		if (acc) {			parse_warn (cfile,				    "partial base64 value left over: %d.",				    acc);		}	}	data -> len = j;	data -> data = data -> buffer -> data;      out:	for (t = bufs; t; t = last) {		last = t -> next;		dfree (t, MDL);	}	if (data -> len)		return 1;	else		return 0;}/* * colon-seperated-hex-list :== NUMBER | *				NUMBER COLON colon-seperated-hex-list */int parse_cshl (data, cfile)	struct data_string *data;	struct parse *cfile;{	u_int8_t ibuf [128];	unsigned ilen = 0;	unsigned tlen = 0;	struct option_tag *sl = (struct option_tag *)0;	struct option_tag *next, **last = &sl;	enum dhcp_token token;	const char *val;	unsigned char *rvp;	do {		token = next_token (&val, (unsigned *)0, cfile);		if (token != NUMBER && token != NUMBER_OR_NAME) {			parse_warn (cfile, "expecting hexadecimal number.");			skip_to_semi (cfile);			for (; sl; sl = next) {				next = sl -> next;				dfree (sl, MDL);			}			return 0;		}		if (ilen == sizeof ibuf) {			next = (struct option_tag *)				dmalloc (ilen - 1 +					 sizeof (struct option_tag), MDL);			if (!next)				log_fatal ("no memory for string list.");			memcpy (next -> data, ibuf, ilen);			*last = next;			last = &next -> next;			tlen += ilen;			ilen = 0;		}		convert_num (cfile, &ibuf [ilen++], val, 16, 8);		token = peek_token (&val, (unsigned *)0, cfile);		if (token != COLON)			break;		token = next_token (&val, (unsigned *)0, cfile);	} while (1);	if (!buffer_allocate (&data -> buffer, tlen + ilen, MDL))		log_fatal ("no memory to store octet data.");	data -> data = &data -> buffer -> data [0];	data -> len = tlen + ilen;	data -> terminated = 0;	rvp = &data -> buffer -> data [0];	while (sl) {		next = sl -> next;		memcpy (rvp, sl -> data, sizeof ibuf);		rvp += sizeof ibuf;		dfree (sl, MDL);		sl = next;	}		memcpy (rvp, ibuf, ilen);	return 1;}/* * executable-statements :== executable-statement executable-statements | *			     executable-statement * * executable-statement :== *	IF if-statement | * 	ADD class-name SEMI | *	BREAK SEMI | *	OPTION option-parameter SEMI | *	SUPERSEDE option-parameter SEMI | *	PREPEND option-parameter SEMI | *	APPEND option-parameter SEMI */int parse_executable_statements (statements, cfile, lose, case_context)	struct executable_statement **statements;	struct parse *cfile;	int *lose;	enum expression_context case_context;{	struct executable_statement **next;	next = statements;	while (parse_executable_statement (next, cfile, lose, case_context))		next = &((*next) -> next);	if (!*lose)		return 1;	return 0;}int parse_executable_statement (result, cfile, lose, case_context)	struct executable_statement **result;	struct parse *cfile;	int *lose;	enum expression_context case_context;{	enum dhcp_token token;	const char *val;	struct executable_statement base;	struct class *cta;	struct option *option;	struct option_cache *cache;	int known;	int flag;	int i;	struct dns_zone *zone;	isc_result_t status;	char *s;	token = peek_token (&val, (unsigned *)0, cfile);	switch (token) {	      case IF:		next_token (&val, (unsigned *)0, cfile);		return parse_if_statement (result, cfile, lose);	      case TOKEN_ADD:		token = next_token (&val, (unsigned *)0, cfile);		token = next_token (&val, (unsigned *)0, cfile);		if (token != STRING) {			parse_warn (cfile, "expecting class name.");			skip_to_semi (cfile);			*lose = 1;			return 0;		}		cta = (struct class *)0;		status = find_class (&cta, val, MDL);		if (status != ISC_R_SUCCESS) {			parse_warn (cfile, "class %s: %s",				    val, isc_result_totext (status));			skip_to_semi (cfile);			*lose = 1;			return 0;		}		if (!parse_semi (cfile)) {			*lose = 1;			return 0;		}		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for new statement.");		(*result) -> op = add_statement;		(*result) -> data.add = cta;		break;	      case BREAK:		token = next_token (&val, (unsigned *)0, cfile);		if (!parse_semi (cfile)) {			*lose = 1;			return 0;		}		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for new statement.");		(*result) -> op = break_statement;		break;	      case SEND:

⌨️ 快捷键说明

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