static int config(void) { if (config_module()) return -1; if (config_port()) return -1; if (config_service()) return -1; return 0; }
/* From a set of <b>options</b>, setup every hidden service found. Return 0 on * success or -1 on failure. If <b>validate_only</b> is set, parse, warn and * return as normal, but don't actually change the configured services. */ int hs_config_service_all(const or_options_t *options, int validate_only) { int dir_option_seen = 0, ret = -1; const config_line_t *line; smartlist_t *new_service_list = NULL; tor_assert(options); /* Newly configured service are put in that list which is then used for * validation and staging for >= v3. */ new_service_list = smartlist_new(); for (line = options->RendConfigLines; line; line = line->next) { /* Ignore all directives that aren't the start of a service. */ if (strcasecmp(line->key, "HiddenServiceDir")) { if (!dir_option_seen) { log_warn(LD_CONFIG, "%s with no preceding HiddenServiceDir directive", line->key); goto err; } continue; } /* Flag that we've seen a directory directive and we'll use it to make * sure that the torrc options ordering is actually valid. */ dir_option_seen = 1; /* Try to configure this service now. On success, it will be added to the * list and validated against the service in that same list. */ if (config_service(line, options, new_service_list) < 0) { goto err; } } /* In non validation mode, we'll stage those services we just successfully * configured. Service ownership is transferred from the list to the global * state. If any service is invalid, it will be removed from the list and * freed. All versions are handled in that function. */ if (!validate_only) { stage_services(new_service_list); } else { /* We've just validated that we were able to build a clean working list of * services. We don't need those objects anymore. */ SMARTLIST_FOREACH(new_service_list, hs_service_t *, s, hs_service_free(s)); /* For the v2 subsystem, the configuration function adds the service * object to the staging list and it is transferred in the main list * through the prunning process. In validation mode, we thus have to purge * the staging list so it's not kept in memory as valid service. */ rend_service_free_staging_list(); } /* Success. Note that the service list has no ownership of its content. */ ret = 0; goto end; err: SMARTLIST_FOREACH(new_service_list, hs_service_t *, s, hs_service_free(s)); end: smartlist_free(new_service_list); /* Tor main should call the free all function on error. */ return ret; }