cmogstored 1.8.1 - use default system stack size
[cmogstored.git] / cfg_parser.rl
blobf180af14e3a3264abae8a13f01a8ba17f394f44b
1 /*
2  * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
3  * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
4  */
5 /*
6  * parses config files used by the original (Perl) mogstored
7  */
8 #include "cmogstored.h"
9 #include "cfg.h"
10 #include "listen_parser.h"
12 static char *mystrdup(const char *key, char *mark_beg, const char *p)
14         size_t mark_len = p - mark_beg;
15         mark_beg[mark_len] = 0;
16         if (strlen(mark_beg) != mark_len) {
17                 syslog(LOG_ERR, "NUL character in `%s' value", key);
18                 return NULL;
19         }
21         return xstrdup(mark_beg);
24 %%{
25         machine cfg_parser;
26         include listen_parser_common "listen_parser_common.rl";
28         eor = '\n';
29         ignored_line := ( (any-'\n')* eor ) @ { fgoto main; };
30         lws = (space-'\n');
31         comment = lws* ("#"(any-'\n')*);
32         comment_line = comment eor;
33         sep = lws* "=" lws*;
35         path = ((any - space)+) > { mark_beg = fpc; };
37         mgmtlisten = lws* "mgmtlisten" sep listen comment* (eor) > {
38                 a = mog_listen_parse_internal(mark_beg, mark_len,
39                                               port_beg, port_len, sa_family);
40                 if (!a) return -1;
41                 cfg->mgmtlisten = a;
42         };
44         httplisten = lws* "httplisten" sep listen comment* eor > {
45                 a = mog_listen_parse_internal(mark_beg, mark_len,
46                                               port_beg, port_len, sa_family);
47                 if (!a) return -1;
48                 cfg->httplisten = a;
49         };
50         httpgetlisten = lws* "httpgetlisten" sep listen comment* eor > {
51                 a = mog_listen_parse_internal(mark_beg, mark_len,
52                                               port_beg, port_len, sa_family);
53                 if (!a) return -1;
54                 cfg->httpgetlisten = a;
55         };
56         docroot = lws* "docroot" sep path (comment* eor) > {
57                 /* delay realpath(3) until svc init, symlinks may change */
58                 cfg->docroot = mystrdup("docroot", mark_beg, fpc);
59                 if (!cfg->docroot) return -1;
60         };
61         pidfile = lws* "pidfile" sep path (comment* eor) > {
62                 /* delay realpath(3) until svc init, symlinks may change */
63                 cfg->pidfile = mystrdup("pidfile", mark_beg, fpc);
64                 if (!cfg->pidfile) return -1;
65         };
66         daemonize_compat = lws* "daemonize" comment* eor > {
67                 syslog(LOG_ERR,
68 "\"daemonize\" in was supported in error in the past and now deprecated");
69                 syslog(LOG_ERR,
70 "use \"daemonize = 1\" in your config file instead");
71                 cfg->daemonize = true;
72         };
73         daemonize = lws* "daemonize" sep
74                 ((any - space)+) > { mark_beg = fpc; }
75                 (comment* eor) > {
76                         mark_len = fpc - mark_beg;
77                         mark_beg[mark_len] = 0;
79                         /* special case for compatibility with mogstored */
80                         cfg->daemonize = strcmp("0", mark_beg);
81                 };
82         maxconns = lws* "maxconns" sep
83                 (digit+) > { mark_beg = fpc; }
84                 (comment* eor) > {
85                         mark_len = fpc - mark_beg;
86                         mark_beg[mark_len] = 0;
87                         errno = 0;
88                         cfg->maxconns = strtoul(mark_beg, NULL, 10);
89                         if (errno) {
90                                 syslog(LOG_ERR,
91                                        "failed to parse: maxconns = %s - %m",
92                                        mark_beg);
93                                 return -1;
94                         }
95                 };
96         server = lws* "server" sep
97                 (alpha+) > { mark_beg = fpc; }
98                 (comment* eor) > {
99                         cfg->server = mystrdup("server", mark_beg, fpc);
100                         if (!cfg->server) return -1;
101                         mog_cfg_check_server(cfg);
102                 };
103         serverbin = lws* "serverbin" sep path
104                 (comment* eor) > {
105                         char *tmp = mystrdup("serverbin", mark_beg, fpc);
106                         if (!tmp) return -1;
107                         warn("W: serverbin = %s ignored", tmp);
108                         free(tmp);
109                 };
110         main := (mgmtlisten | httplisten | httpgetlisten |
111                  pidfile | docroot | daemonize | daemonize_compat | maxconns |
112                  server | serverbin ) +
113                 $! {
114                         fhold;
115                         fgoto ignored_line;
116                 };
119 %% write data;
121 /* this is a one-shot parser, no need to stream local config files  */
122 int mog_cfg_parse(struct mog_cfg *cfg, char *buf, size_t len)
124         char *p, *pe, *eof = NULL;
125         char *mark_beg = NULL;
126         char *port_beg = NULL;
127         size_t mark_len = 0;
128         size_t port_len = 0;
129         sa_family_t sa_family = AF_INET;
130         struct mog_addrinfo *a;
131         int cs;
133         %% write init;
135         p = buf;
136         pe = buf + len;
138         %% write exec;
140         if (cs == cfg_parser_error)
141                 return -1;
143         assert(p <= pe && "buffer overflow after cfg parse");
144         return 0;