text: 
  
  /*
   * Odyssey.
   *
   * Scalable PostgreSQL connection pooler.
   */
  
  #include <kiwi.h>
  #include <machinarium.h>
  #include <odyssey.h>
  
  void od_config_init(od_config_t *config)
  {
  	config->daemonize = 0;
  	config->priority = 0;
  	config->log_debug = 0;
  	config->log_to_stdout = 1;
  	config->log_config = 0;
  	config->log_session = 1;
  	config->log_query = 0;
  	config->log_file = NULL;
  	config->log_stats = 1;
  	config->stats_interval = 3;
  	config->log_format = NULL;
  	config->pid_file = NULL;
  	config->unix_socket_dir = NULL;
  	config->locks_dir = NULL;
  	config->enable_online_restart_feature = 0;
  	config->bindwith_reuseport = 0;
  	config->graceful_die_on_errors = 0;
  	config->unix_socket_mode = NULL;
  
  	config->log_syslog = 0;
  	config->log_syslog_ident = NULL;
  	config->log_syslog_facility = NULL;
  
  	config->readahead = 8192;
  	config->nodelay = 1;
  
  	config->keepalive = 15;
  	config->keepalive_keep_interval = 5;
  	config->keepalive_probes = 3;
  	config->keepalive_usr_timeout = 0; // use sys default
  
  	config->workers = 1;
  	config->resolvers = 1;
  	config->client_max_set = 0;
  	config->client_max = 0;
  	config->client_max_routing = 0;
  	config->server_login_retry = 1;
  	config->cache_coroutine = 0;
  	config->cache_msg_gc_size = 0;
  	config->coroutine_stack_size = 4;
  	od_list_init(&config->listen);
  }
  
  void od_config_reload(od_config_t *current_config, od_config_t *new_config)
  {
  	current_config->client_max = new_config->client_max;
  	current_config->client_max_routing = new_config->client_max_routing;
  	current_config->server_login_retry = new_config->server_login_retry;
  }
  
  static void od_config_listen_free(od_config_listen_t *);
  
  void od_config_free(od_config_t *config)
  {
  	od_list_t *i, *n;
  	od_list_foreach_safe(&config->listen, i, n)
  	{
  		od_config_listen_t *listen;
  		listen = od_container_of(i, od_config_listen_t, link);
  		od_config_listen_free(listen);
  	}
  	if (config->log_file)
  		free(config->log_file);
  	if (config->log_format)
  		free(config->log_format);
  	if (config->pid_file)
  		free(config->pid_file);
  	if (config->unix_socket_dir)
  		free(config->unix_socket_dir);
  	if (config->log_syslog_ident)
  		free(config->log_syslog_ident);
  	if (config->log_syslog_facility)
  		free(config->log_syslog_facility);
  	if (config->locks_dir) {
  		free(config->locks_dir);
  	}
  }
  
  od_config_listen_t *od_config_listen_add(od_config_t *config)
  {
  	od_config_listen_t *listen;
  	listen = (od_config_listen_t *)malloc(sizeof(*listen));
  	if (listen == NULL)
  		return NULL;
  	memset(listen, 0, sizeof(*listen));
  	listen->port = 6432;
  	listen->backlog = 128;
  	listen->client_login_timeout = 15000;
  	od_list_init(&listen->link);
  	od_list_append(&config->listen, &listen->link);
  	return listen;
  }
  
  static void od_config_listen_free(od_config_listen_t *config)
  {
  	if (config->host)
  		free(config->host);
  	if (config->tls)
  		free(config->tls);
  	if (config->tls_ca_file)
  		free(config->tls_ca_file);
  	if (config->tls_key_file)
  		free(config->tls_key_file);
  	if (config->tls_cert_file)
  		free(config->tls_cert_file);
  	if (config->tls_protocols)
  		free(config->tls_protocols);
  	free(config);
  }
  
  int od_config_validate(od_config_t *config, od_logger_t *logger)
  {
  	/* workers */
  	if (config->workers <= 0) {
  		od_error(logger, "config", NULL, NULL, "bad workers number");
  		return -1;
  	}
  
  	/* resolvers */
  	if (config->resolvers <= 0) {
  		od_error(logger, "config", NULL, NULL, "bad resolvers number");
  		return -1;
  	}
  
  	/* coroutine_stack_size */
  	if (config->coroutine_stack_size < 4) {
  		od_error(logger, "config", NULL, NULL,
  			 "bad coroutine_stack_size number");
  		return -1;
  	}
  
  	/* log format */
  	if (config->log_format == NULL) {
  		od_error(logger, "config", NULL, NULL, "log is not defined");
  		return -1;
  	}
  
  	/* unix_socket_mode */
  	if (config->unix_socket_dir) {
  		if (config->unix_socket_mode == NULL) {
  			od_error(logger, "config", NULL, NULL,
  				 "unix_socket_mode is not set");
  			return -1;
  		}
  	}
  
  	/* listen */
  	if (od_list_empty(&config->listen)) {
  		od_error(logger, "config", NULL, NULL,
  			 "no listen servers defined");
  		return -1;
  	}
  
  	od_list_t *i;
  	od_list_foreach(&config->listen, i)
  	{
  		od_config_listen_t *listen;
  		listen = od_container_of(i, od_config_listen_t, link);
  		if (listen->host == NULL) {
  			if (config->unix_socket_dir == NULL) {
  				od_error(
  					logger, "config", NULL, NULL,
  					"listen host is not set and no unix_socket_dir is specified");
  				return -1;
  			}
  		}
  
  		/* tls */
  		if (listen->tls) {
  			if (strcmp(listen->tls, "disable") == 0) {
  				listen->tls_mode = OD_CONFIG_TLS_DISABLE;
  			} else if (strcmp(listen->tls, "allow") == 0) {
  				listen->tls_mode = OD_CONFIG_TLS_ALLOW;
  			} else if (strcmp(listen->tls, "require") == 0) {
  				listen->tls_mode = OD_CONFIG_TLS_REQUIRE;
  			} else if (strcmp(listen->tls, "verify_ca") == 0) {
  				listen->tls_mode = OD_CONFIG_TLS_VERIFY_CA;
  			} else if (strcmp(listen->tls, "verify_full") == 0) {
  				listen->tls_mode = OD_CONFIG_TLS_VERIFY_FULL;
  			} else {
  				od_error(logger, "config", NULL, NULL,
  					 "unknown tls mode");
  				return -1;
  			}
  		}
  	}
  
  	if (config->enable_online_restart_feature &&
  	    !config->bindwith_reuseport) {
  		od_dbg_printf_on_dvl_lvl(1, "validation error detected %s\n",
  					 "");
  		od_error(
  			logger, "config", NULL, NULL,
  			"online restart feature works only with SO_REUSEPORT. Disable "
  			"online restart or/and enable bindwith_reuseport");
  		return NOT_OK_RESPONSE;
  	}
  	return OK_RESPONSE;
  
  	return 0;
  }
  
  static inline char *od_config_yes_no(int value)
  {
  	return value ? "yes" : "no";
  }
  
  void od_config_print(od_config_t *config, od_logger_t *logger)
  {
  	od_log(logger, "config", NULL, NULL, "daemonize               %s",
  	       od_config_yes_no(config->daemonize));
  	od_log(logger, "config", NULL, NULL, "priority                %d",
  	       config->priority);
  	if (config->pid_file)
  		od_log(logger, "config", NULL, NULL,
  		       "pid_file                %s", config->pid_file);
  	if (config->unix_socket_dir) {
  		od_log(logger, "config", NULL, NULL,
  		       "unix_socket_dir         %s", config->unix_socket_dir);
  		od_log(logger, "config", NULL, NULL,
  		       "unix_socket_mode        %s", config->unix_socket_mode);
  	}
  	if (config->log_format)
  		od_log(logger, "config", NULL, NULL,
  		       "log_format              %s", config->log_format);
  	if (config->log_file)
  		od_log(logger, "config", NULL, NULL,
  		       "log_file                %s", config->log_file);
  	od_log(logger, "config", NULL, NULL, "log_to_stdout           %s",
  	       od_config_yes_no(config->log_to_stdout));
  	od_log(logger, "config", NULL, NULL, "log_syslog              %s",
  	       od_config_yes_no(config->log_syslog));
  	if (config->log_syslog_ident)
  		od_log(logger, "config", NULL, NULL,
  		       "log_syslog_ident        %s", config->log_syslog_ident);
  	if (config->log_syslog_facility)
  		od_log(logger, "config", NULL, NULL,
  		       "log_syslog_facility     %s",
  		       config->log_syslog_facility);
  	od_log(logger, "config", NULL, NULL, "log_debug               %s",
  	       od_config_yes_no(config->log_debug));
  	od_log(logger, "config", NULL, NULL, "log_config              %s",
  	       od_config_yes_no(config->log_config));
  	od_log(logger, "config", NULL, NULL, "log_session             %s",
  	       od_config_yes_no(config->log_session));
  	od_log(logger, "config", NULL, NULL, "log_query               %s",
  	       od_config_yes_no(config->log_query));
  	od_log(logger, "config", NULL, NULL, "log_stats               %s",
  	       od_config_yes_no(config->log_stats));
  	od_log(logger, "config", NULL, NULL, "stats_interval          %d",
  	       config->stats_interval);
  	od_log(logger, "config", NULL, NULL, "readahead               %d",
  	       config->readahead);
  	od_log(logger, "config", NULL, NULL, "nodelay                 %s",
  	       od_config_yes_no(config->nodelay));
  	od_log(logger, "config", NULL, NULL, "keepalive               %d",
  	       config->keepalive);
  	if (config->client_max_set)
  		od_log(logger, "config", NULL, NULL,
  		       "client_max              %d", config->client_max);
  	od_log(logger, "config", NULL, NULL, "client_max_routing      %d",
  	       config->client_max_routing);
  	od_log(logger, "config", NULL, NULL, "server_login_retry      %d",
  	       config->server_login_retry);
  	od_log(logger, "config", NULL, NULL, "cache_msg_gc_size       %d",
  	       config->cache_msg_gc_size);
  	od_log(logger, "config", NULL, NULL, "cache_coroutine         %d",
  	       config->cache_coroutine);
  	od_log(logger, "config", NULL, NULL, "coroutine_stack_size    %d",
  	       config->coroutine_stack_size);
  	od_log(logger, "config", NULL, NULL, "workers                 %d",
  	       config->workers);
  	od_log(logger, "config", NULL, NULL, "resolvers               %d",
  	       config->resolvers);
  
  	if (config->enable_online_restart_feature) {
  		od_log(logger, "config", NULL, NULL,
  		       "online restart enabled: OK");
  	}
  	if (config->graceful_die_on_errors) {
  		od_log(logger, "config", NULL, NULL,
  		       "graceful die enabled:   OK");
  	}
  	if (config->bindwith_reuseport) {
  		od_log(logger, "config", NULL, NULL,
  		       "socket bind with:       SO_REUSEPORT");
  	}
  #ifdef USE_SCRAM
  	od_log(logger, "config", NULL, NULL, "SCRAM auth metod:       OK");
  #endif
  
  	od_log(logger, "config", NULL, NULL, "");
  	od_list_t *i;
  	od_list_foreach(&config->listen, i)
  	{
  		od_config_listen_t *listen;
  		listen = od_container_of(i, od_config_listen_t, link);
  		od_log(logger, "config", NULL, NULL, "listen");
  		od_log(logger, "config", NULL, NULL, "  host          %s",
  		       listen->host ? listen->host : "<unix socket>");
  		od_log(logger, "config", NULL, NULL, "  port          %d",
  		       listen->port);
  		od_log(logger, "config", NULL, NULL, "  backlog       %d",
  		       listen->backlog);
  		if (listen->tls)
  			od_log(logger, "config", NULL, NULL,
  			       "  tls           %s", listen->tls);
  		if (listen->tls_ca_file)
  			od_log(logger, "config", NULL, NULL,
  			       "  tls_ca_file   %s", listen->tls_ca_file);
  		if (listen->tls_key_file)
  			od_log(logger, "config", NULL, NULL,
  			       "  tls_key_file  %s", listen->tls_key_file);
  		if (listen->tls_cert_file)
  			od_log(logger, "config", NULL, NULL,
  			       "  tls_cert_file %s", listen->tls_cert_file);
  		if (listen->tls_protocols)
  			od_log(logger, "config", NULL, NULL,
  			       "  tls_protocols %s", listen->tls_protocols);
  		od_log(logger, "config", NULL, NULL, "");
  	}
  }
  