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

📄 confpars.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* confpars.c   Parser 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: confpars.c,v 1.143.2.21 2004/06/10 17:59:51 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";#endif /* not lint */#include "dhcpd.h"static TIME parsed_time;#if defined (TRACING)trace_type_t *trace_readconf_type;trace_type_t *trace_readleases_type;void parse_trace_setup (){	trace_readconf_type = trace_type_register ("readconf", (void *)0,						   trace_conf_input,						   trace_conf_stop, MDL);	trace_readleases_type = trace_type_register ("readleases", (void *)0,						     trace_conf_input,						     trace_conf_stop, MDL);}#endif/* conf-file :== parameters declarations END_OF_FILE   parameters :== <nil> | parameter | parameters parameter   declarations :== <nil> | declaration | declarations declaration */isc_result_t readconf (){	return read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);}isc_result_t read_conf_file (const char *filename, struct group *group,			     int group_type, int leasep){	int file;	struct parse *cfile;	isc_result_t status;#if defined (TRACING)	char *fbuf, *dbuf;	off_t flen;	int result;	unsigned tflen, ulen;	trace_type_t *ttype;	if (leasep)		ttype = trace_readleases_type;	else		ttype = trace_readconf_type;	/* If we're in playback, we need to snarf the contents of the	   named file out of the playback file rather than trying to	   open and read it. */	if (trace_playback ()) {		dbuf = (char *)0;		tflen = 0;		status = trace_get_file (ttype, filename, &tflen, &dbuf);		if (status != ISC_R_SUCCESS)			return status;		ulen = tflen;		/* What we get back is filename\0contents, where contents is		   terminated just by the length.  So we figure out the length		   of the filename, and subtract that and the NUL from the		   total length to get the length of the contents of the file.		   We make fbuf a pointer to the contents of the file, and		   leave dbuf as it is so we can free it later. */		tflen = strlen (dbuf);		ulen = ulen - tflen - 1;		fbuf = dbuf + tflen + 1;		goto memfile;	}#endif	if ((file = open (filename, O_RDONLY)) < 0) {		if (leasep) {			log_error ("Can't open lease database %s: %m --",				   path_dhcpd_db);			log_error ("  check for failed database %s!",				   "rewrite attempt");			log_error ("Please read the dhcpd.leases manual%s",				   " page if you");			log_fatal ("don't know what to do about this.");		} else {			log_fatal ("Can't open %s: %m", filename);		}	}	cfile = (struct parse *)0;#if defined (TRACING)	flen = lseek (file, (off_t)0, SEEK_END);	if (flen < 0) {	      boom:		log_fatal ("Can't lseek on %s: %m", filename);	}	if (lseek (file, (off_t)0, SEEK_SET) < 0)		goto boom;	/* Can't handle files greater than 2^31-1. */	if (flen > 0x7FFFFFFFUL)		log_fatal ("%s: file is too long to buffer.", filename);	ulen = flen;	/* Allocate a buffer that will be what's written to the tracefile,	   and also will be what we parse from. */	tflen = strlen (filename);	dbuf = dmalloc (ulen + tflen + 1, MDL);	if (!dbuf)		log_fatal ("No memory for %s (%d bytes)",			   filename, ulen);	/* Copy the name into the beginning, nul-terminated. */	strcpy (dbuf, filename);	/* Load the file in after the NUL. */	fbuf = dbuf + tflen + 1;	result = read (file, fbuf, ulen);	if (result < 0)		log_fatal ("Can't read in %s: %m", filename);	if (result != ulen)		log_fatal ("%s: short read of %d bytes instead of %d.",			   filename, ulen, result);      memfile:	/* If we're recording, write out the filename and file contents. */	if (trace_record ())		trace_write_packet (ttype, ulen + tflen + 1, dbuf, MDL);	new_parse (&cfile, -1, fbuf, ulen, filename, 0); /* XXX */#else	new_parse (&cfile, file, (char *)0, 0, filename, 0);#endif	if (leasep)		status = lease_file_subparse (cfile);	else		status = conf_file_subparse (cfile, group, group_type);	end_parse (&cfile);#if defined (TRACING)	dfree (dbuf, MDL);#endif	close (file);	return status;}#if defined (TRACING)void trace_conf_input (trace_type_t *ttype, unsigned len, char *data){	char *fbuf;	unsigned flen;	unsigned tflen;	struct parse *cfile = (struct parse *)0;	static int postconf_initialized;	static int leaseconf_initialized;		/* Do what's done above, except that we don't have to read in the	   data, because it's already been read for us. */	tflen = strlen (data);	flen = len - tflen - 1;	fbuf = data + tflen + 1;	/* If we're recording, write out the filename and file contents. */	if (trace_record ())		trace_write_packet (ttype, len, data, MDL);	new_parse (&cfile, -1, fbuf, flen, data, 0);	if (ttype == trace_readleases_type)		lease_file_subparse (cfile);	else		conf_file_subparse (cfile, root_group, ROOT_GROUP);	end_parse (&cfile);	/* Postconfiguration needs to be done after the config file	   has been loaded. */	if (!postconf_initialized && ttype == trace_readconf_type) {		postconf_initialization (0);		postconf_initialized = 1;	}	if (!leaseconf_initialized && ttype == trace_readleases_type) {		db_startup (0);		leaseconf_initialized = 1;		postdb_startup ();	}}void trace_conf_stop (trace_type_t *ttype) { }#endif/* conf-file :== parameters declarations END_OF_FILE   parameters :== <nil> | parameter | parameters parameter   declarations :== <nil> | declaration | declarations declaration */isc_result_t conf_file_subparse (struct parse *cfile, struct group *group,				 int group_type){	const char *val;	enum dhcp_token token;	int declaration = 0;	int status;	do {		token = peek_token (&val, (unsigned *)0, cfile);		if (token == END_OF_FILE)			break;		declaration = parse_statement (cfile, group, group_type,					       (struct host_decl *)0,					       declaration);	} while (1);	token = next_token (&val, (unsigned *)0, cfile);	status = cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS;	return status;}/* lease-file :== lease-declarations END_OF_FILE   lease-statments :== <nil>   		     | lease-declaration		     | lease-declarations lease-declaration */isc_result_t lease_file_subparse (struct parse *cfile){	const char *val;	enum dhcp_token token;	isc_result_t status;	do {		token = next_token (&val, (unsigned *)0, cfile);		if (token == END_OF_FILE)			break;		if (token == LEASE) {			struct lease *lease = (struct lease *)0;			if (parse_lease_declaration (&lease, cfile)) {				enter_lease (lease);				lease_dereference (&lease, MDL);			} else				parse_warn (cfile,					    "possibly corrupt lease file");		} else if (token == HOST) {			parse_host_declaration (cfile, root_group);		} else if (token == GROUP) {			parse_group_declaration (cfile, root_group);#if defined (FAILOVER_PROTOCOL)		} else if (token == FAILOVER) {			parse_failover_state_declaration				(cfile, (dhcp_failover_state_t *)0);#endif		} else {			log_error ("Corrupt lease file - possible data loss!");			skip_to_semi (cfile);		}	} while (1);	status = cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS;	return status;}/* statement :== parameter | declaration   parameter :== timestamp   	       | DEFAULT_LEASE_TIME lease_time	       | MAX_LEASE_TIME lease_time	       | DYNAMIC_BOOTP_LEASE_CUTOFF date	       | DYNAMIC_BOOTP_LEASE_LENGTH lease_time	       | BOOT_UNKNOWN_CLIENTS boolean	       | ONE_LEASE_PER_CLIENT boolean	       | GET_LEASE_HOSTNAMES boolean	       | USE_HOST_DECL_NAME boolean	       | NEXT_SERVER ip-addr-or-hostname SEMI	       | option_parameter	       | SERVER-IDENTIFIER ip-addr-or-hostname SEMI	       | FILENAME string-parameter	       | SERVER_NAME string-parameter	       | hardware-parameter	       | fixed-address-parameter	       | ALLOW allow-deny-keyword	       | DENY allow-deny-keyword	       | USE_LEASE_ADDR_FOR_DEFAULT_ROUTE boolean	       | AUTHORITATIVE	       | NOT AUTHORITATIVE   declaration :== host-declaration		 | group-declaration		 | shared-network-declaration		 | subnet-declaration		 | VENDOR_CLASS class-declaration		 | USER_CLASS class-declaration		 | RANGE address-range-declaration */int parse_statement (cfile, group, type, host_decl, declaration)	struct parse *cfile;	struct group *group;	int type;	struct host_decl *host_decl;	int declaration;{	enum dhcp_token token;	const char *val;	struct shared_network *share;	char *t, *n;	struct expression *expr;	struct data_string data;	struct hardware hardware;	struct executable_statement *et, *ep;	struct option *option;	struct option_cache *cache;	int lose;	struct data_string key_id;	int known;	isc_result_t status;	token = peek_token (&val, (unsigned *)0, cfile);	switch (token) {	      case INCLUDE:		next_token (&val, (unsigned *)0, cfile);		token = next_token (&val, (unsigned *)0, cfile);		if (token != STRING) {			parse_warn (cfile, "filename string expected.");			skip_to_semi (cfile);		} else {			status = read_conf_file (val, group, type, 0);			if (status != ISC_R_SUCCESS)				parse_warn (cfile, "%s: bad parse.", val);			parse_semi (cfile);		}		return 1;			      case HOST:		next_token (&val, (unsigned *)0, cfile);		if (type != HOST_DECL && type != CLASS_DECL)			parse_host_declaration (cfile, group);		else {			parse_warn (cfile,				    "host declarations not allowed here.");			skip_to_semi (cfile);		}		return 1;	      case GROUP:		next_token (&val, (unsigned *)0, cfile);		if (type != HOST_DECL && type != CLASS_DECL)			parse_group_declaration (cfile, group);		else {			parse_warn (cfile,				    "group declarations not allowed here.");			skip_to_semi (cfile);		}		return 1;	      case TIMESTAMP:		next_token (&val, (unsigned *)0, cfile);		parsed_time = parse_timestamp (cfile);		break;	      case SHARED_NETWORK:		next_token (&val, (unsigned *)0, cfile);		if (type == SHARED_NET_DECL ||		    type == HOST_DECL ||		    type == SUBNET_DECL ||		    type == CLASS_DECL) {			parse_warn (cfile, "shared-network parameters not %s.",				    "allowed here");			skip_to_semi (cfile);			break;		}		parse_shared_net_declaration (cfile, group);		return 1;	      case SUBNET:		next_token (&val, (unsigned *)0, cfile);		if (type == HOST_DECL || type == SUBNET_DECL ||		    type == CLASS_DECL) {			parse_warn (cfile,				    "subnet declarations not allowed here.");			skip_to_semi (cfile);			return 1;		}		/* If we're in a subnet declaration, just do the parse. */		if (group -> shared_network) {			parse_subnet_declaration (cfile,						  group -> shared_network);			break;		}		/* Otherwise, cons up a fake shared network structure		   and populate it with the lone subnet... */		share = (struct shared_network *)0;		status = shared_network_allocate (&share, MDL);		if (status != ISC_R_SUCCESS)			log_fatal ("Can't allocate shared subnet: %s",				   isc_result_totext (status));		if (!clone_group (&share -> group, group, MDL))			log_fatal ("Can't allocate group for shared net");		shared_network_reference (&share -> group -> shared_network,					  share, MDL);		parse_subnet_declaration (cfile, share);		/* share -> subnets is the subnet we just parsed. */		if (share -> subnets) {			interface_reference (&share -> interface,					     share -> subnets -> interface,					     MDL);			/* Make the shared network name from network number. */			n = piaddrmask (share -> subnets -> net,					share -> subnets -> netmask, MDL);			share -> name = n;			/* Copy the authoritative parameter from the subnet,			   since there is no opportunity to declare it here. */			share -> group -> authoritative =				share -> subnets -> group -> authoritative;			enter_shared_network (share);		}		shared_network_dereference (&share, MDL);		return 1;	      case VENDOR_CLASS:		next_token (&val, (unsigned *)0, cfile);		if (type == CLASS_DECL) {			parse_warn (cfile,				    "class declarations not allowed here.");			skip_to_semi (cfile);			break;		}		parse_class_declaration ((struct class **)0, cfile, group, 0);		return 1;	      case USER_CLASS:		next_token (&val, (unsigned *)0, cfile);		if (type == CLASS_DECL) {			parse_warn (cfile,				    "class declarations not allowed here.");			skip_to_semi (cfile);			break;		}		parse_class_declaration ((struct class **)0, cfile, group, 1);		return 1;	      case CLASS:		next_token (&val, (unsigned *)0, cfile);		if (type == CLASS_DECL) {			parse_warn (cfile,				    "class declarations not allowed here.");			skip_to_semi (cfile);			break;		}		parse_class_declaration ((struct class **)0, cfile, group, 2);		return 1;	      case SUBCLASS:		next_token (&val, (unsigned *)0, cfile);		if (type == CLASS_DECL) {

⌨️ 快捷键说明

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