diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-08-05 15:53:35 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-08-05 15:53:35 +0300 |
commit | 60eed8fc3bddfd7728d6e8d147636f853c3e3859 (patch) | |
tree | 6f79bf55faefd8add94c55fd3f8f66ed035e9476 /src | |
parent | 365cd1ef4cde229e19bbcad3c26f47d4d700376b (diff) | |
download | mailfromd-60eed8fc3bddfd7728d6e8d147636f853c3e3859.tar.gz mailfromd-60eed8fc3bddfd7728d6e8d147636f853c3e3859.tar.bz2 |
Implement functions for modifying headers addressed by their number.
Improve header renaming functions.
* NEWS: Updated.
* doc/functions.texi: Updated.
* mflib/header_rename.mf4: Rewrite from scratch.
* src/builtin/curhdr.bi (get_current_header): Remove,
use env_get_header instead. All uses changed.
* src/builtin/header.bi (header_delete_nth)
(header_replace_nth): New built-ins.
* src/builtin/snarf.m4 (MF_CAPTURE): Accept opional argument.
All uses updated.
* src/builtin/vars.bi (sendmail_header_count): New variable.
(get_sendmail_header_count)
(set_sendmail_header_count): New functions.
* src/engine.c (message_data) <hdrtrans,hdrcount>: New members.
(test_message_data_init,priv_get): Initialize hdrtrans and hdrcount.
(priv_store_msgmod_closure): Name can be NULL.
(filter_cleanup): Free hdrtrans.
(run_msgmod) <header_insert>: Adjust header number by the value of
sendmail_header_count variable.
Handle header_replace_nth and header_delete_nth opcodes.
* src/gram.y (msgmod_opcode_str): Handle header_replace_nth and
header_delete_nth opcodes.
* src/mailfromd.h (msgmod_opcode) <header_delete_nth>
<header_replace_nth>: New opcodes.
(get_sendmail_header_count)
(set_sendmail_header_count)
(env_get_header): New protos.
* src/prog.c (eval_environ) <header>: New member.
(env_capture_start): Initialize header.
(env_get_header): New function.
(env_msgmod): Name can be NULL.
(destroy_environment): Destroy the header.
Diffstat (limited to 'src')
-rw-r--r-- | src/builtin/curhdr.bi | 149 | ||||
-rw-r--r-- | src/builtin/header.bi | 32 | ||||
-rw-r--r-- | src/builtin/snarf.m4 | 14 | ||||
-rw-r--r-- | src/builtin/vars.bi | 15 | ||||
-rw-r--r-- | src/engine.c | 141 | ||||
-rw-r--r-- | src/gram.y | 9 | ||||
-rw-r--r-- | src/mailfromd.h | 9 | ||||
-rw-r--r-- | src/prog.c | 82 |
8 files changed, 329 insertions, 122 deletions
diff --git a/src/builtin/curhdr.bi b/src/builtin/curhdr.bi index b1776b77..01192bdb 100644 --- a/src/builtin/curhdr.bi +++ b/src/builtin/curhdr.bi @@ -16,109 +16,25 @@ #include "msg.h" -struct current_header { - mu_header_t hdr; -}; - -static void * -alloc_header() -{ - return xzalloc(sizeof(struct current_header)); -} - -static void -destroy_header(void *data) -{ - struct current_header *chdr = data; - mu_header_destroy(&chdr->hdr); - free(chdr); -} - -static void -free_header(void *data) -{ - struct current_header *chdr = data; - mu_header_destroy(&chdr->hdr); -} - -MF_DECLARE_DATA(HEADER, alloc_header, destroy_header, free_header) - -static mu_header_t -get_current_header(eval_environ_t env, mu_stream_t mstr) -{ - struct current_header *chdr = MF_GET_DATA; - if (!chdr->hdr) { - mu_header_t hdr; - char *text; - int rc; - mu_off_t size; - size_t total; - size_t start; - - rc = mu_stream_size(mstr, &size); - MF_ASSERT(rc == 0, - mfe_failure, - "mu_stream_size: %s", - mu_strerror (rc)); - text = malloc(size + 1); - MF_ASSERT(text != NULL, - mfe_failure, - _("not enough memory")); - rc = mu_stream_seek(mstr, 0, SEEK_SET, NULL); - MF_ASSERT(rc == 0, - mfe_failure, - "mu_stream_seek: %s", - mu_strerror(rc)); - - /* FIXME: Use "header" filter instead of this loop */ - for (total = 0; total < size;) { - size_t nrd; - - rc = mu_stream_read(mstr, text + total, - size - total, &nrd); - if (rc || nrd == 0) - break; - total += nrd; - } - text[total] = 0; - - /* FIXME: Reposition the stream at its end. - This call may happen in the middle of capturing - so I have to make sure to not disturb the capturing - process. - - The same effect could have been achieved by using - streamref, but this approach speeds up things a - bit. - */ - env_reposition(env); - - if (memcmp (text, "From ", 5) == 0) - start = strcspn (text, "\n") + 1; - else - start = 0; - rc = mu_header_create(&hdr, text + start, total - start); - free(text); - MF_ASSERT(rc == 0, - mfe_failure, - "mu_header_create: %s", - mu_strerror (rc)); - chdr->hdr = hdr; - } - return chdr->hdr; -} - /* number current_header_count([string name]) */ MF_STATE(eoh) MF_STATE(body) MF_STATE(eom) -MF_CAPTURE(mstr) +MF_CAPTURE MF_DEFUN(current_header_count, NUMBER, OPTIONAL, STRING name) { - mu_header_t hdr = get_current_header(env, mstr); + mu_header_t hdr; size_t total; size_t count; - int rc = mu_header_get_field_count(hdr, &total); + int rc; + + rc = env_get_header(env, &hdr); + MF_ASSERT(rc == 0, + mfe_failure, + "env_get_header: %s", + mu_strerror(rc)); + + rc = mu_header_get_field_count(hdr, &total); MF_ASSERT(rc == 0, mfe_failure, @@ -143,12 +59,20 @@ END MF_STATE(eoh) MF_STATE(body) MF_STATE(eom) -MF_CAPTURE(mstr) +MF_CAPTURE MF_DEFUN(current_header_nth_name, STRING, NUMBER index) { - mu_header_t hdr = get_current_header(env, mstr); + mu_header_t hdr; const char *sptr; - int rc = mu_header_sget_field_name(hdr, index, &sptr); + int rc; + + rc = env_get_header(env, &hdr); + MF_ASSERT(rc == 0, + mfe_failure, + "env_get_header: %s", + mu_strerror(rc)); + + rc = mu_header_sget_field_name(hdr, index, &sptr); if (rc == MU_ERR_NOENT) MF_THROW(mfe_not_found, @@ -166,12 +90,20 @@ END MF_STATE(eoh) MF_STATE(body) MF_STATE(eom) -MF_CAPTURE(mstr) +MF_CAPTURE MF_DEFUN(current_header_nth_value, STRING, NUMBER index) { - mu_header_t hdr = get_current_header(env, mstr); + mu_header_t hdr; const char *sptr; - int rc = mu_header_sget_field_value(hdr, index, &sptr); + int rc; + + rc = env_get_header(env, &hdr); + MF_ASSERT(rc == 0, + mfe_failure, + "env_get_header: %s", + mu_strerror(rc)); + + rc = mu_header_sget_field_value(hdr, index, &sptr); if (rc == MU_ERR_NOENT) MF_THROW(mfe_not_found, @@ -189,13 +121,20 @@ END MF_STATE(eoh) MF_STATE(body) MF_STATE(eom) -MF_CAPTURE(mstr) +MF_CAPTURE MF_DEFUN(current_header, STRING, STRING name, OPTIONAL, NUMBER index) { - mu_header_t hdr = get_current_header(env, mstr); + mu_header_t hdr; const char *sptr; - int rc = mu_header_sget_value_n(hdr, name, MF_OPTVAL(index, 1), - &sptr); + int rc; + + rc = env_get_header(env, &hdr); + MF_ASSERT(rc == 0, + mfe_failure, + "env_get_header: %s", + mu_strerror(rc)); + + rc = mu_header_sget_value_n(hdr, name, MF_OPTVAL(index, 1), &sptr); if (rc == MU_ERR_NOENT) MF_THROW(mfe_not_found, diff --git a/src/builtin/header.bi b/src/builtin/header.bi index 9e30800b..07fd530e 100644 --- a/src/builtin/header.bi +++ b/src/builtin/header.bi @@ -70,6 +70,22 @@ MF_DEFUN(header_delete, VOID, STRING name, OPTIONAL, NUMBER idx) } END +MF_CAPTURE +MF_DEFUN(header_delete_nth, VOID, NUMBER idx) +{ + struct locus locus; + + env_get_locus(env, &locus); + + trace("%s%s:%lu: %s %lu", + mailfromd_msgid(env_get_context(env)), + locus.file, locus.line, + msgmod_opcode_str(header_delete_nth), + idx); + env_msgmod(env, header_delete_nth, NULL, NULL, idx); +} +END + MF_DEFUN(header_replace, VOID, STRING name, STRING value, OPTIONAL, NUMBER idx) { struct locus locus; @@ -85,4 +101,20 @@ MF_DEFUN(header_replace, VOID, STRING name, STRING value, OPTIONAL, NUMBER idx) } END +MF_CAPTURE +MF_DEFUN(header_replace_nth, VOID, NUMBER idx, STRING name, STRING value) +{ + struct locus locus; + + env_get_locus(env, &locus); + + trace("%s%s:%lu: %s \"%s: %s\" (%lu)", + mailfromd_msgid(env_get_context(env)), + locus.file, locus.line, + msgmod_opcode_str(header_replace_nth), + name, value, idx); + env_msgmod(env, header_replace_nth, name, value, idx); +} +END + MF_INIT diff --git a/src/builtin/snarf.m4 b/src/builtin/snarf.m4 index 71bffd36..2c64a755 100644 --- a/src/builtin/snarf.m4 +++ b/src/builtin/snarf.m4 @@ -338,11 +338,14 @@ m4_define([<MF_STATE>], [<m4_define([<__MF_STATE__>],__MF_STATE__[< | STATMASK(smtp_state_$1)>])>],m4_dnl [<m4_define([<__MF_STATE__>],[<STATMASK(smtp_state_$1)>])>])>]) -/* MF_CAPTURE(str) - Declare next MF_DEFUN as requiring message capturing. - Store a reference to the capture stream in STR. +/* MF_CAPTURE([str]) - Declare next MF_DEFUN as requiring message capturing. + The form with the STR argument can be used only in MF_STATE(eom) + functions (FIXME: this should be enforced at compile time). In that + case a reference to the capture stream is stored in STR. */ -m4_define([<MF_CAPTURE>], -[<m4_ifdef([<__MF_CAPTURE__>],,[<m4_define([<__MF_CAPTURE__>],[<$1>])>])>]) +m4_define([<MF_CAPTURE>],m4_dnl +[<m4_define([<__MF_NEEDS_CAPTURE__>],1)m4_dnl +m4_ifelse([<$1>],,,[<m4_define([<__MF_CAPTURE__>],[<$1>])>])>]) /* env_get_stream - prohibit the use of the library function of the same name. */ @@ -395,7 +398,7 @@ va_builtin_install_ex("$2", bi_$2,m4_dnl __mf_argtype($3),m4_dnl mf_argcount(m4_shift(m4_shift(m4_shift($@)))),m4_dnl mf_optcount(m4_shift(m4_shift(m4_shift($@)))),m4_dnl - m4_ifdef([<__MF_CAPTURE__>],[<MFD_BUILTIN_CAPTURE>],0)|$1,m4_dnl + m4_ifdef([<__MF_NEEDS_CAPTURE__>],[<MFD_BUILTIN_CAPTURE>],0)|$1,m4_dnl mf_typelist(m4_shift(m4_shift(m4_shift($@))))); m4_divert(2)m4_dnl {m4_ifdef([<__MF_CAPTURE__>],[< @@ -670,6 +673,7 @@ m4_popdef([<__MF_FUNCTION__>])m4_dnl m4_popdef([<__MF_ARGLIST__>])m4_dnl m4_popdef([<__MF_VARARGS__>])m4_dnl m4_undefine([<__MF_CAPTURE__>])m4_dnl +m4_undefine([<__MF_NEEDS_CAPTURE__>])m4_dnl m4_undefine([<__MF_STATE__>])m4_dnl m4_undefine([<__MF_ENDLAB__>])m4_dnl m4_define([<__mf_dataseg>])m4_dnl diff --git a/src/builtin/vars.bi b/src/builtin/vars.bi index 8c23f292..60b3e12b 100644 --- a/src/builtin/vars.bi +++ b/src/builtin/vars.bi @@ -21,7 +21,8 @@ MF_VAR(milter_client_address, STRING, SYM_PRECIOUS); MF_VAR(milter_server_family, NUMBER, SYM_PRECIOUS); MF_VAR(milter_server_address, STRING, SYM_PRECIOUS); MF_VAR(milter_server_id, STRING, SYM_PRECIOUS); - +MF_VAR(sendmail_header_count, NUMBER, SYM_PRECIOUS); + /* Functions to access %rcpt_count */ unsigned long get_rcpt_count(eval_environ_t env) @@ -41,6 +42,18 @@ incr_rcpt_count(eval_environ_t env) MF_VAR_INC(rcpt_count); } +/* Same for sendmail_header_count */ +unsigned long +get_sendmail_header_count(eval_environ_t env) +{ + return (long) MF_VAR_REF(sendmail_header_count); +} + +void +set_sendmail_header_count(eval_environ_t env, unsigned long v) +{ + MF_VAR_REF(sendmail_header_count, v); +} /* define_milter_address name */ m4_define([<define_milter_address>],[< diff --git a/src/engine.c b/src/engine.c index 424549cb..18b0b6b4 100644 --- a/src/engine.c +++ b/src/engine.c @@ -47,11 +47,25 @@ static void ctx_msgmod(void *data, struct msgmod_closure *cmd); /* Per-message data */ +/* Header translation table is used to translate absolute header number + into Sendmail notation (name, idx), where name is the header name and + idx is 1-based number of occurrence of the header with that name. + + This translation is needed for two functions provided by Mailfromd: + header_delete_nth and header_replace_nth. +*/ +struct hdrtrans { + const char *name; + size_t idx; +}; + struct message_data { eval_environ_t env; /* Evaluation environment */ mu_list_t mmq; /* Message Modification Queue */ char *helostr; /* Domain name obtained in HELO phase */ - char msgid[64]; /* Message ID */ + char msgid[64]; /* Message ID */ + struct hdrtrans *hdrtrans; /* Header translation table */ + size_t hdrcount; /* No. of entries in hdrtrans */ }; static struct message_data *test_message_data; @@ -63,6 +77,8 @@ test_message_data_init(eval_environ_t env) test_message_data->mmq = NULL; test_message_data->helostr = NULL; test_message_data->msgid[0] = 0; + test_message_data->hdrtrans = NULL; + test_message_data->hdrcount = 0; } static struct message_data * @@ -92,6 +108,8 @@ priv_get(SMFICTX *ctx) md->mmq = NULL; md->helostr = NULL; md->msgid[0] = 0; + md->hdrtrans = NULL; + md->hdrcount = 0; gacopyz_setpriv(ctx, md); env_init(md->env); if (gacopyz_server_sockname(ctx, &addr, &len) == 0) @@ -156,7 +174,7 @@ priv_store_msgmod_closure(SMFICTX *ctx, struct msgmod_closure *cmd) mu_debug(MF_SOURCE_ENGINE, MU_DEBUG_TRACE5, ("adding msgmod_closure: %s \"%s\" %s %u", msgmod_opcode_str(cmd->opcode), - cmd->name, SP(cmd->value), cmd->idx)); + SP(cmd->name), SP(cmd->value), cmd->idx)); mu_list_append(md->mmq, cmd); return 0; } @@ -263,6 +281,7 @@ filter_cleanup(SMFICTX *ctx) free(md->helostr); destroy_environment(md->env); mu_list_destroy(&md->mmq); + free(md->hdrtrans); free(md); gacopyz_setpriv(ctx, NULL); } @@ -597,15 +616,68 @@ xlate_and_replace_body(SMFICTX *ctx, const char *value, size_t size) } static int +md_hdrtrans_fill(struct message_data *md) +{ + int rc; + mu_header_t hdr; + size_t count, i, j; + + if (env_get_header(md->env, &hdr)) + return 1; + rc = mu_header_get_field_count(hdr, &count); + if (rc) { + mu_diag_funcall(MU_DIAG_ERROR, + "mu_header_get_field_count", + NULL, rc); + return 1; + } + md->hdrtrans = xcalloc(count, sizeof(md->hdrtrans[0])); + for (i = 1; i <= count; i++) { + const char *s; + rc = mu_header_sget_field_name(hdr, i, &s); + if (rc) { + mu_diag_funcall(MU_DIAG_ERROR, + "mu_header_sget_field_name", + NULL, rc); + return 1; + } + md->hdrtrans[i-1].name = s; + md->hdrtrans[i-1].idx = 1; + for (j = i - 1; j > 0; j--) + if (mu_c_strcasecmp(md->hdrtrans[j-1].name, s) == 0) { + md->hdrtrans[i-1].idx = + md->hdrtrans[j-1].idx + 1; + break; + } + } + md->hdrcount = count; + return 0; +} + +static int +md_hdrtrans(struct message_data *md, struct msgmod_closure *hdr) +{ + if (!md->hdrtrans && md_hdrtrans_fill(md)) + return -1; + if (hdr->idx == 0 || hdr->idx > md->hdrcount) + return 1; + hdr->name = (char*) md->hdrtrans[hdr->idx - 1].name; + hdr->idx = md->hdrtrans[hdr->idx - 1].idx; + return 0; +} + +static int run_msgmod(void *item, void *data) { - struct msgmod_closure *hdr = item; + struct msgmod_closure *hdr = item, thdr; SMFICTX *ctx = data; - + struct message_data *md; + mu_debug(MF_SOURCE_ENGINE, MU_DEBUG_TRACE6, ("%s %s: %s %u", msgmod_opcode_str(hdr->opcode), - hdr->name, SP(hdr->value), hdr->idx)); + SP(hdr->name), SP(hdr->value), hdr->idx)); + switch (hdr->opcode) { case header_add: gacopyz_add_header(ctx, hdr->name, hdr->value); @@ -620,7 +692,25 @@ run_msgmod(void *item, void *data) break; case header_insert: - gacopyz_insert_header(ctx, hdr->idx, hdr->name, hdr->value); + /* Note: The get_sendmail_header_count() call returns the + number of headers defined by Sendmail (or other MTA) itself. + I have found no reliable method allowing to determine + that number automatically. In the absence of such method, + the user has to define the header count explicitly, by + setting the sendmail_header_count variable. For Sendmail, + a good estimate is given by the following command: + + grep -c ^H /etc/mail/sendmail.cf + + Notice, however, that some of the headers may be defined + conditionally, see the section 5.5. "H -- Define Header", + in the Sendmail(tm) Installation and Operation Guide, for + more information. + */ + md = priv_get(ctx); + gacopyz_insert_header(ctx, + hdr->idx + get_sendmail_header_count(md->env), + hdr->name, hdr->value); break; case rcpt_add: @@ -637,6 +727,45 @@ run_msgmod(void *item, void *data) case body_repl: xlate_and_replace_body(ctx, hdr->value, strlen(hdr->value)); + break; + + case header_replace_nth: + md = priv_get(ctx); + thdr = *hdr; + switch (md_hdrtrans(md, &thdr)) { + case -1: + return 1; + case 1: + return 0; + default: + break; + } + /* Remove old header */ + gacopyz_change_header(ctx, thdr.idx, thdr.name, NULL); + /* Insert the new one. For the meaning of + get_sendmail_header_count, see the comment to the + header_insert case above. + */ + gacopyz_insert_header(ctx, + hdr->idx + get_sendmail_header_count(md->env), + hdr->name, hdr->value); + break; + + case header_delete_nth: + thdr = *hdr; + switch (md_hdrtrans(priv_get(ctx), &thdr)) { + case -1: + return 1; + case 1: + return 0; + default: + break; + } + gacopyz_change_header(ctx, thdr.idx, thdr.name, NULL); + break; + + default: + abort(); } return 0; } @@ -3243,6 +3243,13 @@ msgmod_opcode_str(enum msgmod_opcode opcode) case body_repl: return "REPLACE BODY"; + + case header_replace_nth: + return "REPLACE NTH HEADER"; + + case header_delete_nth: + return "DELETE NTH HEADER"; + } return "UNKNOWN HEADER COMMAND"; } @@ -3268,7 +3275,7 @@ dbg_msgmod(void *data, struct msgmod_closure *clos) printf("clearing msgmod list\n"); else printf("%s %s: %s %u\n", msgmod_opcode_str(clos->opcode), - clos->name, SP(clos->value), clos->idx); + SP(clos->name), SP(clos->value), clos->idx); } static const char * diff --git a/src/mailfromd.h b/src/mailfromd.h index df336cad..02307056 100644 --- a/src/mailfromd.h +++ b/src/mailfromd.h @@ -245,7 +245,9 @@ enum msgmod_opcode { /* Message modification operation */ rcpt_add, /* Add a recipient */ rcpt_delete, /* Delete a recipient */ quarantine, /* Quarantine a message */ - body_repl, /* Replace message body */ + body_repl, /* Replace message body */ + header_delete_nth, /* Delete Nth header */ + header_replace_nth /* Replace Nth header */ }; struct msgmod_closure { @@ -785,6 +787,10 @@ extern prog_counter_t entry_point[smtp_state_count]; unsigned long get_rcpt_count(eval_environ_t env); void clear_rcpt_count(eval_environ_t env); void incr_rcpt_count(eval_environ_t env); + +unsigned long get_sendmail_header_count(eval_environ_t env); +void set_sendmail_header_count(eval_environ_t env, unsigned long v); + void set_last_poll_helo(eval_environ_t env, const char *text); void set_last_poll_greeting(eval_environ_t env, const char *text); void set_last_poll_host(eval_environ_t env, const char *host_addr); @@ -852,6 +858,7 @@ const char *environment_get_null_symbol(eval_environ_t env, SMFICTX *env_get_context(eval_environ_t env); size_t env_get_line_count(eval_environ_t env); int env_get_stream(eval_environ_t env, mu_stream_t *pstr); +int env_get_header(eval_environ_t env, mu_header_t *hdr); void env_reposition(eval_environ_t env); int env_capture_start(eval_environ_t env); int env_capture_write(eval_environ_t env, const char *buf, size_t size); @@ -288,6 +288,8 @@ struct eval_environ { size_t line_count; /* Number of lines in stream */ int reposition; /* When !0, stream must be repositioned to its end before writing. */ + mu_header_t header; /* Headers from stream, converted to a MU + object. */ /* Non-local exits */ struct exception_context *defcatch_ctx; @@ -2420,7 +2422,7 @@ env_capture_start(eval_environ_t env) if (env->stream) { /* Drop any previously captured message data */ env_free_captured(env); - + mu_header_destroy(&env->header); /* Truncate existing stream and reposition to its beginning */ rc = mu_stream_truncate(env->stream, 0); @@ -2519,6 +2521,78 @@ env_capture_write_args(eval_environ_t env, ...) return rc; } +int +env_get_header(eval_environ_t env, mu_header_t *hdr) +{ + if (!env->header) { + char *text; + int rc; + mu_off_t size; + size_t total; + size_t start; + + rc = mu_stream_size(env->stream, &size); + if (rc) { + mu_diag_funcall(MU_DIAG_ERROR, "mu_stream_size", NULL, + rc); + return rc; + } + text = xmalloc(size + 1); + rc = mu_stream_seek(env->stream, 0, SEEK_SET, NULL); + if (rc) { + mu_diag_funcall(MU_DIAG_ERROR, "mu_stream_seek", + NULL, rc); + free(text); + return rc; + } + + /* FIXME: Use "header" filter instead of this loop */ + for (total = 0; total < size;) { + size_t nrd; + + rc = mu_stream_read(env->stream, text + total, + size - total, &nrd); + if (rc) { + mu_diag_funcall(MU_DIAG_ERROR, + "mu_stream_read", + NULL, rc); + free(text); + return rc; + } + if (nrd == 0) + break; + total += nrd; + } + text[total] = 0; + + /* FIXME: Reposition the stream at its end. + This call may happen in the middle of capturing + so I have to make sure to not disturb the capturing + process. + + The same effect could have been achieved by using + streamref, but this approach speeds up things a + bit. + */ + env_reposition(env); + + if (memcmp (text, "From ", 5) == 0) + start = strcspn (text, "\n") + 1; + else + start = 0; + rc = mu_header_create(&env->header, text + start, + total - start); + free(text); + if (rc) { + mu_diag_funcall(MU_DIAG_ERROR, "mu_header_create", + NULL, rc); + return rc; + } + } + *hdr = env->header; + return 0; +} + void env_clear_msgmod(eval_environ_t env) { @@ -2536,10 +2610,11 @@ env_msgmod(eval_environ_t env, enum msgmod_opcode opcode, if (PROG_TRACE_ENGINE) prog_trace(env, "Registering %s \"%s\" \"%s\" %u", - msgmod_opcode_str(opcode), name, SP(value), idx); + msgmod_opcode_str(opcode), SP(name), SP(value), + idx); cp->opcode = opcode; - cp->name = xstrdup(name); + cp->name = name ? xstrdup(name) : NULL; cp->value = value ? xstrdup(value) : NULL; cp->idx = idx; env->msgmod(env->data, cp); @@ -2694,6 +2769,7 @@ destroy_environment(eval_environ_t env) free(env->dataseg); free(env->matches); mu_stream_destroy(&env->stream); + mu_header_destroy(&env->header); mu_list_destroy(&env->cleanup_list); env_builtin_priv_destroy(env); free(env); |