PageRenderTime 68ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/rc-gram.y

#
Happy | 1863 lines | 1645 code | 218 blank | 0 comment | 0 complexity | d8e5cfb4a8517c0679356379d293ee38 MD5 | raw file
Possible License(s): GPL-3.0
  1. %{
  2. /*
  3. rc-gram.y
  4. This file is part of GNU Anubis.
  5. Copyright (C) 2003-2014 The Anubis Team.
  6. GNU Anubis is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by the
  8. Free Software Foundation; either version 3 of the License, or (at your
  9. option) any later version.
  10. GNU Anubis is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License along
  15. with GNU Anubis. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <setjmp.h>
  23. #include "headers.h"
  24. #include "extern.h"
  25. #include "rcfile.h"
  26. extern int yylex (void);
  27. int yyerror (const char *s);
  28. static RC_SECTION *rc_section_create (char *, RC_LOC *, RC_STMT *);
  29. static void rc_section_destroy (RC_SECTION **);
  30. static void rc_section_print (RC_SECTION *);
  31. static void rc_asgn_destroy (RC_ASGN *);
  32. static void rc_bool_destroy (RC_BOOL *);
  33. static void rc_level_print (int, char *);
  34. static RC_NODE *rc_node_create (enum rc_node_type, struct rc_loc *loc);
  35. static void rc_node_destroy (RC_NODE *);
  36. static void rc_node_print (RC_NODE *);
  37. static void rc_rule_destroy (RC_RULE *);
  38. static void rc_cond_destroy (RC_COND *);
  39. static RC_STMT *rc_stmt_create (enum rc_stmt_type, struct rc_loc *loc);
  40. static void rc_stmt_destroy (RC_STMT *);
  41. static void rc_stmt_list_destroy (RC_STMT *);
  42. static void rc_stmt_print (RC_STMT *, int);
  43. static int reg_modifier_add (int *, char *, struct rc_loc *);
  44. static int check_kw (char *ident, int *flags);
  45. static int is_prog_allowed (struct rc_loc *);
  46. static RC_SECTION *rc_section;
  47. static int debug_level;
  48. static int error_count;
  49. static int def_regex_modifier = R_POSIX;
  50. static struct rc_secdef *rc_secdef;
  51. #define YYLLOC_DEFAULT(Current, Rhs, N) \
  52. do \
  53. { \
  54. if (N) \
  55. { \
  56. (Current).beg = YYRHSLOC(Rhs, 1).beg; \
  57. (Current).end = YYRHSLOC(Rhs, N).end; \
  58. } \
  59. else \
  60. { \
  61. (Current).beg = YYRHSLOC(Rhs, 0).end; \
  62. (Current).end = (Current).beg; \
  63. } \
  64. } \
  65. while (0)
  66. #define YY_LOCATION_PRINT(File, Loc) \
  67. do \
  68. { \
  69. if (RC_LOCUS_FILE_EQ(&(Loc).beg, &(Loc).end)) \
  70. fprintf(File, "%s:%lu.%lu-%lu.%lu", \
  71. (Loc).beg.file, \
  72. (unsigned long) (Loc).beg.line, \
  73. (unsigned long) (Loc).beg.column, \
  74. (unsigned long) (Loc).end.line, \
  75. (unsigned long) (Loc).end.column); \
  76. else \
  77. fprintf(File, "%s:%lu.%lu-%s:%lu.%lu", \
  78. (Loc).beg.file, \
  79. (unsigned long) (Loc).beg.line, \
  80. (unsigned long) (Loc).beg.column, \
  81. (Loc).end.file, \
  82. (unsigned long) (Loc).end.line, \
  83. (unsigned long) (Loc).end.column); \
  84. } \
  85. while (0)
  86. %}
  87. %error-verbose
  88. %locations
  89. %expect 2
  90. %union {
  91. char *string;
  92. RC_SECTION *section;
  93. RC_STMT *stmt;
  94. struct
  95. {
  96. RC_STMT *head;
  97. RC_STMT *tail;
  98. } stmtlist;
  99. RC_COND cond;
  100. RC_RULE rule;
  101. RC_NODE *node;
  102. RC_REGEX *regex;
  103. int num;
  104. struct
  105. {
  106. int part;
  107. RC_REGEX *key;
  108. char *string;
  109. char *sep;
  110. } msgpart;
  111. RC_LOC loc;
  112. char *begin_sec;
  113. ANUBIS_LIST list;
  114. int eq;
  115. };
  116. %token EOL T_BEGIN T_END AND OR NE
  117. %token IF FI ELSE ELIF RULE DONE
  118. %token CALL STOP ADD REMOVE MODIFY
  119. %token <string> IDENT STRING REGEX D_BEGIN
  120. %token <num> T_MSGPART
  121. %left OR
  122. %left AND
  123. %left NOT
  124. %type <string> keyword string modifier arg string_key opt_sep
  125. %type <section> section seclist
  126. %type <stmtlist> stmtlist
  127. %type <stmt> stmt asgn_stmt cond_stmt else_cond rule_stmt inst_stmt modf_stmt
  128. %type <num> modlist opt_modlist
  129. %type <node> rule_start cond expr
  130. %type <msgpart> msgpart s_msgpart r_msgpart key opt_key
  131. %type <list> arglist
  132. %type <regex> regex
  133. %type <begin_sec> begin
  134. %type <eq> meq
  135. %%
  136. input : seclist
  137. {
  138. }
  139. ;
  140. seclist : section
  141. {
  142. $$ = rc_section = $1;
  143. }
  144. | seclist section
  145. {
  146. if ($2)
  147. {
  148. if (rc_section == NULL)
  149. {
  150. $$ = rc_section = $2;
  151. }
  152. else
  153. {
  154. $1->next = $2;
  155. $$ = $2;
  156. }
  157. }
  158. }
  159. | seclist error
  160. {
  161. lex_clear_state ();
  162. yychar = error_sync_begin ();
  163. if (yychar > 0)
  164. {
  165. yyerrok;
  166. yyclearin;
  167. }
  168. }
  169. ;
  170. section : /* empty */ EOL
  171. {
  172. $$ = NULL;
  173. }
  174. | begin stmtlist end
  175. {
  176. $$ = rc_section_create ($1, &@1.beg, $2.head);
  177. }
  178. | begin end
  179. {
  180. $$ = NULL;
  181. }
  182. ;
  183. begin : T_BEGIN { verbatim (); } string EOL
  184. {
  185. $$ = $3;
  186. if (rc_section_lookup (rc_section, $3))
  187. parse_error (&@3.beg, _("Section %s already defined"), $3);
  188. rc_secdef = anubis_find_section ($3);
  189. }
  190. | D_BEGIN EOL
  191. {
  192. $$ = $1;
  193. if (rc_section_lookup (rc_section, $1))
  194. parse_error (&@1.beg, _("Section %s already defined"), $1);
  195. rc_secdef = anubis_find_section ($1);
  196. }
  197. ;
  198. end : T_END EOL
  199. ;
  200. stmtlist : stmt
  201. {
  202. $$.head = $$.tail = $1;
  203. }
  204. | stmtlist stmt
  205. {
  206. if ($2)
  207. {
  208. if ($$.head == NULL)
  209. {
  210. $$.head = $$.tail = $2;
  211. }
  212. else
  213. {
  214. $$.tail->next = $2;
  215. $$.tail = $2;
  216. }
  217. }
  218. }
  219. ;
  220. stmt : /* empty */ EOL
  221. {
  222. $$ = NULL;
  223. }
  224. | asgn_stmt EOL
  225. | cond_stmt EOL
  226. | rule_stmt EOL
  227. | inst_stmt EOL
  228. | modf_stmt EOL
  229. | error EOL
  230. {
  231. lex_clear_state ();
  232. yyerrok;
  233. yyclearin;
  234. $$ = NULL;
  235. }
  236. ;
  237. asgn_stmt: keyword arglist
  238. {
  239. int flags;
  240. if (!check_kw ($1, &flags))
  241. {
  242. parse_error (&@1.beg, _("unknown keyword: %s"), $1);
  243. YYERROR;
  244. }
  245. $$ = rc_stmt_create (rc_stmt_asgn, &@1.beg);
  246. $$->v.asgn.lhs = $1;
  247. if (list_count ($2))
  248. {
  249. char *s = list_item ($2, 0);
  250. if (s && !strcmp (s, "="))
  251. list_remove ($2, s, NULL);
  252. }
  253. $$->v.asgn.rhs = $2;
  254. $$->v.asgn.flags = flags;
  255. }
  256. ;
  257. keyword : IDENT
  258. {
  259. verbatim ();
  260. }
  261. ;
  262. arglist : arg
  263. {
  264. $$ = list_create ();
  265. list_append ($$, $1);
  266. }
  267. | arglist arg
  268. {
  269. list_append ($1, $2);
  270. $$ = $1;
  271. }
  272. ;
  273. arg : string
  274. ;
  275. cond_stmt: if cond stmtlist else_cond FI
  276. {
  277. $$ = rc_stmt_create (rc_stmt_cond, &@1.beg);
  278. $$->v.cond.node = $2;
  279. $$->v.cond.iftrue = $3.head;
  280. $$->v.cond.iffalse = $4;
  281. }
  282. ;
  283. else_cond: /* empty */
  284. {
  285. $$ = NULL;
  286. }
  287. | ELIF cond stmtlist else_cond
  288. {
  289. $$ = rc_stmt_create (rc_stmt_cond, &@1.beg);
  290. $$->v.cond.node = $2;
  291. $$->v.cond.iftrue = $3.head;
  292. $$->v.cond.iffalse = $4;
  293. }
  294. | ELSE stmtlist
  295. {
  296. $$ = $2.head;
  297. }
  298. ;
  299. cond : expr
  300. | '(' cond ')'
  301. {
  302. $$ = $2;
  303. }
  304. | cond AND cond
  305. {
  306. $$ = rc_node_create (rc_node_bool, &@2.beg);
  307. $$->v.bool.op = bool_and;
  308. $$->v.bool.left = $1;
  309. $$->v.bool.right = $3;
  310. }
  311. | cond OR cond
  312. {
  313. $$ = rc_node_create (rc_node_bool, &@2.beg);
  314. $$->v.bool.op = bool_or;
  315. $$->v.bool.left = $1;
  316. $$->v.bool.right = $3;
  317. }
  318. | NOT cond
  319. {
  320. $$ = rc_node_create (rc_node_bool, &@1.beg);
  321. $$->v.bool.op = bool_not;
  322. $$->v.bool.left = $2;
  323. $$->v.bool.right = NULL;
  324. }
  325. ;
  326. meq : /* empty */
  327. {
  328. $$ = 1;
  329. }
  330. | '='
  331. {
  332. $$ = 1;
  333. }
  334. | NE
  335. {
  336. $$ = 0;
  337. }
  338. ;
  339. key : regex
  340. {
  341. $$.part = HEADER;
  342. $$.key = $1;
  343. $$.string = NULL;
  344. }
  345. | '[' string ']'
  346. {
  347. $$.part = HEADER;
  348. $$.key = NULL;
  349. $$.string = $2;
  350. }
  351. ;
  352. opt_key : /* empty */
  353. {
  354. $$.string = NULL;
  355. $$.key = NULL;
  356. }
  357. | key
  358. ;
  359. msgpart : T_MSGPART opt_key
  360. {
  361. $$ = $2;
  362. $$.sep = NULL;
  363. $$.part = $1;
  364. }
  365. | key
  366. ;
  367. opt_sep : /* empty */
  368. {
  369. $$ = NULL;
  370. }
  371. | '(' string ')'
  372. {
  373. $$ = $2;
  374. }
  375. ;
  376. s_msgpart: msgpart
  377. {
  378. $$ = $1;
  379. if ($$.key)
  380. parse_error (&@1.beg,
  381. _("regexp is not allowed in this context"));
  382. }
  383. ;
  384. r_msgpart: msgpart
  385. {
  386. $$ = $1;
  387. if (!$$.key)
  388. {
  389. $$.key = anubis_regex_compile ($$.string, R_EXACT);
  390. xfree ($$.string);
  391. }
  392. }
  393. ;
  394. regex : modlist '[' string ']'
  395. {
  396. $$ = anubis_regex_compile ($3, $1);
  397. free ($3);
  398. if (!$$)
  399. {
  400. parse_error (&@3.beg,
  401. _("Invalid regular expression (see the above message)"));
  402. YYERROR;
  403. }
  404. }
  405. ;
  406. string_key: /* empty */
  407. {
  408. $$ = NULL;
  409. }
  410. | '[' string ']'
  411. {
  412. $$ = $2;
  413. }
  414. ;
  415. expr : s_msgpart opt_sep meq opt_modlist string
  416. {
  417. RC_NODE *node = rc_node_create (rc_node_expr, &@1.beg);
  418. node->v.expr.part = $1.part;
  419. node->v.expr.key = $1.string;
  420. node->v.expr.sep = $2;
  421. node->v.expr.re = anubis_regex_compile ($5, $4);
  422. free ($5);
  423. if ($3)
  424. $$ = node;
  425. else
  426. {
  427. $$ = rc_node_create (rc_node_bool, &@1.beg);
  428. $$->v.bool.op = bool_not;
  429. $$->v.bool.left = node;
  430. $$->v.bool.right = NULL;
  431. }
  432. }
  433. ;
  434. modlist : modifier
  435. {
  436. $$ = def_regex_modifier;
  437. reg_modifier_add (&$$, $1, &@1.beg);
  438. xfree ($1);
  439. }
  440. | modlist modifier
  441. {
  442. reg_modifier_add (&$1, $2, &@1.beg);
  443. xfree ($2);
  444. $$ = $1;
  445. }
  446. ;
  447. opt_modlist: /* empty */
  448. {
  449. $$ = def_regex_modifier;
  450. }
  451. | modlist
  452. ;
  453. modifier : ':' IDENT
  454. {
  455. $$ = $2;
  456. }
  457. ;
  458. if : IF
  459. {
  460. if (!is_prog_allowed (&@1.beg))
  461. YYERROR;
  462. }
  463. ;
  464. rule_stmt: rule_start EOL stmtlist DONE
  465. {
  466. $$ = rc_stmt_create (rc_stmt_rule, &@1.beg);
  467. $$->v.rule.node = $1;
  468. $$->v.rule.stmt = $3.head;
  469. }
  470. ;
  471. rule_start: rule opt_modlist string
  472. {
  473. $$ = rc_node_create (rc_node_expr, &@1.beg);
  474. $$->v.expr.part = HEADER;
  475. $$->v.expr.key = strdup (X_ANUBIS_RULE_HEADER);
  476. $$->v.expr.re = anubis_regex_compile ($3, $2);
  477. free ($3);
  478. }
  479. ;
  480. rule : RULE
  481. {
  482. if (!is_prog_allowed (&@1.beg))
  483. YYERROR;
  484. }
  485. ;
  486. string : STRING
  487. | IDENT
  488. ;
  489. inst_stmt: STOP
  490. {
  491. if (!is_prog_allowed (&@1.beg))
  492. YYERROR;
  493. $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
  494. $$->v.inst.opcode = inst_stop;
  495. $$->v.inst.part = NIL;
  496. $$->v.inst.key = NULL;
  497. $$->v.inst.key2 = NULL;
  498. $$->v.inst.arg = NULL;
  499. }
  500. | CALL string
  501. {
  502. if (!is_prog_allowed (&@1.beg))
  503. YYERROR;
  504. $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
  505. $$->v.inst.opcode = inst_call;
  506. $$->v.inst.key = NULL;
  507. $$->v.inst.part = NIL;
  508. $$->v.inst.key2 = NULL;
  509. $$->v.inst.arg = $2;
  510. }
  511. | ADD s_msgpart string
  512. {
  513. if (!is_prog_allowed (&@1.beg))
  514. YYERROR;
  515. if ($2.part == COMMAND)
  516. {
  517. parse_error (&@2.beg, _("command part is not allowed"));
  518. YYERROR;
  519. }
  520. $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
  521. $$->v.inst.opcode = inst_add;
  522. $$->v.inst.part = $2.part;
  523. $$->v.inst.key = NULL;
  524. $$->v.inst.key2 = $2.string;
  525. $$->v.inst.arg = $3;
  526. }
  527. | REMOVE r_msgpart
  528. {
  529. if (!is_prog_allowed (&@1.beg))
  530. YYERROR;
  531. if ($2.part == COMMAND)
  532. {
  533. parse_error (&@2.beg, _("command part is not allowed"));
  534. YYERROR;
  535. }
  536. $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
  537. $$->v.inst.opcode = inst_remove;
  538. $$->v.inst.part = $2.part;
  539. $$->v.inst.key = $2.key;
  540. $$->v.inst.key2 = NULL;
  541. $$->v.inst.arg = NULL;
  542. }
  543. | MODIFY r_msgpart string_key string
  544. {
  545. if (!is_prog_allowed (&@1.beg))
  546. YYERROR;
  547. $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
  548. $$->v.inst.opcode = inst_modify;
  549. $$->v.inst.part = $2.part;
  550. $$->v.inst.key = $2.key;
  551. $$->v.inst.key2 = $3;
  552. $$->v.inst.arg = $4;
  553. }
  554. | MODIFY r_msgpart string_key
  555. {
  556. if (!is_prog_allowed (&@1.beg))
  557. YYERROR;
  558. $$ = rc_stmt_create (rc_stmt_inst, &@1.beg);
  559. $$->v.inst.opcode = inst_modify;
  560. $$->v.inst.part = $2.part;
  561. $$->v.inst.key = $2.key;
  562. if ($3 == NULL && anubis_regex_refcnt ($2.key))
  563. parse_error (&@2.end, _("missing replacement value"));
  564. $$->v.inst.key2 = $3;
  565. $$->v.inst.arg = NULL;
  566. }
  567. ;
  568. modf_stmt: REGEX modlist
  569. {
  570. if (!is_prog_allowed (&@1.beg))
  571. YYERROR;
  572. def_regex_modifier = $2;
  573. $$ = NULL;
  574. }
  575. ;
  576. %%
  577. static void
  578. default_error_printer (void *data,
  579. struct rc_loc *loc,
  580. const char *pfx,
  581. const char *fmt, va_list ap)
  582. {
  583. char buf[LINEBUFFER];
  584. vsnprintf (buf, sizeof buf, fmt, ap);
  585. if (topt & T_LOCATION_COLUMN)
  586. anubis_error (0, 0, "%s:%lu.%lu: %s%s%s",
  587. loc->file,
  588. (unsigned long)loc->line,
  589. (unsigned long)loc->column,
  590. pfx ? pfx : "",
  591. pfx ? ": " : "",
  592. buf);
  593. else
  594. anubis_error (0, 0, "%s:%lu: %s%s%s",
  595. loc->file, (unsigned long)loc->line,
  596. pfx ? pfx : "",
  597. pfx ? ": " : "",
  598. buf);
  599. }
  600. static void *rc_error_printer_data;
  601. static RC_ERROR_PRINTER rc_error_printer = default_error_printer;
  602. void
  603. parse_error (struct rc_loc *loc, const char *fmt, ...)
  604. {
  605. va_list ap;
  606. va_start (ap, fmt);
  607. rc_error_printer (rc_error_printer_data, loc ? loc : &rc_locus, NULL,
  608. fmt, ap);
  609. va_end (ap);
  610. error_count++;
  611. }
  612. int
  613. yyerror (const char *s)
  614. {
  615. parse_error (NULL, "%s", s);
  616. return 0;
  617. }
  618. RC_SECTION *
  619. rc_parse (char *name)
  620. {
  621. int status;
  622. yydebug = yy_flex_debug = 0;
  623. if (debug_level > 1)
  624. {
  625. yydebug = 1;
  626. if (debug_level > 2)
  627. yy_flex_debug = 1;
  628. }
  629. if (rc_open (name))
  630. return NULL;
  631. rc_section = NULL;
  632. error_count = 0;
  633. status = yyparse ();
  634. if (status || error_count)
  635. rc_section_list_destroy (&rc_section);
  636. if (debug_level)
  637. rc_section_print (rc_section);
  638. return rc_section;
  639. }
  640. /* Same as rc_parse() but also allows user to specify his own
  641. error printer function */
  642. RC_SECTION *
  643. rc_parse_ep (char *name, RC_ERROR_PRINTER errprn, void *data)
  644. {
  645. void *save_ep_data = rc_error_printer_data;
  646. void *save_ep_handler = rc_error_printer;
  647. RC_SECTION *sec;
  648. rc_error_printer = errprn;
  649. rc_error_printer_data = data;
  650. sec = rc_parse (name);
  651. rc_error_printer = save_ep_handler;
  652. rc_error_printer_data = save_ep_data;
  653. return sec;
  654. }
  655. void
  656. rc_set_debug_level (char *arg)
  657. {
  658. if (!arg)
  659. debug_level = 0;
  660. else if (arg[1] != 0 || !isdigit (arg[0]))
  661. {
  662. mprintf (_("Not a valid debugging level: %s"), arg);
  663. return;
  664. }
  665. else
  666. debug_level = arg[0] - '0';
  667. }
  668. /* Locations */
  669. /* To save space, each filename is allocated only once. Each filename
  670. has a reference count associated with it. It is incremented
  671. with each new allocation of the same string. It is decremented
  672. with each attempt to free the string. Only when the reference count
  673. drops to zero is the storage actually reclaimed */
  674. struct strobj {
  675. char *value; /* String value */
  676. size_t refcnt; /* Reference count */
  677. };
  678. /* A list of string objects */
  679. static ANUBIS_LIST /* of struct strobj */ string_list;
  680. static int
  681. string_comparator (void *item, void *data)
  682. {
  683. struct strobj *s = item;
  684. return strcmp (s->value, (char*) data);
  685. }
  686. static int
  687. value_comparator (void *item, void *data)
  688. {
  689. struct strobj *s = item;
  690. return s->value != data;
  691. }
  692. /* Looks up a string object with the given value. If not found, a
  693. new object is created and added to the list. In any case the
  694. reference count of the objet is incremented.
  695. The return value is the string value associated with the object. */
  696. char *
  697. string_create (char *str)
  698. {
  699. struct strobj *s = list_locate (string_list, str, string_comparator);
  700. if (!s)
  701. {
  702. s = xmalloc (sizeof (*s));
  703. s->value = strdup (str);
  704. s->refcnt = 0;
  705. list_prepend (string_list, s);
  706. }
  707. s->refcnt++;
  708. return s->value;
  709. }
  710. /* Destroys the object with the given string value */
  711. void
  712. string_destroy (char *str)
  713. {
  714. struct strobj *s = list_locate (string_list, str, value_comparator);
  715. if (s)
  716. {
  717. if (--s->refcnt == 0)
  718. {
  719. free (s->value);
  720. list_remove (string_list, str, value_comparator);
  721. }
  722. }
  723. }
  724. /* Initializes LOC with the current location. If the second argument
  725. is not zero, it overrides the current line number. */
  726. void
  727. rc_mark_loc (RC_LOC *dst, RC_LOC *src)
  728. {
  729. dst->file = string_create (src->file);
  730. dst->line = src->line;
  731. dst->column = src->column;
  732. }
  733. /* Reclaims the memory associated with the LOC */
  734. void
  735. rc_destroy_loc (RC_LOC *loc)
  736. {
  737. string_destroy (loc->file);
  738. }
  739. /* Section manipulation */
  740. RC_SECTION *
  741. rc_section_create (char *name, struct rc_loc *loc, RC_STMT *stmt)
  742. {
  743. RC_SECTION *p = xmalloc (sizeof (*p));
  744. rc_mark_loc (&p->loc, loc);
  745. p->next = NULL;
  746. p->name = name;
  747. p->stmt = stmt;
  748. return p;
  749. }
  750. void
  751. rc_section_destroy (RC_SECTION **s)
  752. {
  753. rc_stmt_list_destroy ((*s)->stmt);
  754. rc_destroy_loc (&(*s)->loc);
  755. xfree ((*s)->name);
  756. xfree (*s);
  757. }
  758. void
  759. rc_section_list_destroy (RC_SECTION **s)
  760. {
  761. while (*s)
  762. {
  763. RC_SECTION *next = (*s)->next;
  764. rc_section_destroy (s);
  765. *s = next;
  766. }
  767. }
  768. void
  769. rc_section_print (RC_SECTION *sect)
  770. {
  771. for (; sect; sect = sect->next)
  772. {
  773. printf ("BEGIN SECTION %s\n", sect->name);
  774. rc_stmt_print (sect->stmt, 1);
  775. printf ("END SECTION %s\n", sect->name);
  776. }
  777. }
  778. RC_SECTION *
  779. rc_section_lookup (RC_SECTION *sec, char *name)
  780. {
  781. for (; sec; sec = sec->next)
  782. if (strcmp (sec->name, name) == 0)
  783. break;
  784. return sec;
  785. }
  786. void
  787. rc_section_link (RC_SECTION **ap, RC_SECTION *b)
  788. {
  789. RC_SECTION *a, *prev;
  790. /* Remove all sections with prio == override (the default) */
  791. a = *ap;
  792. prev = NULL;
  793. while (a)
  794. {
  795. RC_SECTION *next = a->next;
  796. struct rc_secdef *sd = anubis_find_section (a->name);
  797. if (sd && sd->prio == prio_user_only)
  798. {
  799. if (prev)
  800. prev->next = next;
  801. else
  802. *ap = next;
  803. rc_section_destroy (&a);
  804. } else
  805. prev = a;
  806. a = next;
  807. }
  808. if (!*ap)
  809. {
  810. *ap = b;
  811. return;
  812. }
  813. for (a = *ap; a->next; a = a->next)
  814. ;
  815. while (b)
  816. {
  817. struct rc_secdef *sd;
  818. RC_SECTION *nxtptr = b->next;
  819. sd = anubis_find_section (b->name);
  820. if (sd)
  821. {
  822. switch (sd->prio)
  823. {
  824. case prio_user:
  825. b->next = *ap;
  826. *ap = b;
  827. break;
  828. case prio_system_only:
  829. rc_section_destroy (&b);
  830. break;
  831. default:
  832. b->next = NULL;
  833. a->next = b;
  834. a = b;
  835. }
  836. }
  837. else
  838. {
  839. b->next = NULL;
  840. a->next = b;
  841. a = b;
  842. }
  843. b = nxtptr;
  844. }
  845. }
  846. /* Assignment manipulations */
  847. void
  848. rc_asgn_destroy (RC_ASGN *asgn)
  849. {
  850. xfree (asgn->lhs);
  851. list_destroy (&asgn->rhs, anubis_free_list_item, NULL);
  852. }
  853. /* Bools */
  854. void
  855. rc_bool_destroy (RC_BOOL *bool)
  856. {
  857. rc_node_destroy (bool->left);
  858. rc_node_destroy (bool->right);
  859. }
  860. /* Nodes */
  861. /* FIXME: 2nd should better be struct rc_yyltype */
  862. RC_NODE *
  863. rc_node_create (enum rc_node_type t, struct rc_loc *loc)
  864. {
  865. RC_NODE *p = xmalloc (sizeof (*p));
  866. memset (p, 0, sizeof (*p));
  867. rc_mark_loc (&p->loc, loc);
  868. p->type = t;
  869. return p;
  870. }
  871. void
  872. rc_node_destroy (RC_NODE *node)
  873. {
  874. if (!node)
  875. return;
  876. switch (node->type)
  877. {
  878. case rc_node_bool:
  879. rc_bool_destroy (&node->v.bool);
  880. break;
  881. case rc_node_expr:
  882. free (node->v.expr.key);
  883. anubis_regex_free (&node->v.expr.re);
  884. }
  885. rc_destroy_loc (&node->loc);
  886. xfree (node);
  887. }
  888. static char *
  889. part_string (int part)
  890. {
  891. switch (part)
  892. {
  893. case NIL:
  894. return "NIL";
  895. case COMMAND:
  896. return "COMMAND";
  897. case HEADER:
  898. return "HEADER";
  899. case BODY:
  900. return "BODY";
  901. default:
  902. return "UNKNOWN";
  903. }
  904. }
  905. void
  906. rc_node_print (RC_NODE *node)
  907. {
  908. switch (node->type)
  909. {
  910. case rc_node_expr:
  911. printf ("%s", part_string (node->v.expr.part));
  912. if (node->v.expr.key && node->v.expr.key[0] != '\n')
  913. printf ("[%s]",node->v.expr.key);
  914. if (node->v.expr.sep)
  915. printf ("(%s)", node->v.expr.sep);
  916. printf (" ");
  917. anubis_regex_print (node->v.expr.re);
  918. break;
  919. case rc_node_bool:
  920. switch (node->v.bool.op)
  921. {
  922. case bool_not:
  923. printf ("NOT (");
  924. rc_node_print (node->v.bool.left);
  925. printf (")");
  926. break;
  927. case bool_and:
  928. printf ("AND (");
  929. rc_node_print (node->v.bool.left);
  930. printf (",");
  931. rc_node_print (node->v.bool.right);
  932. printf (")");
  933. break;
  934. case bool_or:
  935. printf ("OR (");
  936. rc_node_print (node->v.bool.left);
  937. printf (",");
  938. rc_node_print (node->v.bool.right);
  939. printf (")");
  940. break;
  941. }
  942. }
  943. }
  944. /* Rules */
  945. void
  946. rc_rule_destroy (RC_RULE *rule)
  947. {
  948. rc_node_destroy (rule->node);
  949. rc_stmt_list_destroy (rule->stmt);
  950. }
  951. /* Conditionals */
  952. void
  953. rc_cond_destroy (RC_COND *cond)
  954. {
  955. rc_node_destroy (cond->node);
  956. rc_stmt_list_destroy (cond->iftrue);
  957. rc_stmt_list_destroy (cond->iffalse);
  958. }
  959. /* Instructions */
  960. void
  961. rc_inst_destroy (RC_INST *inst)
  962. {
  963. anubis_regex_free (&inst->key);
  964. free (inst->key2);
  965. free (inst->arg);
  966. }
  967. static char *
  968. inst_name (enum rc_inst_opcode opcode)
  969. {
  970. switch (opcode)
  971. {
  972. case inst_stop:
  973. return "STOP";
  974. case inst_call:
  975. return "CALL";
  976. case inst_add:
  977. return "ADD";
  978. case inst_remove:
  979. return "REMOVE";
  980. case inst_modify:
  981. return "MODIFY";
  982. }
  983. return "UNKNOWN";
  984. }
  985. void
  986. rc_inst_print (RC_INST *inst, int level)
  987. {
  988. rc_level_print (level, inst_name (inst->opcode));
  989. switch (inst->opcode)
  990. {
  991. case inst_stop:
  992. break;
  993. case inst_call:
  994. printf (" %s", inst->arg);
  995. break;
  996. case inst_add:
  997. printf (" %s[%s]", part_string (inst->part), inst->key2);
  998. if (inst->arg)
  999. printf (" \"%s\"", inst->arg);
  1000. break;
  1001. default:
  1002. printf (" %s ", part_string (inst->part));
  1003. if (inst->key)
  1004. anubis_regex_print (inst->key);
  1005. if (inst->key2)
  1006. printf (" [%s]", inst->key2);
  1007. if (inst->arg)
  1008. printf (" \"%s\"", inst->arg);
  1009. }
  1010. }
  1011. /* Statements */
  1012. /* FIXME: See rc_node_create */
  1013. RC_STMT *
  1014. rc_stmt_create (enum rc_stmt_type type, struct rc_loc *loc)
  1015. {
  1016. RC_STMT *p = xmalloc (sizeof (*p));
  1017. memset (p, 0, sizeof (*p));
  1018. rc_mark_loc (&p->loc, loc);
  1019. p->type = type;
  1020. return p;
  1021. }
  1022. void
  1023. rc_stmt_destroy (RC_STMT *stmt)
  1024. {
  1025. switch (stmt->type)
  1026. {
  1027. case rc_stmt_asgn:
  1028. rc_asgn_destroy (&stmt->v.asgn);
  1029. break;
  1030. case rc_stmt_rule:
  1031. rc_rule_destroy (&stmt->v.rule);
  1032. break;
  1033. case rc_stmt_cond:
  1034. rc_cond_destroy (&stmt->v.cond);
  1035. break;
  1036. case rc_stmt_inst:
  1037. rc_inst_destroy (&stmt->v.inst);
  1038. }
  1039. rc_destroy_loc (&stmt->loc);
  1040. xfree (stmt);
  1041. }
  1042. void
  1043. rc_stmt_list_destroy (RC_STMT *stmt)
  1044. {
  1045. while (stmt)
  1046. {
  1047. RC_STMT *next = stmt->next;
  1048. rc_stmt_destroy (stmt);
  1049. stmt = next;
  1050. }
  1051. }
  1052. void
  1053. rc_level_print (int level, char *str)
  1054. {
  1055. int i;
  1056. for (i = 0; i < level*2; i++)
  1057. putchar (' ');
  1058. printf ("%s", str);
  1059. }
  1060. static int
  1061. _print_str (void *item, void *data)
  1062. {
  1063. printf (" %s", (char*)item);
  1064. return 0;
  1065. }
  1066. static int
  1067. _print_stars (void *item, void *data)
  1068. {
  1069. printf (" ***");
  1070. return 0;
  1071. }
  1072. void
  1073. rc_stmt_print (RC_STMT *stmt, int level)
  1074. {
  1075. for (; stmt; stmt = stmt->next)
  1076. {
  1077. switch (stmt->type)
  1078. {
  1079. case rc_stmt_asgn:
  1080. rc_level_print (level, "ASGN: ");
  1081. printf ("%s =", stmt->v.asgn.lhs);
  1082. list_iterate (stmt->v.asgn.rhs,
  1083. (stmt->v.asgn.flags & KWF_HIDDEN) ?
  1084. _print_stars : _print_str, NULL);
  1085. break;
  1086. case rc_stmt_cond:
  1087. rc_level_print (level, "COND: ");
  1088. rc_node_print (stmt->v.cond.node);
  1089. printf ("\n");
  1090. rc_level_print (level, "IFTRUE:\n");
  1091. rc_stmt_print (stmt->v.cond.iftrue, level+1);
  1092. if (stmt->v.cond.iffalse)
  1093. {
  1094. rc_level_print (level, "IFFALSE:\n");
  1095. rc_stmt_print (stmt->v.cond.iffalse, level+1);
  1096. }
  1097. rc_level_print (level, "END COND");
  1098. break;
  1099. case rc_stmt_rule:
  1100. rc_level_print (level, "RULE: ");
  1101. rc_node_print (stmt->v.rule.node);
  1102. printf ("\n");
  1103. rc_level_print (level, "BODY\n");
  1104. rc_stmt_print (stmt->v.rule.stmt, level+1);
  1105. rc_level_print (level, "END RULE");
  1106. break;
  1107. case rc_stmt_inst:
  1108. rc_inst_print (&stmt->v.inst, level);
  1109. break;
  1110. default:
  1111. abort ();
  1112. }
  1113. printf ("\n");
  1114. }
  1115. }
  1116. int
  1117. reg_modifier_add (int *flag, char *opt, struct rc_loc *loc)
  1118. {
  1119. /* Regex types: */
  1120. if (!strcasecmp (opt, "re") || !strcasecmp (opt, "regex"))
  1121. {
  1122. re_set_type (*flag, re_typeof (def_regex_modifier));
  1123. }
  1124. else if (!strcasecmp (opt, "posix"))
  1125. {
  1126. re_set_type (*flag, R_POSIX);
  1127. }
  1128. #ifdef HAVE_PCRE
  1129. else if (!strcasecmp (opt, "perlre")
  1130. || !strcasecmp (opt, "perl"))
  1131. {
  1132. re_set_type (*flag, R_PERLRE);
  1133. }
  1134. #endif /* HAVE_PCRE */
  1135. else if (!strcasecmp (opt, "ex") || !strcasecmp (opt, "exact"))
  1136. {
  1137. re_set_type (*flag, R_EXACT);
  1138. }
  1139. /* Modifiers: */
  1140. else if (!strcasecmp (opt, "basic"))
  1141. {
  1142. re_set_type (*flag, R_POSIX);
  1143. re_set_flag (*flag, R_BASIC);
  1144. }
  1145. else if (!strcasecmp (opt, "extended"))
  1146. {
  1147. re_set_type (*flag, R_POSIX);
  1148. re_clear_flag (*flag, R_BASIC);
  1149. }
  1150. else if (!strcasecmp (opt, "scase"))
  1151. re_set_flag (*flag, R_SCASE);
  1152. else if (!strcasecmp (opt, "icase"))
  1153. re_clear_flag (*flag, R_SCASE);
  1154. else
  1155. {
  1156. parse_error (loc, _("Unknown regexp modifier"));
  1157. return 1;
  1158. }
  1159. return 0;
  1160. }
  1161. /* ******************************* Runtime ********************************* */
  1162. static struct rc_secdef_child *
  1163. child_copy (struct rc_secdef_child *p)
  1164. {
  1165. struct rc_secdef_child *newp = xmalloc (sizeof (*newp));
  1166. memcpy (newp, p, sizeof (*newp));
  1167. newp->next = NULL;
  1168. return newp;
  1169. }
  1170. void
  1171. rc_secdef_add_child (struct rc_secdef *def,
  1172. struct rc_secdef_child *child)
  1173. {
  1174. struct rc_secdef_child *p = child_copy (child);
  1175. if (!def->child)
  1176. def->child = p;
  1177. else
  1178. {
  1179. struct rc_secdef_child *last;
  1180. for (last = def->child; last->next; last = last->next)
  1181. ;
  1182. last->next = p;
  1183. }
  1184. }
  1185. struct rc_secdef_child *
  1186. rc_child_lookup (struct rc_secdef_child *child, char *str,
  1187. int method, int *key, int *flags)
  1188. {
  1189. for (; child; child = child->next)
  1190. {
  1191. if (child->method & method)
  1192. {
  1193. struct rc_kwdef *kw;
  1194. for (kw = child->kwdef; kw->name; kw++)
  1195. if (!strcmp (kw->name, str))
  1196. {
  1197. *key = kw->tok;
  1198. if (flags)
  1199. *flags = kw->flags;
  1200. return child;
  1201. }
  1202. }
  1203. }
  1204. return NULL;
  1205. }
  1206. struct disabled_keyword
  1207. {
  1208. int method_mask;
  1209. char *keyword;
  1210. };
  1211. static ANUBIS_LIST disabled_keyword_list;
  1212. void
  1213. rc_disable_keyword (int mask, const char *kw)
  1214. {
  1215. ITERATOR itr;
  1216. struct disabled_keyword *p;
  1217. if (!disabled_keyword_list)
  1218. disabled_keyword_list = list_create ();
  1219. itr = iterator_create (disabled_keyword_list);
  1220. for (p = iterator_first (itr); p; p = iterator_next (itr))
  1221. {
  1222. if (strcmp (p->keyword, kw) == 0)
  1223. {
  1224. p->method_mask |= mask;
  1225. break;
  1226. }
  1227. }
  1228. iterator_destroy (&itr);
  1229. if (!p)
  1230. {
  1231. p = xmalloc (sizeof (*p));
  1232. p->method_mask = mask;
  1233. p->keyword = xstrdup (kw);
  1234. list_append (disabled_keyword_list, p);
  1235. }
  1236. }
  1237. int
  1238. rc_keyword_is_disabled (int mask, const char *kw)
  1239. {
  1240. int rc = 0;
  1241. if (disabled_keyword_list)
  1242. {
  1243. ITERATOR itr = iterator_create (disabled_keyword_list);
  1244. struct disabled_keyword *p;
  1245. for (p = iterator_first (itr); p; p = iterator_next (itr))
  1246. {
  1247. if ((rc = (p->method_mask & mask) && strcmp (p->keyword, kw) == 0))
  1248. break;
  1249. }
  1250. iterator_destroy (&itr);
  1251. }
  1252. return rc;
  1253. }
  1254. struct eval_env
  1255. {
  1256. int method;
  1257. int cmp_method;
  1258. struct rc_secdef_child *child;
  1259. MESSAGE msg;
  1260. void *data;
  1261. int refcnt;
  1262. char **refstr;
  1263. jmp_buf jmp;
  1264. RC_LOC loc;
  1265. int traceable;
  1266. };
  1267. struct rc_loc const *
  1268. eval_env_locus (struct eval_env *env)
  1269. {
  1270. return &env->loc;
  1271. }
  1272. int
  1273. eval_env_method (struct eval_env *env)
  1274. {
  1275. return env->method;
  1276. }
  1277. MESSAGE
  1278. eval_env_message (struct eval_env *env)
  1279. {
  1280. return env->msg;
  1281. }
  1282. void *
  1283. eval_env_data (struct eval_env *env)
  1284. {
  1285. return env->data;
  1286. }
  1287. void
  1288. eval_error (int retcode, struct eval_env *env, const char *fmt, ...)
  1289. {
  1290. va_list ap;
  1291. va_start(ap, fmt);
  1292. rc_error_printer (rc_error_printer_data, &env->loc, NULL, fmt, ap);
  1293. va_end(ap);
  1294. if (retcode)
  1295. longjmp(env->jmp, retcode);
  1296. }
  1297. void
  1298. eval_warning (struct eval_env *env, const char *fmt, ...)
  1299. {
  1300. va_list ap;
  1301. va_start(ap, fmt);
  1302. rc_error_printer (rc_error_printer_data, &env->loc, _("warning"),
  1303. fmt, ap);
  1304. va_end(ap);
  1305. }
  1306. static void asgn_eval (struct eval_env *env, RC_ASGN *asgn);
  1307. static int node_eval (struct eval_env *env, RC_NODE *node);
  1308. static int bool_eval (struct eval_env *env, RC_BOOL *bool);
  1309. static void cond_eval (struct eval_env *env, RC_COND *cond);
  1310. static void rule_eval (struct eval_env *env, RC_RULE *rule);
  1311. static void stmt_list_eval (struct eval_env *env, RC_STMT *stmt);
  1312. static void inst_eval (struct eval_env *env, RC_INST *inst);
  1313. #define VALID_STR(s) ((s)?(s):"NULL")
  1314. void
  1315. inst_eval (struct eval_env *env, RC_INST *inst)
  1316. {
  1317. char *arg = NULL, *argp = NULL;
  1318. if (!env->msg)
  1319. return; /* FIXME: bail out? */
  1320. if (inst->arg)
  1321. {
  1322. if (env->refstr)
  1323. arg = argp = substitute (inst->arg, env->refstr);
  1324. else
  1325. arg = inst->arg;
  1326. }
  1327. switch (inst->opcode)
  1328. {
  1329. case inst_stop:
  1330. tracefile (&env->loc, _("STOP"));
  1331. longjmp (env->jmp, 1);
  1332. break;
  1333. case inst_call:
  1334. tracefile (&env->loc, _("Calling %s"), inst->arg);
  1335. rcfile_call_section (env->method, inst->arg, "RULE",
  1336. env->data, env->msg);
  1337. break;
  1338. case inst_add:
  1339. tracefile (&env->loc, _("ADD %s [%s] %s"),
  1340. part_string (inst->part),
  1341. VALID_STR (inst->key2), arg);
  1342. if (inst->part == BODY)
  1343. message_add_body (env->msg, inst->key2, arg);
  1344. else if (inst->part == HEADER)
  1345. message_add_header (env->msg, inst->key2, arg);
  1346. break;
  1347. case inst_modify:
  1348. tracefile (&env->loc, _("MODIFY %s [%s] [%s] %s"),
  1349. part_string (inst->part),
  1350. anubis_regex_source (inst->key),
  1351. VALID_STR (inst->key2), arg);
  1352. switch (inst->part)
  1353. {
  1354. case BODY:
  1355. message_modify_body (env->msg, inst->key, arg);
  1356. break;
  1357. case HEADER:
  1358. message_modify_headers (env->msg, inst->key, inst->key2, arg);
  1359. break;
  1360. case COMMAND:
  1361. message_modify_command (env->msg, inst->key, inst->key2, arg);
  1362. break;
  1363. }
  1364. break;
  1365. case inst_remove:
  1366. tracefile (&env->loc, _("REMOVE HEADER [%s]"),
  1367. anubis_regex_source (inst->key));
  1368. message_remove_headers (env->msg, inst->key);
  1369. break;
  1370. default:
  1371. abort ();
  1372. }
  1373. if (argp)
  1374. free (argp);
  1375. }
  1376. void
  1377. asgn_eval (struct eval_env *env, RC_ASGN *asgn)
  1378. {
  1379. int key;
  1380. struct rc_secdef_child *p = rc_child_lookup (env->child, asgn->lhs,
  1381. env->method, &key, NULL);
  1382. if (!p)
  1383. return;
  1384. if (rc_keyword_is_disabled (env->method, asgn->lhs))
  1385. {
  1386. eval_warning (env,
  1387. _("ignoring statement overridden from the command line"));
  1388. return;
  1389. }
  1390. if (env->traceable)
  1391. tracefile (&env->loc, _("Executing %s"), asgn->lhs);
  1392. if (env->refstr)
  1393. {
  1394. char *s;
  1395. ANUBIS_LIST arg = list_create ();
  1396. ITERATOR itr = iterator_create (asgn->rhs);
  1397. for (s = iterator_first (itr); s; s = iterator_next (itr))
  1398. {
  1399. char *str = substitute (s, env->refstr);
  1400. list_append (arg, str);
  1401. }
  1402. iterator_destroy (&itr);
  1403. p->parser (env, key, arg, p->data);
  1404. list_destroy (&arg, anubis_free_list_item, NULL);
  1405. }
  1406. else
  1407. p->parser (env, key, asgn->rhs, p->data);
  1408. }
  1409. int
  1410. re_eval_list (struct eval_env *env, char *key, char *sep,
  1411. RC_REGEX *re, ANUBIS_LIST list)
  1412. {
  1413. ASSOC *p;
  1414. ITERATOR itr;
  1415. int rc = 0;
  1416. itr = iterator_create (list);
  1417. if (sep)
  1418. {
  1419. char *tmpbuf = NULL;
  1420. size_t tmpsize = 0;
  1421. size_t seplen = strlen (sep);
  1422. char *first_val = NULL;
  1423. for (p = iterator_first (itr); p; p = iterator_next (itr))
  1424. {
  1425. if (!p->key || !strcasecmp (p->key, key))
  1426. {
  1427. if (tmpsize == 0)
  1428. {
  1429. if (!first_val)
  1430. {
  1431. first_val = p->value; /* Initialize copy on write */
  1432. continue;
  1433. }
  1434. else
  1435. {
  1436. tmpbuf = xstrdup (first_val);
  1437. tmpsize = strlen (tmpbuf);
  1438. first_val = NULL;
  1439. }
  1440. }
  1441. tmpsize += seplen + strlen (p->value);
  1442. tmpbuf = xrealloc (tmpbuf, tmpsize + 1);
  1443. strcat (tmpbuf, sep);
  1444. strcat (tmpbuf, p->value);
  1445. }
  1446. }
  1447. rc = anubis_regex_match (re, first_val ? first_val : tmpbuf,
  1448. &env->refcnt, &env->refstr);
  1449. free (tmpbuf);
  1450. }
  1451. else
  1452. {
  1453. for (p = iterator_first (itr); rc == 0 && p; p = iterator_next (itr))
  1454. {
  1455. if (!p->key || !strcasecmp (p->key, key))
  1456. rc = anubis_regex_match (re, p->value,
  1457. &env->refcnt, &env->refstr);
  1458. }
  1459. }
  1460. iterator_destroy (&itr);
  1461. return rc;
  1462. }
  1463. int
  1464. re_eval_text (struct eval_env *env, RC_REGEX *re, const char *text)
  1465. {
  1466. /* FIXME */
  1467. return anubis_regex_match (re, text, &env->refcnt, &env->refstr);
  1468. }
  1469. int
  1470. expr_eval (struct eval_env *env, RC_EXPR *expr)
  1471. {
  1472. int rc;
  1473. if (env->refstr && anubis_regex_refcnt (expr->re))
  1474. {
  1475. argcv_free (-1, env->refstr);
  1476. env->refcnt = 0;
  1477. env->refstr = NULL;
  1478. }
  1479. switch (expr->part)
  1480. {
  1481. case COMMAND:
  1482. rc = re_eval_list (env, expr->key, expr->sep, expr->re,
  1483. message_get_commands (env->msg));
  1484. break;
  1485. case HEADER:
  1486. rc = re_eval_list (env, expr->key, expr->sep, expr->re,
  1487. message_get_header (env->msg));
  1488. break;
  1489. case BODY:
  1490. rc = re_eval_text (env, expr->re, message_get_body (env->msg));
  1491. break;
  1492. default:
  1493. abort ();
  1494. }
  1495. if (rc)
  1496. {
  1497. if (!strcmp (VALID_STR (expr->key), X_ANUBIS_RULE_HEADER))
  1498. tracefile (&env->loc, _("Matched trigger \"%s\""),
  1499. anubis_regex_source (expr->re));
  1500. else
  1501. tracefile (&env->loc,
  1502. _("Matched condition %s[%s] \"%s\""),
  1503. part_string (expr->part),
  1504. VALID_STR (expr->key),
  1505. anubis_regex_source (expr->re));
  1506. }
  1507. return rc;
  1508. }
  1509. int
  1510. node_eval (struct eval_env *env, RC_NODE *node)
  1511. {
  1512. int rc; /* It won't be used uninitialized despite what cc says.
  1513. Note default: branch below */
  1514. env->loc = node->loc;
  1515. switch (node->type)
  1516. {
  1517. case rc_node_bool:
  1518. rc = bool_eval (env, &node->v.bool);
  1519. break;
  1520. case rc_node_expr:
  1521. rc = expr_eval (env, &node->v.expr);
  1522. break;
  1523. default:
  1524. abort ();
  1525. }
  1526. return rc;
  1527. }
  1528. int
  1529. bool_eval (struct eval_env *env, RC_BOOL *bool)
  1530. {
  1531. int rc = node_eval (env, bool->left);
  1532. switch (bool->op)
  1533. {
  1534. case bool_not:
  1535. return !rc;
  1536. case bool_and:
  1537. if (!rc)
  1538. return 0;
  1539. break;
  1540. case bool_or:
  1541. if (rc)
  1542. return 1;
  1543. break;
  1544. }
  1545. return node_eval (env, bool->right);
  1546. }
  1547. void
  1548. cond_eval (struct eval_env *env, RC_COND *cond)
  1549. {
  1550. if (node_eval (env, cond->node))
  1551. stmt_list_eval (env, cond->iftrue);
  1552. else
  1553. stmt_list_eval (env, cond->iffalse);
  1554. }
  1555. void
  1556. rule_eval (struct eval_env *env, RC_RULE *rule)
  1557. {
  1558. if (node_eval (env, rule->node))
  1559. stmt_list_eval (env, rule->stmt);
  1560. }
  1561. void
  1562. stmt_list_eval (struct eval_env *env, RC_STMT *stmt)
  1563. {
  1564. for (; stmt; stmt = stmt->next)
  1565. {
  1566. env->loc = stmt->loc;
  1567. switch (stmt->type)
  1568. {
  1569. case rc_stmt_asgn:
  1570. asgn_eval (env, &stmt->v.asgn);
  1571. break;
  1572. case rc_stmt_cond:
  1573. cond_eval (env, &stmt->v.cond);
  1574. break;
  1575. case rc_stmt_rule:
  1576. rule_eval (env, &stmt->v.rule);
  1577. break;
  1578. case rc_stmt_inst:
  1579. inst_eval (env, &stmt->v.inst);
  1580. }
  1581. }
  1582. }
  1583. void
  1584. eval_section (int method, RC_SECTION *sec, struct rc_secdef *secdef,
  1585. void *data, MESSAGE msg)
  1586. {
  1587. struct eval_env env;
  1588. env.method = method;
  1589. env.child = secdef->child;
  1590. env.refcnt = 0;
  1591. env.refstr = NULL;
  1592. env.msg = msg;
  1593. env.data = data;
  1594. env.loc = sec->loc;
  1595. env.traceable = secdef->allow_prog;
  1596. if (env.traceable)
  1597. tracefile (&sec->loc, _("Section %s"), sec->name);
  1598. if (setjmp (env.jmp) == 0)
  1599. stmt_list_eval (&env, sec->stmt);
  1600. if (env.refstr)
  1601. argcv_free (-1, env.refstr);
  1602. }
  1603. void
  1604. rc_run_section (int method, RC_SECTION *sec, struct rc_secdef *secdef,
  1605. const char *class_name,
  1606. void *data, MESSAGE msg)
  1607. {
  1608. if (!sec)
  1609. return;
  1610. if (!class_name)
  1611. class_name = sec->name;
  1612. for (; secdef->name; secdef++)
  1613. {
  1614. if (!strcmp (secdef->name, class_name))
  1615. {
  1616. eval_section (method, sec, secdef, data, msg);
  1617. return;
  1618. }
  1619. }
  1620. anubis_error (0, 0, _("Unknown section: %s"), sec->name);
  1621. }
  1622. static int
  1623. check_kw (char *ident, int *flags)
  1624. {
  1625. struct rc_secdef *p = rc_secdef;
  1626. int key;
  1627. if (!p)
  1628. p = anubis_find_section ("RULE");
  1629. return rc_child_lookup (p->child, ident, CF_ALL, &key, flags) != NULL;
  1630. }
  1631. static int
  1632. is_prog_allowed (struct rc_loc *loc)
  1633. {
  1634. struct rc_secdef *p = rc_secdef;
  1635. if (!p)
  1636. p = anubis_find_section ("RULE");
  1637. if (!p->allow_prog)
  1638. parse_error (loc, _("program is not allowed in this section"));
  1639. return p->allow_prog;
  1640. }