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

📄 tree.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			return 0;		}		arg = expr -> data.funcall.arglist;		s = binding -> value -> value.fundef -> args;		while (arg && s) {			nb = dmalloc (sizeof *nb, MDL);			if (!nb) {			      blb:				binding_scope_dereference (&ns, MDL);				return 0;			} else {				memset (nb, 0, sizeof *nb);				nb -> name = dmalloc (strlen (s -> string) + 1,						      MDL);				if (nb -> name)					strcpy (nb -> name, s -> string);				else {					dfree (nb, MDL);					nb = (struct binding *)0;					goto blb;				}			}			evaluate_expression (&nb -> value, packet, lease,					     client_state,					     in_options, cfg_options, scope,					     arg -> data.arg.val, file, line);			nb -> next = ns -> bindings;			ns -> bindings = nb;			arg = arg -> data.arg.next;			s = s -> next;		}		if (arg) {			log_error ("%s: too many arguments.",				   expr -> data.funcall.name);			binding_scope_dereference (&ns, MDL);			return 0;		}		if (s) {			log_error ("%s: too few arguments.",				   expr -> data.funcall.name);			binding_scope_dereference (&ns, MDL);			return 0;		}		if (scope && *scope)			binding_scope_reference (&ns -> outer, *scope, MDL);		status = (execute_statements			  (&bv, packet,			   lease, client_state, in_options, cfg_options, &ns,			   binding -> value -> value.fundef -> statements));		binding_scope_dereference (&ns, MDL);		if (!bv)			return 1;        } else if (is_boolean_expression (expr)) {		if (!binding_value_allocate (&bv, MDL))			return 0;		bv -> type = binding_boolean;		status = (evaluate_boolean_expression			  (&bv -> value.boolean, packet, lease, client_state,			   in_options, cfg_options, scope, expr));	} else if (is_numeric_expression (expr)) {		if (!binding_value_allocate (&bv, MDL))			return 0;		bv -> type = binding_numeric;		status = (evaluate_numeric_expression			  (&bv -> value.intval, packet, lease, client_state,			   in_options, cfg_options, scope, expr));	} else if (is_data_expression  (expr)) {		if (!binding_value_allocate (&bv, MDL))			return 0;		bv -> type = binding_data;		status = (evaluate_data_expression			  (&bv -> value.data, packet, lease, client_state,			   in_options, cfg_options, scope, expr, MDL));	} else if (is_dns_expression (expr)) {#if defined (NSUPDATE)		if (!binding_value_allocate (&bv, MDL))			return 0;		bv -> type = binding_dns;		status = (evaluate_dns_expression			  (&bv -> value.dns, packet, lease, client_state,			   in_options, cfg_options, scope, expr));#endif	} else {		log_error ("%s: invalid expression type: %d",			   "evaluate_expression", expr -> op);		return 0;	}	if (result && status)		binding_value_reference (result, bv, file, line);	binding_value_dereference (&bv, MDL);	return status;}int binding_value_dereference (struct binding_value **v,			       const char *file, int line){	struct binding_value *bv = *v;	*v = (struct binding_value *)0;	/* Decrement the reference count.   If it's nonzero, we're	   done. */	--(bv -> refcnt);	rc_register (file, line, v, bv, bv -> refcnt, 1, RC_MISC);	if (bv -> refcnt > 0)		return 1;	if (bv -> refcnt < 0) {		log_error ("%s(%d): negative refcnt!", file, line);#if defined (DEBUG_RC_HISTORY)		dump_rc_history (bv);#endif#if defined (POINTER_DEBUG)		abort ();#else		return 0;#endif	}	switch (bv -> type) {	      case binding_boolean:	      case binding_numeric:		break;	      case binding_data:		if (bv -> value.data.buffer)			data_string_forget (&bv -> value.data, file, line);		break;	      case binding_dns:#if defined (NSUPDATE)		if (bv -> value.dns) {			if (bv -> value.dns -> r_data) {				dfree (bv -> value.dns -> r_data_ephem, MDL);				bv -> value.dns -> r_data = (unsigned char *)0;				bv -> value.dns -> r_data_ephem =					(unsigned char *)0;			}			minires_freeupdrec (bv -> value.dns);		}		break;#endif	      default:		log_error ("%s(%d): invalid binding type: %d",			   file, line, bv -> type);		return 0;	}	dfree (bv, file, line);	return 1;}#if defined (NSUPDATE)int evaluate_dns_expression (result, packet, lease, client_state, in_options,			     cfg_options, scope, expr)	ns_updrec **result;	struct packet *packet;	struct lease *lease;	struct client_state *client_state;	struct option_state *in_options;	struct option_state *cfg_options;	struct binding_scope **scope;	struct expression *expr;{	ns_updrec *foo;	unsigned long ttl = 0;	char *tname;	struct data_string name, data;	int r0, r1, r2, r3;	if (!result || *result) {		log_error ("evaluate_dns_expression called with non-null %s",			   "result pointer");#if defined (POINTER_DEBUG)		abort ();#else		return 0;#endif	}			switch (expr -> op) {#if defined (NSUPDATE)	      case expr_ns_add:		r0 = evaluate_numeric_expression (&ttl, packet, lease,						  client_state,						  in_options, cfg_options,						  scope,						  expr -> data.ns_add.ttl);		goto nsfinish;	      case expr_ns_exists:		ttl = 1;	      case expr_ns_delete:	      case expr_ns_not_exists:		r0 = 1;	      nsfinish:		memset (&name, 0, sizeof name);		r1 = evaluate_data_expression (&name, packet, lease,					       client_state,					       in_options, cfg_options, scope,					       expr -> data.ns_add.rrname,					       MDL);		if (r1) {			/* The result of the evaluation may or may not			   be NUL-terminated, but we need it			   terminated for sure, so we have to allocate			   a buffer and terminate it. */			tname = dmalloc (name.len + 1, MDL);			if (!tname) {				r2 = 0;				r1 = 0;				data_string_forget (&name, MDL);			} else {				memcpy (tname, name.data, name.len);				tname [name.len] = 0;				memset (&data, 0, sizeof data);				r2 = evaluate_data_expression					(&data, packet, lease, client_state,					 in_options, cfg_options, scope,					 expr -> data.ns_add.rrdata, MDL);			}		} else			r2 = 0;		if (r0 && r1 && (r2 || expr -> op != expr_ns_add)) {		    *result = minires_mkupdrec (((expr -> op == expr_ns_add ||						  expr -> op == expr_ns_delete)						 ? S_UPDATE : S_PREREQ),						tname,						expr -> data.ns_add.rrclass,						expr -> data.ns_add.rrtype,						ttl);		    if (!*result) {			  ngood:			    if (r2) {				data_string_forget (&data, MDL);				r2 = 0;			    }		    } else {			if (data.len) {				/* As a special case, if we get exactly				   four bytes of data, it's an IP address				   represented as a 32-bit quantity, which				   is actually what we *should* be getting				   here.   Because res_mkupdrec is currently				   broken and expects a dotted quad, convert				   it.   This should be fixed when the new				   resolver is merged. */				if (data.len == 4) {				    (*result) -> r_data_ephem =					    dmalloc (16, MDL);				    if (!(*result) -> r_data_ephem)					goto dpngood;				    (*result) -> r_data =					    (*result) -> r_data_ephem;				    /*%Audit% 16 bytes max. %2004.06.17,Safe%*/				    sprintf ((char *)(*result) -> r_data_ephem,					     "%u.%u.%u.%u",					     data.data [0] & 0xff,					     data.data [1] & 0xff,					     data.data [2] & 0xff,					     data.data [3] & 0xff);				    (*result) -> r_size = 					    strlen ((const char *)						    (*result) -> r_data);				} else {				    (*result) -> r_size = data.len;				    (*result) -> r_data_ephem =					    dmalloc (data.len, MDL);				    if (!(*result) -> r_data_ephem) {				      dpngood: /* double plus ungood. */					minires_freeupdrec (*result);					*result = 0;					goto ngood;				    }				    (*result) -> r_data =					    (*result) -> r_data_ephem;				    memcpy ((*result) -> r_data_ephem,					    data.data, data.len);				}			} else {				(*result) -> r_data = 0;				(*result) -> r_size = 0;			}			switch (expr -> op) {			      case expr_ns_add:				(*result) -> r_opcode = ADD;				break;			      case expr_ns_delete:				(*result) -> r_opcode = DELETE;				break;			      case expr_ns_exists:				(*result) -> r_opcode = YXRRSET;				break;			      case expr_ns_not_exists:				(*result) -> r_opcode = NXRRSET;				break;				/* Can't happen, but satisfy gcc. */			      default:				break;			}		    }		}		if (r1) {			data_string_forget (&name, MDL);			dfree (tname, MDL);		}		if (r2)			data_string_forget (&data, MDL);		/* One flaw in the thinking here: an IP address and an		   ASCII string both look like data expressions, but		   for A records, we want an ASCII string, not a		   binary IP address.  Do I need to turn binary IP		   addresses into a seperate type?  */		return (r0 && r1 &&			(r2 || expr -> op != expr_ns_add) && *result);#else	      case expr_ns_add:	      case expr_ns_delete:	      case expr_ns_exists:	      case expr_ns_not_exists:		return 0;#endif	      case expr_funcall:		log_error ("%s: dns values for functions not supported.",			   expr -> data.funcall.name);		break;	      case expr_variable_reference:		log_error ("%s: dns values for variables not supported.",			   expr -> data.variable);		break;	      case expr_check:	      case expr_equal:	      case expr_not_equal:	      case expr_and:	      case expr_or:	      case expr_not:	      case expr_match:	      case expr_static:	      case expr_known:	      case expr_exists:	      case expr_variable_exists:		log_error ("Boolean opcode in evaluate_dns_expression: %d",		      expr -> op);		return 0;	      case expr_none:	      case expr_substring:	      case expr_suffix:	      case expr_option:	      case expr_hardware:	      case expr_const_data:	      case expr_packet:	      case expr_concat:	      case expr_encapsulate:	      case expr_host_lookup:	      case expr_encode_int8:	      case expr_encode_int16:	      case expr_encode_int32:	      case expr_binary_to_ascii:	      case expr_reverse:	      case expr_filename:	      case expr_sname:	      case expr_pick_first_value:	      case expr_host_decl_name:	      case expr_config_option:	      case expr_leased_address:	      case expr_null:		log_error ("Data opcode in evaluate_dns_expression: %d",		      expr -> op);		return 0;	      case expr_extract_int8:	      case expr_extract_int16:	      case expr_extract_int32:	      case expr_const_int:	      case expr_lease_time:	      case expr_dns_transaction:	      case expr_add:	      case expr_subtract:	      case expr_multiply:	      case expr_divide:	      case expr_remainder:	      case expr_binary_and:	      case expr_binary_or:	      case expr_binary_xor:	      case expr_client_state:		log_error ("Numeric opcode in evaluate_dns_expression: %d",		      expr -> op);		return 0;	      case expr_function:		log_error ("Function opcode in evaluate_dns_expression: %d",		      expr -> op);		return 0;	      case expr_arg:		break;	}	log_error ("Bogus opcode in evaluate_dns_expression: %d",		   expr -> op);	return 0;}#endif /* defined (NSUPDATE) */int evaluate_boolean_expression (result, packet, lease, client_state,				 in_options, cfg_options, scope, expr)	int *result;	struct packet *packet;	struct lease *lease;	struct client_state *client_state;	struct option_state *in_options;	struct option_state *cfg_options;	struct binding_scope **scope;	struct expression *expr;{	struct data_string left, right;	struct data_string rrtype, rrname, rrdata;	unsigned long ttl;	int srrtype, srrname, srrdata, sttl;	int bleft, bright;	int sleft, sright;	struct binding *binding;	struct binding_value *bv, *obv;	switch (expr -> op) {	      case expr_check:		*result = check_collection (packet, lease,					    expr -> data.check);#if defined (DEBUG_EXPRESSIONS)		log_debug ("bool: check (%s) returns %s",			   expr -> data.check -> name,			   *result ? "true" : "false");#endif		return 1;	      case expr_equal:	      case expr_not_equal:		bv = obv = (struct binding_value *)0;		sleft = evaluate_expression (&bv, packet, lease, client_state,					     in_options, cfg_options, scope,					     expr -> data.equal [0], MDL);		sright = evaluate_expression (&obv, packet, lease,					      client_state, in_options,					      cfg_options, scope,					      expr -> data.equal [1], MDL);		if (sleft && sright) {		    if (bv -> type != obv -> type)			*result = expr -> op == expr_not_equal;		    else {			switch (obv -> type) {			  case binding_boolean:			    if (bv -> value.boolean == obv -> value.boolean)				*result = expr -> op == expr_equal;			    else				*result = expr -> op == expr_not_equal;			    break;			  case binding_data:			    if ((bv -> value.data.len ==				 obv -> value.data.len) &&				!memcmp (bv -> value.data.data,					 obv -> value.data.data,					 obv -> value.data.len))				*result = expr -> op == expr_equal;			    else				*result = expr -> op == expr_not_equal;			    break;			  case binding_numeric:			    if (bv -> value.intval == obv -> value.intval)				*result = expr -> op == expr_equal;			    else				*result = expr -> op == expr_not_equal;			    break;

⌨️ 快捷键说明

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