summaryrefslogtreecommitdiffabout
path: root/mfd
Side-by-side diff
Diffstat (limited to 'mfd') (more/less context) (ignore whitespace changes)
-rw-r--r--mfd/drivers.c115
-rw-r--r--mfd/gram.y131
-rw-r--r--mfd/lex.l4
-rw-r--r--mfd/mailfromd.h8
-rw-r--r--mfd/opcodes2
-rw-r--r--mfd/prog.c10
6 files changed, 182 insertions, 88 deletions
diff --git a/mfd/drivers.c b/mfd/drivers.c
index d8dfb4b..ed8a288 100644
--- a/mfd/drivers.c
+++ b/mfd/drivers.c
@@ -891,25 +891,24 @@ print_type_result(NODE *node, int level)
{
- if (node->v.ret.code) {
- const char *s = NULL;
- int expr = 0;
-
- print_level(level);
- if (node->v.ret.message) {
- if (node->v.ret.message->type == node_type_string)
- s = node->v.ret.message->v.literal->text;
- else {
- expr = 1;
- s = "(expression)";
- }
- }
- dbg_setreply(NULL,
- (char*) LITERAL_TEXT(node->v.ret.code),
- (char*) LITERAL_TEXT(node->v.ret.xcode),
- (char*) s);
- if (expr)
- print_node(node->v.ret.message, level+1);
- }
+ NODE *code, *xcode;
+
+ code = node->v.ret.code;
+ xcode = node->v.ret.xcode;
+
print_level(level);
+ printf("SET REPLY ");
print_stat(node->v.ret.stat);
printf("\n");
+ print_level(level);
+ printf("CODE:\n");
+ if (code)
+ print_node(code, level+1);
+ print_level(level);
+ printf("XCODE:\n");
+ if (xcode)
+ print_node(xcode, level+1);
+ print_level(level);
+ printf("MESSAGE:\n");
+ if (node->v.ret.message)
+ print_node(node->v.ret.message, level+1);
+ printf("\n");
}
@@ -919,6 +918,4 @@ mark_type_result(NODE *node)
{
- if (node->v.ret.code)
- node->v.ret.code->flags |= VAR_REFERENCED;
- if (node->v.ret.xcode)
- node->v.ret.xcode->flags |= VAR_REFERENCED;
+ mark(node->v.ret.code);
+ mark(node->v.ret.xcode);
mark(node->v.ret.message);
@@ -929,2 +926,4 @@ optimize_type_result(NODE *node)
{
+ optimize(node->v.ret.code);
+ optimize(node->v.ret.xcode);
optimize(node->v.ret.message);
@@ -932,8 +931,7 @@ optimize_type_result(NODE *node)
-void
-code_type_result(NODE *node, struct locus **old_locus)
+static void
+code_result_arg(NODE *node)
{
- MARK_LOCUS();
- if (node->v.ret.message)
- code_node(node->v.ret.message);
+ if (node)
+ code_node(node);
else {
@@ -942,2 +940,51 @@ code_type_result(NODE *node, struct locus **old_locus)
}
+}
+
+static NODE *
+result_argptr(NODE *arg)
+{
+ if (arg && arg->type == node_type_string
+ && arg->v.literal->text[0] == 0)
+ arg = NULL;
+ return arg;
+}
+
+void
+code_type_result(NODE *node, struct locus **old_locus)
+{
+ NODE *code, *xcode;
+
+ code = result_argptr(node->v.ret.code);
+ xcode = result_argptr(node->v.ret.xcode);
+
+ switch (node->v.ret.stat) {
+ case SMFIS_REJECT:
+ if (code && code->type == node_type_string
+ && code->v.literal->text[0] != '5')
+ parse_error_locus(&node->locus,
+ _("Reject code should be 5xx"));
+ if (xcode && xcode->type == node_type_string
+ && xcode->v.literal->text[0] != '5')
+ parse_error_locus(&node->locus,
+ _("Reject extended code should be 5.x.x"));
+ break;
+
+ case SMFIS_TEMPFAIL:
+ if (code && code->type == node_type_string
+ && code->v.literal->text[0] != '4')
+ parse_error_locus(&node->locus,
+ _("Tempfail code should be 4xx"));
+ if (xcode && xcode->type == node_type_string
+ && xcode->v.literal->text[0] != '4')
+ parse_error_locus(&node->locus,
+ _("Tempfail extended code should be 4.x.x"));
+ break;
+ default:
+ break;
+ }
+
+ code_result_arg(node->v.ret.message);
+ code_result_arg(xcode);
+ code_result_arg(code);
+
MARK_LOCUS();
@@ -945,4 +992,2 @@ code_type_result(NODE *node, struct locus **old_locus)
code_immediate((void*)node->v.ret.stat);
- code_immediate((void*)LITERAL_OFF(node->v.ret.code));
- code_immediate((void*)LITERAL_OFF(node->v.ret.xcode));
code_op(opcode_nil);
@@ -1484,9 +1529,7 @@ code_type_catch(NODE *node, struct locus **old_locus)
} else {
- code_op(opcode_push);
- code_immediate(NULL);
+ code_result_arg(NULL);
+ code_result_arg(NULL);
+ code_result_arg(NULL);
code_op(opcode_result);
code_immediate(SMFIS_CONTINUE);
- code_immediate(NULL);
- code_immediate(NULL);
- code_immediate(NULL);
}
diff --git a/mfd/gram.y b/mfd/gram.y
index 332a748..15ee960 100644
--- a/mfd/gram.y
+++ b/mfd/gram.y
@@ -301,3 +301,3 @@ _create_alias(void *item, void *data)
%error-verbose
-%expect 29
+%expect 28
@@ -362,3 +362,3 @@ _create_alias(void *item, void *data)
%token <locus> FOR LOOP WHILE BREAK NEXT ARGCOUNT ALIAS DOTS ARGX VAPTR
-%token <literal> STRING CODE XCODE
+%token <literal> STRING
%token <literal> SYMBOL IDENTIFIER
@@ -388,3 +388,4 @@ _create_alias(void *item, void *data)
if_cond else_cond on_cond atom argref paren_argref
- funcall proccall expr common_expr simp_expr atom_expr
+ funcall proccall expr maybe_expr maybe_xcode_expr
+ common_expr simp_expr atom_expr
asgn catch throw return case_cond autodcl constdecl
@@ -396,6 +397,5 @@ _create_alias(void *item, void *data)
%type <loop> opt_loop_parms loop_parm_list
-%type <number> number
%type <arglist> arglist
%type <var> variable
-%type <literal> string opt_ident loop_ident alias
+%type <literal> string opt_ident loop_ident alias code xcode
%type <state> state_ident
@@ -894,6 +894,2 @@ sendmail_action:
{
- if ($2.code && $2.code->text[0] != '5')
- parse_error(_("Reject code should be 5xx"));
- if ($2.xcode && $2.xcode->text[0] != '5')
- parse_error(_("Reject extended code should be 5.x.x"));
$$ = alloc_node(node_type_result, &$1);
@@ -902,8 +898,12 @@ sendmail_action:
}
+ | ACT_REJECT '(' maybe_expr ',' maybe_xcode_expr ',' maybe_expr ')'
+ {
+ $$ = alloc_node(node_type_result, &$1);
+ $$->v.ret.stat = SMFIS_REJECT;
+ $$->v.ret.code = $3 ? cast_to(dtype_string, $3) : NULL;
+ $$->v.ret.xcode = $5 ? cast_to(dtype_string, $5) : NULL;
+ $$->v.ret.message = $7 ? cast_to(dtype_string, $7) : NULL;
+ }
| ACT_TEMPFAIL maybe_triplet
{
- if ($2.code && $2.code->text[0] != '4')
- parse_error(_("Tempfail code should be 4xx"));
- if ($2.xcode && $2.xcode->text[0] != '4')
- parse_error(_("Tempfail extended code should be 4.x.x"));
$$ = alloc_node(node_type_result, &$1);
@@ -912,2 +912,10 @@ sendmail_action:
}
+ | ACT_TEMPFAIL '(' maybe_expr ',' maybe_xcode_expr ',' maybe_expr ')'
+ {
+ $$ = alloc_node(node_type_result, &$1);
+ $$->v.ret.stat = SMFIS_TEMPFAIL;
+ $$->v.ret.code = $3 ? cast_to(dtype_string, $3) : NULL;
+ $$->v.ret.xcode = $5 ? cast_to(dtype_string, $5) : NULL;
+ $$->v.ret.message = $7 ? cast_to(dtype_string, $7) : NULL;
+ }
| ACT_CONTINUE
@@ -926,2 +934,11 @@ sendmail_action:
+maybe_xcode_expr: maybe_expr
+ | xcode
+ {
+ $$ = alloc_node(node_type_string, get_locus());
+ $$->v.literal = $1;
+ }
+ ;
+
+
header_action:
@@ -957,5 +974,6 @@ maybe_triplet: /* empty */
-triplet : CODE
+triplet : code
{
- $$.code = $1;
+ $$.code = alloc_node(node_type_string, get_locus());
+ $$.code->v.literal = $1;
$$.xcode = NULL;
@@ -963,17 +981,22 @@ triplet : CODE
}
- | CODE XCODE
+ | code xcode
{
- $$.code = $1;
- $$.xcode = $2;
+ $$.code = alloc_node(node_type_string, get_locus());
+ $$.code->v.literal = $1;
+ $$.xcode = alloc_node(node_type_string, get_locus());
+ $$.xcode->v.literal = $2;
$$.message = NULL;
}
- | CODE XCODE expr
+ | code xcode expr
{
- $$.code = $1;
- $$.xcode = $2;
+ $$.code = alloc_node(node_type_string, get_locus());
+ $$.code->v.literal = $1;
+ $$.xcode = alloc_node(node_type_string, get_locus());
+ $$.xcode->v.literal = $2;
$$.message = cast_to(dtype_string, $3);
}
- | CODE expr
+ | code expr
{
- $$.code = $1;
+ $$.code = alloc_node(node_type_string, get_locus());
+ $$.code->v.literal = $1;
$$.xcode = NULL;
@@ -983,2 +1006,38 @@ triplet : CODE
+code : NUMBER
+ {
+ char buf[4];
+
+ if ($1 < 200 || $1 > 599) {
+ yyerror(_("Invalid SMTP reply code"));
+ buf[0] = 0;
+ } else
+ snprintf(buf, sizeof(buf), "%lu", $1);
+ $$ = string_alloc(buf, strlen(buf));
+ }
+ ;
+
+xcode : NUMBER '.' NUMBER '.' NUMBER
+ {
+ char buf[sizeof("5.999.999")];
+
+ /* RFC 1893:
+ The syntax of the new status codes is defined as:
+
+ status-code = class "." subject "." detail
+ class = "2"/"4"/"5"
+ subject = 1*3digit
+ detail = 1*3digit
+ */
+ if (($1 != 2 && $1 != 4 && $1 !=5)
+ || $3 > 999 || $5 > 999) {
+ yyerror(_("Invalid extended reply code"));
+ buf[0] = 0;
+ } else
+ snprintf(buf, sizeof(buf), "%lu.%lu.%lu",
+ $1, $3, $5);
+ $$ = string_alloc(buf, strlen(buf));
+ }
+ ;
+
condition : if_cond
@@ -1123,3 +1182,3 @@ value : STRING
}
- | number
+ | NUMBER
{
@@ -1166,15 +1225,2 @@ fnmatches : FNMATCHES
-number : NUMBER
- | CODE
- {
- char *p;
- $$ = strtol($1->text, &p, 10);
- if (*p) {
- /* should not happen */
- parse_error(_("Invalid number (near `%s')"), p);
- YYERROR;
- }
- }
- ;
-
@@ -1404,2 +1450,9 @@ expr : NOT expr
+maybe_expr : /* empty */
+ {
+ $$ = NULL;
+ }
+ | expr
+ ;
+
common_expr: simp_expr
@@ -1952,3 +2005,3 @@ on : ON
{
- onblock(1);
+ tie_in_onblock(1);
}
@@ -1958,3 +2011,3 @@ do : DO
{
- onblock(0);
+ tie_in_onblock(0);
}
diff --git a/mfd/lex.l b/mfd/lex.l
index 3ceabfc..c1f9c3e 100644
--- a/mfd/lex.l
+++ b/mfd/lex.l
@@ -320,4 +320,2 @@ vaptr return keyword(VAPTR);
/* Numeric strings */
-{N}\.{N}\.{N} { string(yytext, yyleng); return XCODE; }
-[0-9]{3} { string(yytext, yyleng); return CODE; }
0[xX]{X}{X}* { yylval.number = strtoul(yytext, NULL, 16); return NUMBER; };
@@ -793,3 +791,3 @@ isemptystr(char *text)
void
-onblock(int enable)
+tie_in_onblock(int enable)
{
diff --git a/mfd/mailfromd.h b/mfd/mailfromd.h
index ac93cba..bdf09dc 100644
--- a/mfd/mailfromd.h
+++ b/mfd/mailfromd.h
@@ -309,5 +309,5 @@ struct return_node {
sfsistat stat; /* Return status */
- struct literal *code; /* Code */
- struct literal *xcode; /* Extended code */
- NODE *message; /* Subtree producing the textual message */
+ NODE *code; /* Code */
+ NODE *xcode; /* Extended code */
+ NODE *message; /* Textual message */
};
@@ -699,3 +699,3 @@ int yyerror(char *s);
void add_include_dir(const char *dir);
-void onblock(int enable);
+void tie_in_onblock(int enable);
int parse_program(char *name, int ydebug);
diff --git a/mfd/opcodes b/mfd/opcodes
index cee68d4..dd883ea 100644
--- a/mfd/opcodes
+++ b/mfd/opcodes
@@ -92,3 +92,3 @@ FUNCALL dump_funcall 2
NEXT NULL 0
-RESULT dump_result 3
+RESULT dump_result 1
HEADER dump_header 2
diff --git a/mfd/prog.c b/mfd/prog.c
index 90a426e..f8e58a9 100644
--- a/mfd/prog.c
+++ b/mfd/prog.c
@@ -1489,5 +1489,5 @@ instr_result(eval_environ_t env)
- get_string_arg(env, 0, &message);
- get_literal(env, 1, (const char**)&code);
- get_literal(env, 2, (const char**)&xcode);
+ get_string_arg(env, 2, &message);
+ get_string_arg(env, 1, &xcode);
+ get_string_arg(env, 0, &code);
@@ -1515,4 +1515,4 @@ instr_result(eval_environ_t env)
env->setreply(env->data, code, xcode, message);
- advance_pc(env, 3);
- adjust_stack(env, 1);
+ advance_pc(env, 1);
+ adjust_stack(env, 3);
}

Return to:

Send suggestions and report system problems to the System administrator.