You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cfg_file.y 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. /* $Id$ */
  2. %{
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. #include <ctype.h>
  7. #include <errno.h>
  8. #include <stdarg.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <syslog.h>
  13. #include <netinet/in.h>
  14. #include <arpa/inet.h>
  15. #include <glib.h>
  16. #include "cfg_file.h"
  17. #include "main.h"
  18. #define YYDEBUG 1
  19. extern struct config_file *cfg;
  20. extern int yylineno;
  21. extern char *yytext;
  22. LIST_HEAD (moduleoptq, module_opt) *cur_module_opt = NULL;
  23. struct metric *cur_metric = NULL;
  24. %}
  25. %union
  26. {
  27. char *string;
  28. size_t limit;
  29. char flag;
  30. unsigned int seconds;
  31. unsigned int number;
  32. double fract;
  33. }
  34. %token ERROR STRING QUOTEDSTRING FLAG
  35. %token FILENAME REGEXP QUOTE SEMICOLON OBRACE EBRACE COMMA EQSIGN
  36. %token BINDSOCK SOCKCRED DOMAIN IPADDR IPNETWORK HOSTPORT NUMBER CHECK_TIMEOUT
  37. %token MAXSIZE SIZELIMIT SECONDS BEANSTALK MYSQL USER PASSWORD DATABASE
  38. %token TEMPDIR PIDFILE SERVERS ERROR_TIME DEAD_TIME MAXERRORS CONNECT_TIMEOUT PROTOCOL RECONNECT_TIMEOUT
  39. %token READ_SERVERS WRITE_SERVER DIRECTORY_SERVERS MAILBOX_QUERY USERS_QUERY LASTLOGIN_QUERY
  40. %token MEMCACHED WORKERS REQUIRE MODULE
  41. %token MODULE_OPT PARAM VARIABLE
  42. %token HEADER_FILTERS MIME_FILTERS MESSAGE_FILTERS URL_FILTERS FACTORS METRIC NAME
  43. %token REQUIRED_SCORE FUNCTION FRACT COMPOSITES CONTROL PASSWORD
  44. %token LOGGING LOG_TYPE LOG_TYPE_CONSOLE LOG_TYPE_SYSLOG LOG_TYPE_FILE
  45. %token LOG_LEVEL LOG_LEVEL_DEBUG LOG_LEVEL_INFO LOG_LEVEL_WARNING LOG_LEVEL_ERROR LOG_FACILITY LOG_FILENAME
  46. %type <string> STRING
  47. %type <string> VARIABLE
  48. %type <string> QUOTEDSTRING MODULE_OPT PARAM
  49. %type <string> FILENAME
  50. %type <string> SOCKCRED
  51. %type <string> IPADDR IPNETWORK
  52. %type <string> HOSTPORT
  53. %type <string> DOMAIN
  54. %type <limit> SIZELIMIT
  55. %type <flag> FLAG
  56. %type <seconds> SECONDS
  57. %type <number> NUMBER
  58. %type <string> memcached_hosts bind_cred
  59. %type <fract> FRACT
  60. %%
  61. file : /* empty */
  62. | file command SEMICOLON { }
  63. ;
  64. command :
  65. bindsock
  66. | control
  67. | tempdir
  68. | pidfile
  69. | memcached
  70. | workers
  71. | require
  72. | header_filters
  73. | mime_filters
  74. | message_filters
  75. | url_filters
  76. | module_opt
  77. | variable
  78. | factors
  79. | metric
  80. | composites
  81. | logging
  82. ;
  83. tempdir :
  84. TEMPDIR EQSIGN QUOTEDSTRING {
  85. struct stat st;
  86. if (stat ($3, &st) == -1) {
  87. yyerror ("yyparse: cannot stat directory \"%s\": %s", $3, strerror (errno));
  88. YYERROR;
  89. }
  90. if (!S_ISDIR (st.st_mode)) {
  91. yyerror ("yyparse: \"%s\" is not a directory", $3);
  92. YYERROR;
  93. }
  94. cfg->temp_dir = memory_pool_strdup (cfg->cfg_pool, $3);
  95. free ($3);
  96. }
  97. ;
  98. pidfile :
  99. PIDFILE EQSIGN QUOTEDSTRING {
  100. cfg->pid_file = $3;
  101. }
  102. ;
  103. control:
  104. CONTROL OBRACE controlbody EBRACE
  105. ;
  106. controlbody:
  107. controlcmd SEMICOLON
  108. | controlbody controlcmd SEMICOLON
  109. ;
  110. controlcmd:
  111. controlsock
  112. | controlpassword
  113. ;
  114. controlsock:
  115. BINDSOCK EQSIGN bind_cred {
  116. if (!parse_bind_line (cfg, $3, 1)) {
  117. yyerror ("yyparse: parse_bind_line");
  118. YYERROR;
  119. }
  120. cfg->controller_enabled = 1;
  121. free ($3);
  122. }
  123. ;
  124. controlpassword:
  125. PASSWORD EQSIGN QUOTEDSTRING {
  126. cfg->control_password = memory_pool_strdup (cfg->cfg_pool, $3);
  127. }
  128. ;
  129. bindsock:
  130. BINDSOCK EQSIGN bind_cred {
  131. if (!parse_bind_line (cfg, $3, 0)) {
  132. yyerror ("yyparse: parse_bind_line");
  133. YYERROR;
  134. }
  135. free ($3);
  136. }
  137. ;
  138. bind_cred:
  139. STRING {
  140. $$ = $1;
  141. }
  142. | IPADDR{
  143. $$ = $1;
  144. }
  145. | DOMAIN {
  146. $$ = $1;
  147. }
  148. | HOSTPORT {
  149. $$ = $1;
  150. }
  151. | QUOTEDSTRING {
  152. $$ = $1;
  153. }
  154. ;
  155. header_filters:
  156. HEADER_FILTERS EQSIGN QUOTEDSTRING {
  157. cfg->header_filters_str = memory_pool_strdup (cfg->cfg_pool, $3);
  158. free ($3);
  159. }
  160. ;
  161. mime_filters:
  162. MIME_FILTERS EQSIGN QUOTEDSTRING {
  163. cfg->mime_filters_str = memory_pool_strdup (cfg->cfg_pool, $3);
  164. free ($3);
  165. }
  166. ;
  167. message_filters:
  168. MESSAGE_FILTERS EQSIGN QUOTEDSTRING {
  169. cfg->message_filters_str = memory_pool_strdup (cfg->cfg_pool, $3);
  170. free ($3);
  171. }
  172. ;
  173. url_filters:
  174. URL_FILTERS EQSIGN QUOTEDSTRING {
  175. cfg->url_filters_str = memory_pool_strdup (cfg->cfg_pool, $3);
  176. free ($3);
  177. }
  178. ;
  179. memcached:
  180. MEMCACHED OBRACE memcachedbody EBRACE
  181. ;
  182. memcachedbody:
  183. memcachedcmd SEMICOLON
  184. | memcachedbody memcachedcmd SEMICOLON
  185. ;
  186. memcachedcmd:
  187. memcached_servers
  188. | memcached_connect_timeout
  189. | memcached_error_time
  190. | memcached_dead_time
  191. | memcached_maxerrors
  192. | memcached_protocol
  193. ;
  194. memcached_servers:
  195. SERVERS EQSIGN memcached_server
  196. ;
  197. memcached_server:
  198. memcached_params
  199. | memcached_server COMMA memcached_params
  200. ;
  201. memcached_params:
  202. memcached_hosts {
  203. if (!add_memcached_server (cfg, $1)) {
  204. yyerror ("yyparse: add_memcached_server");
  205. YYERROR;
  206. }
  207. free ($1);
  208. }
  209. ;
  210. memcached_hosts:
  211. STRING
  212. | IPADDR
  213. | DOMAIN
  214. | HOSTPORT
  215. ;
  216. memcached_error_time:
  217. ERROR_TIME EQSIGN NUMBER {
  218. cfg->memcached_error_time = $3;
  219. }
  220. ;
  221. memcached_dead_time:
  222. DEAD_TIME EQSIGN NUMBER {
  223. cfg->memcached_dead_time = $3;
  224. }
  225. ;
  226. memcached_maxerrors:
  227. MAXERRORS EQSIGN NUMBER {
  228. cfg->memcached_maxerrors = $3;
  229. }
  230. ;
  231. memcached_connect_timeout:
  232. CONNECT_TIMEOUT EQSIGN SECONDS {
  233. cfg->memcached_connect_timeout = $3;
  234. }
  235. ;
  236. memcached_protocol:
  237. PROTOCOL EQSIGN STRING {
  238. if (strncasecmp ($3, "udp", sizeof ("udp") - 1) == 0) {
  239. cfg->memcached_protocol = UDP_TEXT;
  240. }
  241. else if (strncasecmp ($3, "tcp", sizeof ("tcp") - 1) == 0) {
  242. cfg->memcached_protocol = TCP_TEXT;
  243. }
  244. else {
  245. yyerror ("yyparse: cannot recognize protocol: %s", $3);
  246. YYERROR;
  247. }
  248. }
  249. ;
  250. workers:
  251. WORKERS EQSIGN NUMBER {
  252. cfg->workers_number = $3;
  253. }
  254. ;
  255. metric:
  256. METRIC OBRACE metricbody EBRACE {
  257. if (cur_metric == NULL || cur_metric->name == NULL) {
  258. yyerror ("yyparse: not enough arguments in metric definition");
  259. YYERROR;
  260. }
  261. g_hash_table_insert (cfg->metrics, cur_metric->name, cur_metric);
  262. cur_metric = NULL;
  263. }
  264. ;
  265. metricbody:
  266. | metriccmd SEMICOLON
  267. | metricbody metriccmd SEMICOLON
  268. ;
  269. metriccmd:
  270. | metricname
  271. | metricfunction
  272. | metricscore
  273. ;
  274. metricname:
  275. NAME EQSIGN QUOTEDSTRING {
  276. if (cur_metric == NULL) {
  277. cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
  278. }
  279. cur_metric->name = memory_pool_strdup (cfg->cfg_pool, $3);
  280. }
  281. ;
  282. metricfunction:
  283. FUNCTION EQSIGN QUOTEDSTRING {
  284. if (cur_metric == NULL) {
  285. cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
  286. }
  287. cur_metric->func_name = memory_pool_strdup (cfg->cfg_pool, $3);
  288. }
  289. ;
  290. metricscore:
  291. REQUIRED_SCORE EQSIGN NUMBER {
  292. if (cur_metric == NULL) {
  293. cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
  294. }
  295. cur_metric->required_score = $3;
  296. }
  297. | REQUIRED_SCORE EQSIGN FRACT {
  298. if (cur_metric == NULL) {
  299. cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
  300. }
  301. cur_metric->required_score = $3;
  302. }
  303. ;
  304. factors:
  305. FACTORS OBRACE factorsbody EBRACE
  306. ;
  307. factorsbody:
  308. factorparam SEMICOLON
  309. | factorsbody factorparam SEMICOLON
  310. ;
  311. factorparam:
  312. QUOTEDSTRING EQSIGN FRACT {
  313. double *tmp = memory_pool_alloc (cfg->cfg_pool, sizeof (double));
  314. *tmp = $3;
  315. g_hash_table_insert (cfg->factors, $1, tmp);
  316. }
  317. | QUOTEDSTRING EQSIGN NUMBER {
  318. double *tmp = memory_pool_alloc (cfg->cfg_pool, sizeof (double));
  319. *tmp = $3;
  320. g_hash_table_insert (cfg->factors, $1, tmp);
  321. };
  322. require:
  323. REQUIRE OBRACE requirebody EBRACE
  324. ;
  325. requirebody:
  326. requirecmd SEMICOLON
  327. | requirebody requirecmd SEMICOLON
  328. ;
  329. requirecmd:
  330. MODULE EQSIGN QUOTEDSTRING {
  331. struct stat st;
  332. struct perl_module *cur;
  333. if (stat ($3, &st) == -1) {
  334. yyerror ("yyparse: cannot stat file %s, %m", $3);
  335. YYERROR;
  336. }
  337. cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct perl_module));
  338. if (cur == NULL) {
  339. yyerror ("yyparse: g_malloc: %s", strerror(errno));
  340. YYERROR;
  341. }
  342. cur->path = $3;
  343. LIST_INSERT_HEAD (&cfg->perl_modules, cur, next);
  344. }
  345. ;
  346. composites:
  347. COMPOSITES OBRACE compositesbody EBRACE
  348. ;
  349. compositesbody:
  350. compositescmd SEMICOLON
  351. | compositesbody compositescmd SEMICOLON
  352. ;
  353. compositescmd:
  354. QUOTEDSTRING EQSIGN QUOTEDSTRING {
  355. struct expression *expr;
  356. if ((expr = parse_expression (cfg->cfg_pool, $3)) == NULL) {
  357. yyerror ("yyparse: cannot parse composite expression: %s", $3);
  358. YYERROR;
  359. }
  360. g_hash_table_insert (cfg->composite_symbols, $1, expr);
  361. }
  362. ;
  363. module_opt:
  364. MODULE_OPT OBRACE moduleoptbody EBRACE {
  365. g_hash_table_insert (cfg->modules_opts, $1, cur_module_opt);
  366. cur_module_opt = NULL;
  367. }
  368. ;
  369. moduleoptbody:
  370. optcmd SEMICOLON
  371. | moduleoptbody optcmd SEMICOLON
  372. ;
  373. optcmd:
  374. PARAM EQSIGN QUOTEDSTRING {
  375. struct module_opt *mopt;
  376. if (cur_module_opt == NULL) {
  377. cur_module_opt = g_malloc (sizeof (cur_module_opt));
  378. LIST_INIT (cur_module_opt);
  379. }
  380. mopt = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_opt));
  381. mopt->param = $1;
  382. mopt->value = $3;
  383. LIST_INSERT_HEAD (cur_module_opt, mopt, next);
  384. }
  385. ;
  386. variable:
  387. VARIABLE EQSIGN QUOTEDSTRING {
  388. g_hash_table_insert (cfg->variables, $1, $3);
  389. }
  390. ;
  391. logging:
  392. LOGGING OBRACE loggingbody EBRACE
  393. ;
  394. loggingbody:
  395. loggingcmd SEMICOLON
  396. | loggingbody loggingcmd SEMICOLON
  397. ;
  398. loggingcmd:
  399. loggingtype
  400. | logginglevel
  401. | loggingfacility
  402. | loggingfile
  403. ;
  404. loggingtype:
  405. LOG_TYPE EQSIGN LOG_TYPE_CONSOLE {
  406. cfg->log_type = RSPAMD_LOG_CONSOLE;
  407. }
  408. LOG_TYPE EQSIGN LOG_TYPE_SYSLOG {
  409. cfg->log_type = RSPAMD_LOG_SYSLOG;
  410. }
  411. LOG_TYPE EQSIGN LOG_TYPE_FILE {
  412. cfg->log_type = RSPAMD_LOG_FILE;
  413. }
  414. ;
  415. logginglevel:
  416. LOG_LEVEL EQSIGN LOG_LEVEL_DEBUG {
  417. cfg->log_level = G_LOG_LEVEL_DEBUG;
  418. }
  419. LOG_LEVEL EQSIGN LOG_LEVEL_INFO {
  420. cfg->log_level = G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE;
  421. }
  422. LOG_LEVEL EQSIGN LOG_LEVEL_WARNING {
  423. cfg->log_level = G_LOG_LEVEL_WARNING;
  424. }
  425. LOG_LEVEL EQSIGN LOG_LEVEL_ERROR {
  426. cfg->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
  427. }
  428. ;
  429. loggingfacility:
  430. LOG_FACILITY EQSIGN QUOTEDSTRING {
  431. if (strncasecmp ($3, "LOG_AUTH", sizeof ("LOG_AUTH") - 1) == 0) {
  432. cfg->log_facility = LOG_AUTH;
  433. }
  434. else if (strncasecmp ($3, "LOG_CRON", sizeof ("LOG_CRON") - 1) == 0) {
  435. cfg->log_facility = LOG_CRON;
  436. }
  437. else if (strncasecmp ($3, "LOG_DAEMON", sizeof ("LOG_DAEMON") - 1) == 0) {
  438. cfg->log_facility = LOG_DAEMON;
  439. }
  440. else if (strncasecmp ($3, "LOG_MAIL", sizeof ("LOG_MAIL") - 1) == 0) {
  441. cfg->log_facility = LOG_MAIL;
  442. }
  443. else if (strncasecmp ($3, "LOG_USER", sizeof ("LOG_USER") - 1) == 0) {
  444. cfg->log_facility = LOG_USER;
  445. }
  446. else if (strncasecmp ($3, "LOG_LOCAL0", sizeof ("LOG_LOCAL0") - 1) == 0) {
  447. cfg->log_facility = LOG_LOCAL0;
  448. }
  449. else if (strncasecmp ($3, "LOG_LOCAL1", sizeof ("LOG_LOCAL1") - 1) == 0) {
  450. cfg->log_facility = LOG_LOCAL1;
  451. }
  452. else if (strncasecmp ($3, "LOG_LOCAL2", sizeof ("LOG_LOCAL2") - 1) == 0) {
  453. cfg->log_facility = LOG_LOCAL2;
  454. }
  455. else if (strncasecmp ($3, "LOG_LOCAL3", sizeof ("LOG_LOCAL3") - 1) == 0) {
  456. cfg->log_facility = LOG_LOCAL3;
  457. }
  458. else if (strncasecmp ($3, "LOG_LOCAL4", sizeof ("LOG_LOCAL4") - 1) == 0) {
  459. cfg->log_facility = LOG_LOCAL4;
  460. }
  461. else if (strncasecmp ($3, "LOG_LOCAL5", sizeof ("LOG_LOCAL5") - 1) == 0) {
  462. cfg->log_facility = LOG_LOCAL5;
  463. }
  464. else if (strncasecmp ($3, "LOG_LOCAL6", sizeof ("LOG_LOCAL6") - 1) == 0) {
  465. cfg->log_facility = LOG_LOCAL6;
  466. }
  467. else if (strncasecmp ($3, "LOG_LOCAL7", sizeof ("LOG_LOCAL7") - 1) == 0) {
  468. cfg->log_facility = LOG_LOCAL7;
  469. }
  470. else {
  471. yyerror ("yyparse: invalid logging facility: %s", $3);
  472. YYERROR;
  473. }
  474. free ($3);
  475. }
  476. ;
  477. loggingfile:
  478. LOG_FILENAME EQSIGN QUOTEDSTRING {
  479. cfg->log_file = memory_pool_strdup (cfg->cfg_pool, $3);
  480. free ($3);
  481. }
  482. ;
  483. %%
  484. /*
  485. * vi:ts=4
  486. */