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 13KB

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