|  | @@ -74,7 +74,8 @@
 | 
	
		
			
				|  |  |  #define EVENT_NEWCONSENSUS     0x0016
 | 
	
		
			
				|  |  |  #define EVENT_BUILDTIMEOUT_SET     0x0017
 | 
	
		
			
				|  |  |  #define EVENT_SIGNAL           0x0018
 | 
	
		
			
				|  |  | -#define _EVENT_MAX             0x0018
 | 
	
		
			
				|  |  | +#define EVENT_CONF_CHANGED     0x0019
 | 
	
		
			
				|  |  | +#define _EVENT_MAX             0x0019
 | 
	
		
			
				|  |  |  /* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /** Bitfield: The bit 1<<e is set if <b>any</b> open control
 | 
	
	
		
			
				|  | @@ -946,6 +947,7 @@ static const struct control_event_t control_event_table[] = {
 | 
	
		
			
				|  |  |    { EVENT_NEWCONSENSUS, "NEWCONSENSUS" },
 | 
	
		
			
				|  |  |    { EVENT_BUILDTIMEOUT_SET, "BUILDTIMEOUT_SET" },
 | 
	
		
			
				|  |  |    { EVENT_SIGNAL, "SIGNAL" },
 | 
	
		
			
				|  |  | +  { EVENT_CONF_CHANGED, "CONF_CHANGED"},
 | 
	
		
			
				|  |  |    { 0, NULL },
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -3996,6 +3998,38 @@ control_event_guard(const char *nickname, const char *digest,
 | 
	
		
			
				|  |  |    return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/** Called when a configuration option changes. This is generally triggered
 | 
	
		
			
				|  |  | + * by SETCONF requests and RELOAD/SIGHUP signals. The <b>elements</b> is
 | 
	
		
			
				|  |  | + * a smartlist_t containing (key, value, ...) pairs in sequence.
 | 
	
		
			
				|  |  | + * <b>value</b> can be NULL. */
 | 
	
		
			
				|  |  | +int
 | 
	
		
			
				|  |  | +control_event_conf_changed(smartlist_t *elements)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  int i;
 | 
	
		
			
				|  |  | +  char *result;
 | 
	
		
			
				|  |  | +  smartlist_t *lines;
 | 
	
		
			
				|  |  | +  if (!EVENT_IS_INTERESTING(EVENT_CONF_CHANGED) || smartlist_len(elements) == 0) {
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  lines = smartlist_create();
 | 
	
		
			
				|  |  | +  for (i = 0; i < smartlist_len(elements); i += 2) {
 | 
	
		
			
				|  |  | +    char *k = smartlist_get(elements, i);
 | 
	
		
			
				|  |  | +    char *v = smartlist_get(elements, i+1);
 | 
	
		
			
				|  |  | +    if (v == NULL) {
 | 
	
		
			
				|  |  | +      smartlist_asprintf_add(lines, "650-%s", k);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      smartlist_asprintf_add(lines, "650-%s=%s", k, v);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  result = smartlist_join_strings(lines, "\r\n", 0, NULL);
 | 
	
		
			
				|  |  | +  send_control_event(EVENT_CONF_CHANGED, 0,
 | 
	
		
			
				|  |  | +    "650-CONF_CHANGED\r\n%s\r\n650 OK\r\n", result);
 | 
	
		
			
				|  |  | +  tor_free(result);
 | 
	
		
			
				|  |  | +  SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
 | 
	
		
			
				|  |  | +  smartlist_free(lines);
 | 
	
		
			
				|  |  | +  return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /** Helper: Return a newly allocated string containing a path to the
 | 
	
		
			
				|  |  |   * file where we store our authentication cookie. */
 | 
	
		
			
				|  |  |  static char *
 |