📄 tree.c
字号:
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 + -