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 {
|
||||
daemonize on;
|
||||
|
||||
log_file = "";
|
||||
pid_file = "";
|
||||
pooling = "session"; # transaction, statement
|
||||
log_file "";
|
||||
pid_file "";
|
||||
pooling "session"; # transaction, statement
|
||||
|
||||
listen {
|
||||
host = "localhost";
|
||||
port = 1234;
|
||||
host "localhost";
|
||||
port 1234;
|
||||
|
||||
tls_sslmode = disable
|
||||
tls_ca_file = <system default>
|
||||
tls_key_file =
|
||||
tls_cert_file =
|
||||
tls_protocols = all;
|
||||
tls_ciphers = fast;
|
||||
tls_sslmode disable
|
||||
tls_ca_file
|
||||
tls_key_file
|
||||
tls_cert_file
|
||||
tls_protocols all;
|
||||
tls_ciphers fast;
|
||||
|
||||
connection_max = 100;
|
||||
threads = 8;
|
||||
client_max 100;
|
||||
workers 8;
|
||||
}
|
||||
|
||||
server default {
|
||||
host = "localhost";
|
||||
port = 4322;
|
||||
host "localhost";
|
||||
port 4322;
|
||||
}
|
||||
|
||||
server "misc" {
|
||||
host = "localhost";
|
||||
port = 4321;
|
||||
tls_sslmode = disable
|
||||
tls_ca_file = <system default>
|
||||
tls_key_file =
|
||||
tls_cert_file =
|
||||
tls_protocols = all;
|
||||
tls_ciphers = fast;
|
||||
host "localhost";
|
||||
port 4321;
|
||||
tls_sslmode disable
|
||||
tls_ca_file
|
||||
tls_key_file
|
||||
tls_cert_file
|
||||
tls_protocol all;
|
||||
tls_ciphers fast;
|
||||
}
|
||||
|
||||
routing {
|
||||
mode = "forward"; # round-robin
|
||||
mode "forward"; # round-robin
|
||||
|
||||
bardb {
|
||||
redirect = "misc";
|
||||
client_max = 100;
|
||||
pool_size_min = 0;
|
||||
pool_size_max = 100
|
||||
redirect "misc";
|
||||
client_max 100;
|
||||
pool_size_min 0;
|
||||
pool_size_max 100;
|
||||
# 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);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "od_macro.h"
|
||||
#include "od_list.h"
|
||||
|
@ -20,3 +21,29 @@ void od_schemefree(odscheme_t *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;
|
||||
|
||||
struct odscheme_server_t {
|
||||
char *host;
|
||||
int port;
|
||||
int is_default;
|
||||
char *name;
|
||||
char *host;
|
||||
int port;
|
||||
int is_default;
|
||||
odlist_t link;
|
||||
};
|
||||
|
||||
struct odscheme_route_t {
|
||||
char *database;
|
||||
char *user;
|
||||
char *password;
|
||||
int client_max;
|
||||
int pool_min;
|
||||
int pool_max;
|
||||
char *database;
|
||||
char *user;
|
||||
char *password;
|
||||
int client_max;
|
||||
int pool_min;
|
||||
int pool_max;
|
||||
odlist_t link;
|
||||
};
|
||||
|
||||
struct odscheme_t {
|
||||
|
@ -47,4 +50,10 @@ struct odscheme_t {
|
|||
void od_schemeinit(odscheme_t*);
|
||||
void od_schemefree(odscheme_t*);
|
||||
|
||||
odscheme_server_t*
|
||||
od_scheme_addserver(odscheme_t*);
|
||||
|
||||
odscheme_route_t*
|
||||
od_scheme_addroute(odscheme_t*);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue