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

📄 confpars.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
				parse_warn (cfile,					    "pools with failover peers %s",					    "may not permit dynamic bootp.");				log_error ("Either write a \"no failover\" %s",					   "statement and use disjoint");				log_error ("pools, or don't permit dynamic%s",					   " bootp.");				log_error ("This is a protocol limitation,%s",					   " not an ISC DHCP limitation, so");				log_error ("please don't request an %s",					   "enhancement or ask why this is.");				goto clash_testing_done;			}		}		if (!pool -> permit_list) {			if (!pool -> prohibit_list)				goto dynamic_bootp_clash;			for (permit = pool -> prohibit_list; permit;			     permit = permit -> next) {				if (permit -> type ==				    permit_dynamic_bootp_clients ||				    permit -> type == permit_all_clients)					goto clash_testing_done;			}		}	}      clash_testing_done:				#endif /* FAILOVER_PROTOCOL */	/* See if there's already a pool into which we can merge this one. */	for (pp = pool -> shared_network -> pools; pp; pp = pp -> next) {		struct lease *l;		if (pp -> group -> statements != pool -> group -> statements)			continue;#if defined (FAILOVER_PROTOCOL)		if (pool -> failover_peer != pp -> failover_peer)			continue;#endif		if (!permit_list_match (pp -> permit_list,					pool -> permit_list) ||		    !permit_list_match (pool -> permit_list,					pp -> permit_list) ||		    !permit_list_match (pp -> prohibit_list,					pool -> prohibit_list) ||		    !permit_list_match (pool -> prohibit_list,					pp -> prohibit_list))			continue;		/* Okay, we can merge these two pools.    All we have to		   do is fix up the leases, which all point to their pool. */		for (lp = lpchain; lp; lp = lp -> next) {			pool_dereference (&lp -> pool, MDL);			pool_reference (&lp -> pool, pp, MDL);		}		break;	}	/* If we didn't succeed in merging this pool into another, put	   it on the list. */	if (!pp) {		p = &pool -> shared_network -> pools;		for (; *p; p = &((*p) -> next))			;		pool_reference (p, pool, MDL);	}	/* Don't allow a pool declaration with no addresses, since it is	   probably a configuration error. */	if (!lpchain) {		parse_warn (cfile, "Pool declaration with no address range.");		log_error ("Pool declarations must always contain at least");		log_error ("one range statement.");	}	/* Dereference the lease chain. */	lp = (struct lease *)0;	while (lpchain) {		lease_reference (&lp, lpchain, MDL);		lease_dereference (&lpchain, MDL);		if (lp -> next) {			lease_reference (&lpchain, lp -> next, MDL);			lease_dereference (&lp -> next, MDL);			lease_dereference (&lp, MDL);		}	}	pool_dereference (&pool, MDL);}/* boolean :== ON SEMI | OFF SEMI | TRUE SEMI | FALSE SEMI */int parse_boolean (cfile)	struct parse *cfile;{	enum dhcp_token token;	const char *val;	int rv;	token = next_token (&val, (unsigned *)0, cfile);	if (!strcasecmp (val, "true")	    || !strcasecmp (val, "on"))		rv = 1;	else if (!strcasecmp (val, "false")		 || !strcasecmp (val, "off"))		rv = 0;	else {		parse_warn (cfile,			    "boolean value (true/false/on/off) expected");		skip_to_semi (cfile);		return 0;	}	parse_semi (cfile);	return rv;}/* Expect a left brace; if there isn't one, skip over the rest of the   statement and return zero; otherwise, return 1. */int parse_lbrace (cfile)	struct parse *cfile;{	enum dhcp_token token;	const char *val;	token = next_token (&val, (unsigned *)0, cfile);	if (token != LBRACE) {		parse_warn (cfile, "expecting left brace.");		skip_to_semi (cfile);		return 0;	}	return 1;}/* host-declaration :== hostname RBRACE parameters declarations LBRACE */void parse_host_declaration (cfile, group)	struct parse *cfile;	struct group *group;{	const char *val;	enum dhcp_token token;	struct host_decl *host;	char *name;	int declaration = 0;	int dynamicp = 0;	int deleted = 0;	isc_result_t status;	name = parse_host_name (cfile);	if (!name) {		parse_warn (cfile, "expecting a name for host declaration.");		skip_to_semi (cfile);		return;	}	host = (struct host_decl *)0;	status = host_allocate (&host, MDL);	if (status != ISC_R_SUCCESS)		log_fatal ("can't allocate host decl struct %s: %s",			   name, isc_result_totext (status));	host -> name = name;	if (!clone_group (&host -> group, group, MDL)) {		log_fatal ("can't clone group for host %s", name);	      boom:		host_dereference (&host, MDL);		return;	}	if (!parse_lbrace (cfile))		goto boom;	do {		token = peek_token (&val, (unsigned *)0, cfile);		if (token == RBRACE) {			token = next_token (&val, (unsigned *)0, cfile);			break;		}		if (token == END_OF_FILE) {			token = next_token (&val, (unsigned *)0, cfile);			parse_warn (cfile, "unexpected end of file");			break;		}		/* If the host declaration was created by the server,		   remember to save it. */		if (token == DYNAMIC) {			dynamicp = 1;			token = next_token (&val, (unsigned *)0, cfile);			if (!parse_semi (cfile))				break;			continue;		}		/* If the host declaration was created by the server,		   remember to save it. */		if (token == TOKEN_DELETED) {			deleted = 1;			token = next_token (&val, (unsigned *)0, cfile);			if (!parse_semi (cfile))				break;			continue;		}		if (token == GROUP) {			struct group_object *go;			token = next_token (&val, (unsigned *)0, cfile);			token = next_token (&val, (unsigned *)0, cfile);			if (token != STRING && !is_identifier (token)) {				parse_warn (cfile,					    "expecting string or identifier.");				skip_to_rbrace (cfile, 1);				break;			}			go = (struct group_object *)0;			if (!group_hash_lookup (&go, group_name_hash,						val, strlen (val), MDL)) {			    parse_warn (cfile, "unknown group %s in host %s",					val, host -> name);			} else {				if (host -> named_group)					group_object_dereference						(&host -> named_group, MDL);				group_object_reference (&host -> named_group,							go, MDL);				group_object_dereference (&go, MDL);			}			if (!parse_semi (cfile))				break;			continue;		}		if (token == UID) {			const char *s;			unsigned char *t = 0;			unsigned len;			token = next_token (&val, (unsigned *)0, cfile);			data_string_forget (&host -> client_identifier, MDL);			/* See if it's a string or a cshl. */			token = peek_token (&val, (unsigned *)0, cfile);			if (token == STRING) {				token = next_token (&val, &len, cfile);				s = val;				host -> client_identifier.terminated = 1;			} else {				len = 0;				t = parse_numeric_aggregate					(cfile,					 (unsigned char *)0, &len, ':', 16, 8);				if (!t) {					parse_warn (cfile,						    "expecting hex list.");					skip_to_semi (cfile);				}				s = (const char *)t;			}			if (!buffer_allocate			    (&host -> client_identifier.buffer,			     len + host -> client_identifier.terminated, MDL))				log_fatal ("no memory for uid for host %s.",					   host -> name);			host -> client_identifier.data =				host -> client_identifier.buffer -> data;			host -> client_identifier.len = len;			memcpy (host -> client_identifier.buffer -> data, s,				len + host -> client_identifier.terminated);			if (t)				dfree (t, MDL);			if (!parse_semi (cfile))				break;			continue;		}		declaration = parse_statement (cfile, host -> group,					       HOST_DECL, host,					       declaration);	} while (1);	if (deleted) {		struct host_decl *hp = (struct host_decl *)0;		if (host_hash_lookup (&hp, host_name_hash,				      (unsigned char *)host -> name,				      strlen (host -> name), MDL)) {			delete_host (hp, 0);			host_dereference (&hp, MDL);		}	} else {		if (host -> named_group && host -> named_group -> group) {			if (host -> group -> statements ||			    (host -> group -> authoritative !=			     host -> named_group -> group -> authoritative)) {				if (host -> group -> next)				    group_dereference (&host -> group -> next,						       MDL);				group_reference (&host -> group -> next,						 host -> named_group -> group,						 MDL);			} else {				group_dereference (&host -> group, MDL);				group_reference (&host -> group,						 host -> named_group -> group,						 MDL);			}		}						if (dynamicp)			host -> flags |= HOST_DECL_DYNAMIC;		else			host -> flags |= HOST_DECL_STATIC;		status = enter_host (host, dynamicp, 0);		if (status != ISC_R_SUCCESS)			parse_warn (cfile, "host %s: %s", host -> name,				    isc_result_totext (status));	}	host_dereference (&host, MDL);}/* class-declaration :== STRING LBRACE parameters declarations RBRACE*/int parse_class_declaration (cp, cfile, group, type)	struct class **cp;	struct parse *cfile;	struct group *group;	int type;{	const char *val;	enum dhcp_token token;	struct class *class = (struct class *)0, *pc = (struct class *)0;	int declaration = 0;	int lose = 0;	struct data_string data;	char *name;	const char *tname;	struct executable_statement *stmt = (struct executable_statement *)0;	struct expression *expr;	int new = 1;	isc_result_t status;	token = next_token (&val, (unsigned *)0, cfile);	if (token != STRING) {		parse_warn (cfile, "Expecting class name");		skip_to_semi (cfile);		return 0;	}	/* See if there's already a class with the specified name. */	find_class (&pc, val, MDL);	/* If this isn't a subclass, we're updating an existing class. */	if (pc && type != 0 && type != 1 && type != 3) {		class_reference (&class, pc, MDL);		new = 0;		class_dereference (&pc, MDL);	}	/* If this _is_ a subclass, there _must_ be a class with the	   same name. */	if (!pc && (type == 0 || type == 1 || type == 3)) {		parse_warn (cfile, "no class named %s", val);		skip_to_semi (cfile);		return 0;	}	/* The old vendor-class and user-class declarations had an implicit	   match.   We don't do the implicit match anymore.   Instead, for	   backward compatibility, we have an implicit-vendor-class and an	   implicit-user-class.   vendor-class and user-class declarations	   are turned into subclasses of the implicit classes, and the	   submatch expression of the implicit classes extracts the contents of	   the vendor class or user class. */	if (type == 0 || type == 1) {		data.len = strlen (val);		data.buffer = (struct buffer *)0;		if (!buffer_allocate (&data.buffer, data.len + 1, MDL))			log_fatal ("no memory for class name.");		data.data = &data.buffer -> data [0];		data.terminated = 1;		tname = type ? "implicit-vendor-class" : "implicit-user-class";	} else if (type == 2) {		tname = val;	} else {		tname = (const char *)0;	}	if (tname) {		name = dmalloc (strlen (tname) + 1, MDL);		if (!name)			log_fatal ("No memory for class name %s.", tname);		strcpy (name, val);	} else		name = (char *)0;	/* If this is a straight subclass, parse the hash string. */	if (type == 3) {		token = peek_token (&val, (unsigned *)0, cfile);		if (token == STRING) {			token = next_token (&val, &data.len, cfile);			data.buffer = (struct buffer *)0;			if (!buffer_allocate (&data.buffer,					      data.len + 1, MDL)) {				if (pc)					class_dereference (&pc, MDL);								return 0;			}			data.terminated = 1;			data.data = &data.buffer -> data [0];			memcpy ((char *)data.buffer -> data, val,				data.len + 1);		} else if (token == NUMBER_OR_NAME || token == NUMBER) {			memset (&data, 0, sizeof data);			if (!parse_cshl (&data, cfile)) {				class_dereference (&pc, MDL);				return 0;			}		} else {			parse_warn (cfile, "Expecting string or hex list.");			if (pc)				class_dereference (&pc, MDL);			return 0;		}	}	/* See if there's already a class in the hash table matching the	   hash data. */	if (type == 0 || type == 1 || type == 3)		class_hash_lookup (&class, pc -> hash,				   (const char *)data.data, data.len, MDL);	/* If we didn't find an existing class, allocate a new one. */	if (!class) {		/* Allocate the class structure... */		status = class_allocate (&class, MDL);		if (pc) {			group_reference (&class -> group, pc -> group, MDL);			class_reference (&class -> superclass, pc, MDL);			class -> lease_limit = pc -> lease_limit;			if (class -> lease_limit) {				class -> billed_leases =					dmalloc (class -> lease_limit *						 sizeof (struct lease *), MDL);				if (!class -> billed_leases)					log_fatal ("no memory for billing");				memset (class -> billed_leases, 0,					(class -> lease_limit *					 sizeof class -> billed_leases));			}			data_string_copy (&class -> hash_string, &data, MDL);			if (!pc -> hash &&			    !class_new_hash (&pc -> hash, 0, MDL))				log_fatal ("No memory for subclass hash.");			class_hash_add (pc -> hash,					(const char *)class -> hash_string.data,					class -> hash_string.len,					(void *)class, MDL);		} else {			if (!clone_group (&class -> group, group, MDL))				log_fatal ("no memory to clone class group.");		}		/* If this is an implicit vendor or user class, add a		   statement that causes the vendor or user class ID to		   be sent back in the reply. */		if (type == 0 || type == 1) {			stmt = (struct executable_statement *)0;			if (!executable_statement_allocate (&stmt, MDL))				log_fatal ("no memory for class statement.");			stmt -> op = supersede_option_statement;			if (option_cache_allocate (&stmt -> data.option,						   MDL)) {				stmt -> data.option -> data = data;				stmt -> data.option -> option =					dhcp_universe.options					[type					? DHO_VENDOR_CLASS_IDENTIFIER					: DHO_USER_CLASS];			}			class -> statements = stmt;		}		/* Save the name, if there is one. */		class -> name = name;	}	if (type == 0 || type == 1 || type == 3)

⌨️ 快捷键说明

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