+/************************************************/
+/* Add router-assigned variables
+Return OK/DEFER/FAIL/PASS */
+
+static int
+set_router_vars(address_item * addr, const router_instance * r)
+{
+const uschar * varlist = r->set;
+tree_node ** root = (tree_node **) &addr->prop.variables;
+int sep = ';';
+
+if (!varlist) return OK;
+
+/* Walk the varlist, creating variables */
+
+for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); )
+ {
+ const uschar * assignment = ele;
+ int esep = '=';
+ uschar * name = string_nextinlist(&assignment, &esep, NULL, 0);
+ uschar * val;
+ tree_node * node;
+
+ /* Variable name must exist and start "r_". */
+
+ if (!name || name[0] != 'r' || name[1] != '_' || !name[2])
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "bad router variable name '%s' in router '%s'\n", name, r->name);
+ return FAIL;
+ }
+ name += 2;
+
+ while (isspace(*assignment)) assignment++;
+
+ if (!(val = expand_string(US assignment)))
+ if (f.expand_string_forcedfail)
+ {
+ int yield;
+ BOOL more;
+ DEBUG(D_route) debug_printf("forced failure in expansion of \"%s\" "
+ "(router variable): decline action taken\n", ele);
+
+ /* Expand "more" if necessary; DEFER => an expansion failed */
+
+ yield = exp_bool(addr, US"router", r->name, D_route,
+ US"more", r->more, r->expand_more, &more);
+ if (yield != OK) return yield;
+
+ if (!more)
+ {
+ DEBUG(D_route)
+ debug_printf("\"more\"=false: skipping remaining routers\n");
+ router_name = NULL;
+ r = NULL;
+ return FAIL;
+ }
+ return PASS;
+ }
+ else
+ {
+ addr->message = string_sprintf("expansion of \"%s\" failed "
+ "in %s router: %s", ele, r->name, expand_string_message);
+ return DEFER;
+ }
+
+ if (!(node = tree_search(*root, name)))
+ { /* name should never be tainted */
+ node = store_get(sizeof(tree_node) + Ustrlen(name), GET_UNTAINTED);
+ Ustrcpy(node->name, name);
+ (void)tree_insertnode(root, node);
+ }
+ node->data.ptr = US val;
+ DEBUG(D_route) debug_printf("set r_%s%s = '%s'%s\n",
+ name, is_tainted(name)?" (tainted)":"",
+ val, is_tainted(val)?" (tainted)":"");
+
+ /* All expansions after this point need visibility of that variable */
+ router_var = *root;
+ }
+return OK;
+}
+
+