mirror of https://github.com/yandex/odyssey.git
odissey: implement config parser
This commit is contained in:
parent
0be7c41987
commit
d6b072bcfd
56
odissey.conf
56
odissey.conf
|
@ -3,49 +3,49 @@
|
||||||
odissey {
|
odissey {
|
||||||
daemonize on;
|
daemonize on;
|
||||||
|
|
||||||
log_file = "";
|
log_file "";
|
||||||
pid_file = "";
|
pid_file "";
|
||||||
pooling = "session"; # transaction, statement
|
pooling "session"; # transaction, statement
|
||||||
|
|
||||||
listen {
|
listen {
|
||||||
host = "localhost";
|
host "localhost";
|
||||||
port = 1234;
|
port 1234;
|
||||||
|
|
||||||
tls_sslmode = disable
|
tls_sslmode disable
|
||||||
tls_ca_file = <system default>
|
tls_ca_file
|
||||||
tls_key_file =
|
tls_key_file
|
||||||
tls_cert_file =
|
tls_cert_file
|
||||||
tls_protocols = all;
|
tls_protocols all;
|
||||||
tls_ciphers = fast;
|
tls_ciphers fast;
|
||||||
|
|
||||||
connection_max = 100;
|
client_max 100;
|
||||||
threads = 8;
|
workers 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
server default {
|
server default {
|
||||||
host = "localhost";
|
host "localhost";
|
||||||
port = 4322;
|
port 4322;
|
||||||
}
|
}
|
||||||
|
|
||||||
server "misc" {
|
server "misc" {
|
||||||
host = "localhost";
|
host "localhost";
|
||||||
port = 4321;
|
port 4321;
|
||||||
tls_sslmode = disable
|
tls_sslmode disable
|
||||||
tls_ca_file = <system default>
|
tls_ca_file
|
||||||
tls_key_file =
|
tls_key_file
|
||||||
tls_cert_file =
|
tls_cert_file
|
||||||
tls_protocols = all;
|
tls_protocol all;
|
||||||
tls_ciphers = fast;
|
tls_ciphers fast;
|
||||||
}
|
}
|
||||||
|
|
||||||
routing {
|
routing {
|
||||||
mode = "forward"; # round-robin
|
mode "forward"; # round-robin
|
||||||
|
|
||||||
bardb {
|
bardb {
|
||||||
redirect = "misc";
|
redirect "misc";
|
||||||
client_max = 100;
|
client_max 100;
|
||||||
pool_size_min = 0;
|
pool_size_min 0;
|
||||||
pool_size_max = 100
|
pool_size_max 100;
|
||||||
# force user, db, limits
|
# force user, db, limits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
354
src/od_config.c
354
src/od_config.c
|
@ -104,9 +104,361 @@ od_configclose(odconfig_t *config)
|
||||||
od_lexfree(&config->lex);
|
od_lexfree(&config->lex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
od_configerror(odconfig_t *config, odtoken_t *tk, char *fmt, ...)
|
||||||
|
{
|
||||||
|
char msg[256];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(msg, sizeof(msg), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
int line = config->lex.line;
|
||||||
|
if (tk)
|
||||||
|
line = tk->line;
|
||||||
|
od_log(config->log, "%s:%d %s\n", config->scheme->config_file,
|
||||||
|
line, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
od_confignext(odconfig_t *config, int id, odtoken_t **tk)
|
||||||
|
{
|
||||||
|
odtoken_t *tkp = NULL;
|
||||||
|
int token = od_lexpop(&config->lex, &tkp);
|
||||||
|
if (token == OD_LERROR) {
|
||||||
|
od_configerror(config, NULL, "%s", config->lex.error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tk) {
|
||||||
|
*tk = tkp;
|
||||||
|
}
|
||||||
|
if (token != id) {
|
||||||
|
if (id < 0xff && ispunct(id)) {
|
||||||
|
od_configerror(config, tkp, "expected '%c'", id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
od_configerror(config, tkp, "expected '%s'",
|
||||||
|
od_lexname_of(&config->lex, id));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
od_confignext_yes_no(odconfig_t *config, odtoken_t **tk)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
rc = od_lexpop(&config->lex, tk);
|
||||||
|
if (rc == OD_LYES)
|
||||||
|
return 1;
|
||||||
|
if (rc == OD_LNO)
|
||||||
|
return 0;
|
||||||
|
od_configerror(config, *tk, "expected yes/no");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
od_configparse_listen(odconfig_t *config)
|
||||||
|
{
|
||||||
|
if (od_confignext(config, '{', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
odtoken_t *tk;
|
||||||
|
int rc;
|
||||||
|
int eof = 0;
|
||||||
|
while (! eof)
|
||||||
|
{
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
switch (rc) {
|
||||||
|
/* host */
|
||||||
|
case OD_LHOST:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->host = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* port */
|
||||||
|
case OD_LPORT:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->port = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* client_max */
|
||||||
|
case OD_LCLIENT_MAX:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->client_max = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* workers */
|
||||||
|
case OD_LWORKERS:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->workers = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
case OD_LEOF:
|
||||||
|
od_configerror(config, tk, "unexpected end of config file");
|
||||||
|
return -1;
|
||||||
|
case '}':
|
||||||
|
eof = 1;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
od_configerror(config, tk, "unknown option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
od_configparse_server(odconfig_t *config)
|
||||||
|
{
|
||||||
|
odscheme_server_t *server =
|
||||||
|
od_scheme_addserver(config->scheme);
|
||||||
|
if (server == NULL)
|
||||||
|
return -1;
|
||||||
|
odtoken_t *tk;
|
||||||
|
int rc;
|
||||||
|
/* name */
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
if (rc == OD_LSTRING)
|
||||||
|
server->name = tk->v.string;
|
||||||
|
else
|
||||||
|
od_lexpush(&config->lex, tk);
|
||||||
|
/* default */
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
if (rc == OD_LDEFAULT)
|
||||||
|
server->is_default = 1;
|
||||||
|
else
|
||||||
|
od_lexpush(&config->lex, tk);
|
||||||
|
|
||||||
|
if (od_confignext(config, '{', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
int eof = 0;
|
||||||
|
while (! eof)
|
||||||
|
{
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
switch (rc) {
|
||||||
|
/* host */
|
||||||
|
case OD_LHOST:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
server->host = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* port */
|
||||||
|
case OD_LPORT:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
server->port = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
case OD_LEOF:
|
||||||
|
od_configerror(config, tk, "unexpected end of config file");
|
||||||
|
return -1;
|
||||||
|
case '}':
|
||||||
|
eof = 1;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
od_configerror(config, tk, "unknown option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
od_configparse_route(odconfig_t *config, odtoken_t *name)
|
||||||
|
{
|
||||||
|
odscheme_route_t *route =
|
||||||
|
od_scheme_addroute(config->scheme);
|
||||||
|
if (route == NULL)
|
||||||
|
return -1;
|
||||||
|
route->database = name->v.string;
|
||||||
|
if (od_confignext(config, '{', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
odtoken_t *tk;
|
||||||
|
int rc;
|
||||||
|
int eof = 0;
|
||||||
|
while (! eof)
|
||||||
|
{
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
switch (rc) {
|
||||||
|
/* client_max */
|
||||||
|
case OD_LCLIENT_MAX:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
route->client_max = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* pool_min */
|
||||||
|
case OD_LPOOL_MIN:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
route->pool_min = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* pool_max */
|
||||||
|
case OD_LPOOL_MAX:
|
||||||
|
if (od_confignext(config, OD_LNUMBER, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
route->pool_max = tk->v.num;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* user */
|
||||||
|
case OD_LUSER:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
route->user = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* password */
|
||||||
|
case OD_LPASSWORD:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
route->password = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
case OD_LEOF:
|
||||||
|
od_configerror(config, tk, "unexpected end of config file");
|
||||||
|
return -1;
|
||||||
|
case '}':
|
||||||
|
eof = 1;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
od_configerror(config, tk, "unknown option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
od_configparse_routing(odconfig_t *config)
|
||||||
|
{
|
||||||
|
if (od_confignext(config, '{', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
odtoken_t *tk;
|
||||||
|
int rc;
|
||||||
|
int eof = 0;
|
||||||
|
while (! eof)
|
||||||
|
{
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
switch (rc) {
|
||||||
|
/* mode */
|
||||||
|
case OD_LMODE:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->routing = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* route (database name) */
|
||||||
|
case OD_LSTRING:
|
||||||
|
rc = od_configparse_route(config, tk);
|
||||||
|
if (rc == -1)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case OD_LEOF:
|
||||||
|
od_configerror(config, tk, "unexpected end of config file");
|
||||||
|
return -1;
|
||||||
|
case '}':
|
||||||
|
eof = 1;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
od_configerror(config, tk, "unknown option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
od_configparse(odconfig_t *config)
|
od_configparse(odconfig_t *config)
|
||||||
{
|
{
|
||||||
(void)config;
|
odtoken_t *tk;
|
||||||
|
if (od_confignext(config, OD_LODISSEY, NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
if (od_confignext(config, '{', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
int rc;
|
||||||
|
int eof = 0;
|
||||||
|
while (! eof)
|
||||||
|
{
|
||||||
|
rc = od_lexpop(&config->lex, &tk);
|
||||||
|
switch (rc) {
|
||||||
|
/* daemonize */
|
||||||
|
case OD_LDAEMONIZE:
|
||||||
|
rc = od_confignext_yes_no(config, &tk);
|
||||||
|
if (rc == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->daemonize = rc;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* log_file */
|
||||||
|
case OD_LLOG_FILE:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->log_file = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* pid_file */
|
||||||
|
case OD_LPID_FILE:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->pid_file = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* pooling */
|
||||||
|
case OD_LPOOLING:
|
||||||
|
if (od_confignext(config, OD_LSTRING, &tk) == -1)
|
||||||
|
return -1;
|
||||||
|
config->scheme->pooling = tk->v.string;
|
||||||
|
if (od_confignext(config, ';', NULL) == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* listen */
|
||||||
|
case OD_LLISTEN:
|
||||||
|
rc = od_configparse_listen(config);
|
||||||
|
if (rc == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* server */
|
||||||
|
case OD_LSERVER:
|
||||||
|
rc = od_configparse_server(config);
|
||||||
|
if (rc == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
/* routing */
|
||||||
|
case OD_LROUTING:
|
||||||
|
rc = od_configparse_routing(config);
|
||||||
|
if (rc == -1)
|
||||||
|
return -1;
|
||||||
|
continue;
|
||||||
|
case OD_LEOF:
|
||||||
|
od_configerror(config, tk, "unexpected end of config file");
|
||||||
|
return -1;
|
||||||
|
case '}':
|
||||||
|
eof = 1;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
od_configerror(config, tk, "unknown option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "od_macro.h"
|
#include "od_macro.h"
|
||||||
#include "od_list.h"
|
#include "od_list.h"
|
||||||
|
@ -20,3 +21,29 @@ void od_schemefree(odscheme_t *scheme)
|
||||||
{
|
{
|
||||||
(void)scheme;
|
(void)scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
odscheme_server_t*
|
||||||
|
od_scheme_addserver(odscheme_t *scheme)
|
||||||
|
{
|
||||||
|
odscheme_server_t *s =
|
||||||
|
(odscheme_server_t*)malloc(sizeof(*s));
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
|
memset(s, 0, sizeof(*s));
|
||||||
|
od_listinit(&s->link);
|
||||||
|
od_listappend(&scheme->servers, &s->link);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
odscheme_route_t*
|
||||||
|
od_scheme_addroute(odscheme_t *scheme)
|
||||||
|
{
|
||||||
|
odscheme_route_t *r =
|
||||||
|
(odscheme_route_t*)malloc(sizeof(*r));
|
||||||
|
if (r == NULL)
|
||||||
|
return NULL;
|
||||||
|
memset(r, 0, sizeof(*r));
|
||||||
|
od_listinit(&r->link);
|
||||||
|
od_listappend(&scheme->routing_table, &r->link);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
|
@ -11,18 +11,21 @@ typedef struct odscheme_route_t odscheme_route_t;
|
||||||
typedef struct odscheme_t odscheme_t;
|
typedef struct odscheme_t odscheme_t;
|
||||||
|
|
||||||
struct odscheme_server_t {
|
struct odscheme_server_t {
|
||||||
char *host;
|
char *name;
|
||||||
int port;
|
char *host;
|
||||||
int is_default;
|
int port;
|
||||||
|
int is_default;
|
||||||
|
odlist_t link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct odscheme_route_t {
|
struct odscheme_route_t {
|
||||||
char *database;
|
char *database;
|
||||||
char *user;
|
char *user;
|
||||||
char *password;
|
char *password;
|
||||||
int client_max;
|
int client_max;
|
||||||
int pool_min;
|
int pool_min;
|
||||||
int pool_max;
|
int pool_max;
|
||||||
|
odlist_t link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct odscheme_t {
|
struct odscheme_t {
|
||||||
|
@ -47,4 +50,10 @@ struct odscheme_t {
|
||||||
void od_schemeinit(odscheme_t*);
|
void od_schemeinit(odscheme_t*);
|
||||||
void od_schemefree(odscheme_t*);
|
void od_schemefree(odscheme_t*);
|
||||||
|
|
||||||
|
odscheme_server_t*
|
||||||
|
od_scheme_addserver(odscheme_t*);
|
||||||
|
|
||||||
|
odscheme_route_t*
|
||||||
|
od_scheme_addroute(odscheme_t*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue