"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/builtin/msg.c" between
mailfromd-8.11.tar.xz and mailfromd-8.12.tar.xz

About: Mailfromd is a general-purpose mail filtering daemon for Sendmail, Postfix and MeTA1 (interfaces with the MTA using Milter or PMilter protocols).

msg.c  (mailfromd-8.11.tar.xz):msg.c  (mailfromd-8.12.tar.xz)
skipping to change at line 2894 skipping to change at line 2894
} while (0); } while (0);
} }
endlab: endlab:
#line 691 #line 691
env_function_cleanup_flush(env, NULL); env_function_cleanup_flush(env, NULL);
#line 691 #line 691
return; return;
#line 691 #line 691
} }
#if MAILUTILS_VERSION_MAJOR == 3 && MAILUTILS_VERSION_MINOR < 13
/*
* Before maiutils commit 62a81295d771a9ca90e617b13992279932211b78,
* mu_filter_chain_create would (1) decrement the reference counter of
* its transport argument in case of errors, except (2) if the error
* was caused by failure of the filter initialization function.
* This exception is due to another bug, which happened to compensate
* for the first one and which was fixed by mailutils commit
* 231194ebb67b2c2865b8d4e82bd5379761742ec1,
*
* See the following link for detailed description of both bugs:
* http://git.savannah.gnu.org/cgit/mailutils.git/plain/libmailutils/tests/fltcn
t.c?id=231194ebb67b2c2865b8d4e82bd5379761742ec1.
*
* To illuistrate this on the example of ICONV filter, invoked by
* charset_setup:
*
* - If all arguments are OK, the function creates the filter, and
* increments transport reference counter by 1.
* - If unsupported encoding was given, transport reference counter
* is decremented by one.
* - If unsupported fallback method is given, reference counter
* is not changed.
*
* The following workaround ensures the proper behavior:
*
* - On success, reference counter increases by one.
* - One error, it remains unchanged.
*/
# include <mailutils/sys/stream.h>
static int
mfl_filter_chain_create(mu_stream_t *pret, mu_stream_t transport,
int defmode, int flags,
size_t argc, char **argv)
{
int rc;
int ref_count = transport->ref_count;
/*
* Increase reference counter to prevent transport from being
* freed as a result of bug [1].
*/
mu_stream_ref(transport);
rc = mu_filter_chain_create(pret, transport, defmode, flags,
argc, argv);
if (rc == 0)
/* On success, decrement the counter. */
mu_stream_unref(transport);
else /* We've hit bug [2]. Decrement the counter. */
if (transport->ref_count > ref_count)
mu_stream_unref(transport);
return rc;
}
#else
static int
mfl_filter_chain_create(mu_stream_t *pret, mu_stream_t transport,
int defmode, int flags,
size_t argc, char **argv)
{
return mfl_filter_chain_create(pret, transport, defmode, flags,
argc, argv);
}
#endif
static int
mime_decode_filter(mu_stream_t *retflt, mu_stream_t stream, mu_message_t msg)
{
int rc;
mu_header_t hdr;
char *encoding = NULL;
/* Get the headers. */
rc = mu_message_get_header(msg, &hdr);
if (rc) {
mu_diag_funcall(MU_DIAG_ERROR, "mu_message_get_header", NULL, rc)
;
return rc;
}
/* Filter the stream through the appropriate decoder. */
rc = mu_header_aget_value_unfold(hdr,
MU_HEADER_CONTENT_TRANSFER_ENCODING,
&encoding);
switch (rc) {
case 0:
mu_rtrim_class(encoding, MU_CTYPE_SPACE);
break;
case MU_ERR_NOENT:
encoding = NULL;
break;
default:
mu_diag_funcall(MU_DIAG_ERROR, "mu_header_aget_value_unfold",
NULL, rc);
return rc;
}
if (encoding == NULL || *encoding == '\0') {
/* No need to filter */;
mu_stream_ref(stream);
*retflt = stream;
rc = 0;
} else if ((rc = mu_filter_create(retflt, stream, encoding,
MU_FILTER_DECODE,
MU_STREAM_READ)) == 0) {
/* success */;
} else if (rc == MU_ERR_NOENT) {
mu_error("unknown encoding: %s", encoding);
} else {
mu_diag_funcall(MU_DIAG_ERROR,
"mu_filter_create", encoding, rc);
}
free(encoding);
return rc;
}
static int
mime_charset_filter(mu_stream_t *retflt, mu_stream_t stream,
mu_message_t msg, char const *charset,
char const *charset_fallback)
{
int rc;
mu_header_t hdr;
mu_content_type_t ct;
char *buf = NULL;
rc = mu_message_get_header(msg, &hdr);
if (rc) {
mu_diag_funcall(MU_DIAG_ERROR, "mu_message_get_header", NULL, rc)
;
return rc;
}
/* Read and parse the Content-Type header. */
rc = mu_header_aget_value_unfold(hdr, MU_HEADER_CONTENT_TYPE, &buf);
if (rc == MU_ERR_NOENT) {
buf = strdup("text/plain");
if (!buf)
return errno;
} else if (rc) {
mu_diag_funcall(MU_DIAG_ERROR,
"mu_header_aget_value_unfold", NULL, rc);
return rc;
}
#if MAILUTILS_VERSION_MAJOR > 3 || MAILUTILS_VERSION_MINOR >= 10
rc = mu_content_type_parse_ext(buf, NULL,
MU_CONTENT_TYPE_RELAXED |
MU_CONTENT_TYPE_PARAM, &ct);
#else
rc = mu_content_type_parse(buf, NULL, &ct);
#endif
if (rc) {
mu_diag_funcall(MU_DIAG_ERROR,
"mu_content_type_parse_ext", buf, rc);
free(buf);
return rc;
}
free(buf);
buf = NULL;
/* Convert the content to the requested charset. */
struct mu_mime_param *param;
if (charset && charset[0]
&& mu_assoc_lookup(ct->param, "charset", &param) == 0
&& mu_c_strcasecmp(param->value, charset)) {
char const *argv[] = { "iconv", NULL, NULL, NULL, NULL };
int argc = 1;
int rc;
argv[argc++] = param->value;
if (charset) {
argv[argc++] = charset;
if (charset_fallback)
argv[argc++] = charset_fallback;
}
rc = mfl_filter_chain_create(retflt, stream,
MU_FILTER_ENCODE,
MU_STREAM_READ,
argc, (char**) argv);
if (rc) {
//FIXME
mu_error(_("can't convert from charset %s to %s: %s"),
param->value, charset, mu_strerror (rc));
return rc;
}
} else {
mu_stream_ref(stream);
*retflt = stream;
}
mu_content_type_destroy(&ct);
return rc;
}
struct filter_closure {
mu_message_t msg;
char *errmsg;
};
static int
fltfunc(mu_stream_t *dst,
mu_stream_t src,
int mode,
int flags,
size_t argc,
char **argv,
void *closure)
{
struct filter_closure *cls = closure;
int rc = ENOSYS;
if (strcmp(argv[0], "mimedecode") == 0) {
rc = mime_decode_filter(dst, src, cls->msg);
} else if (strcmp(argv[0], "charset") == 0) {
char *charset = NULL;
char *charset_fallback = NULL;
switch (argc) {
case 3:
charset_fallback = argv[2];
case 2:
charset = argv[1];
case 1:
break;
default:
return MU_ERR_FAILURE; //FIXME: error code
}
rc = mime_charset_filter(dst, src,
cls->msg,
charset,
charset_fallback);
}
return rc;
}
static void
errfunc(int ec, char const *errmsg, char const *input, int start, int end,
void *closure)
{
struct filter_closure *cls = closure;
size_t n = 0;
cls->errmsg = NULL;
mu_asnprintf(&cls->errmsg, &n, "%s, near %.*s",
errmsg, end - start, input + start);
}
static void
free_errmsg_ptr(void *ptr)
{
free(*(void**)ptr);
}
/* string message_body_to_stream(number fd, number msg; string mu_filter_chain) */ /* string message_body_to_stream(number fd, number msg; string mu_filter_chain) */
void void
#line 694 #line 948
bi_message_body_to_stream(eval_environ_t env) bi_message_body_to_stream(eval_environ_t env)
#line 694 #line 948
#line 694 #line 948
#line 694 "msg.bi" #line 948 "msg.bi"
{ {
#line 694 #line 948
#line 694 #line 948
#line 694 #line 948
long __bi_argcnt; long __bi_argcnt;
#line 694 #line 948
long fd; long fd;
#line 694 #line 948
long nmsg; long nmsg;
#line 694 #line 948
char * fltchain; char * fltchain;
#line 694 #line 948
#line 694 #line 948
get_numeric_arg(env, 1, &fd); get_numeric_arg(env, 1, &fd);
#line 694 #line 948
get_numeric_arg(env, 2, &nmsg); get_numeric_arg(env, 2, &nmsg);
#line 694 #line 948
get_string_arg(env, 3, &fltchain); get_string_arg(env, 3, &fltchain);
#line 694 #line 948
#line 694 #line 948
get_numeric_arg(env, 0, &__bi_argcnt); get_numeric_arg(env, 0, &__bi_argcnt);
#line 694 #line 948
adjust_stack(env, __bi_argcnt + 1); adjust_stack(env, __bi_argcnt + 1);
#line 694 #line 948
#line 694 #line 948
#line 694 #line 948
if (builtin_module_trace(BUILTIN_IDX_msg)) if (builtin_module_trace(BUILTIN_IDX_msg))
#line 694 #line 948
prog_trace(env, "message_body_to_stream %lu %lu %s",fd, nmsg, ((_ _bi_argcnt > 2) ? fltchain : ""));; prog_trace(env, "message_body_to_stream %lu %lu %s",fd, nmsg, ((_ _bi_argcnt > 2) ? fltchain : ""));;
{ {
int rc; int rc;
int yes = 1; int yes = 1;
mu_stream_t dst; mu_stream_t dst;
mu_stream_t src = NULL;
char *flts = ((__bi_argcnt > 2) ? fltchain : 0); char *flts = ((__bi_argcnt > 2) ? fltchain : 0);
#line 702 #line 957
#line 702 #line 957
struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id); struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 702 #line 957
struct mf_message *mp; struct mf_message *mp;
#line 702 #line 957
#line 702 #line 957
if (!(nmsg >= 0 && nmsg < nmsgs)) if (!(nmsg >= 0 && nmsg < nmsgs))
#line 702 #line 957
( (
#line 702 #line 957
env_throw_bi(env, mfe_range, "message_body_to_stream", _("invalid message descriptor")) env_throw_bi(env, mfe_range, "message_body_to_stream", _("invalid message descriptor"))
#line 702 #line 957
) )
#line 702 #line 957
; ;
#line 702 #line 957
mp = mtab + nmsg; mp = mtab + nmsg;
#line 702 #line 957
if (!(mp->msg)) if (!(mp->msg))
#line 702 #line 957
( (
#line 702 #line 957
env_throw_bi(env, mfe_failure, "message_body_to_stream", _("message not o pen")) env_throw_bi(env, mfe_failure, "message_body_to_stream", _("message not o pen"))
#line 702 #line 957
) )
#line 702 #line 957
#line 702 #line 957
; ;
#line 702 #line 957
if (!mp->body) { if (!mp->body) {
#line 702 #line 957
int rc = mu_message_get_body(mp->msg, &mp->body); int rc = mu_message_get_body(mp->msg, &mp->body);
#line 702 #line 957
if (!(rc == 0)) if (!(rc == 0))
#line 702 #line 957
( (
#line 702 #line 957
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_message_get_ body: %s",mu_strerror(rc)) env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_message_get_ body: %s",mu_strerror(rc))
#line 702 #line 957
)
#line 957
;
#line 957
}
#line 957
if (!mp->hdr) {
#line 957
int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 957
if (!(rc == 0))
#line 957
(
#line 957
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_message_get_
header: %s",mu_strerror(rc))
#line 957
) )
#line 702 #line 957
; ;
#line 702 #line 957
} }
#line 702 #line 957
; ;
rc = mu_fd_stream_create(&dst, NULL, _bi_io_fd(env, fd, 1), rc = mu_fd_stream_create(&dst, NULL, _bi_io_fd(env, fd, 1),
MU_STREAM_WRITE); MU_STREAM_WRITE);
if (!(rc == 0)) if (!(rc == 0))
#line 706 #line 961
( (
#line 706 #line 961
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_fd_stream_cr eate: %s",mu_strerror(rc)) env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_fd_stream_cr eate: %s",mu_strerror(rc))
#line 706 #line 961
) )
#line 709 #line 964
; ;
mu_stream_ioctl(dst, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes); mu_stream_ioctl(dst, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
env_function_cleanup_add(env, dst, _builtin_stream_cleanup);
rc = mu_body_get_streamref(mp->body, &src);
if (!(rc == 0))
#line 969
(
#line 969
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_body_get_str
eamref: %s",mu_strerror(rc))
#line 969
)
#line 972
;
if (flts) { if (flts) {
struct mu_wordsplit ws;
mu_stream_t flt; mu_stream_t flt;
struct filter_closure cls;
cls.msg = mp->msg;
cls.errmsg = NULL;
env_function_cleanup_add(env, &cls.errmsg, free_errmsg_ptr);
rc = mfl_filter_pipe_create(&flt, src,
MU_FILTER_ENCODE,
MU_STREAM_READ,
flts,
fltfunc,
errfunc,
&cls);
mu_stream_unref(src);
if (rc == 0) {
src = flt;
} else {
(
#line 993
env_throw_bi(env, mfe_failure, "message_body_to_stream", cls.errmsg)
#line 993
);
}
}
rc = mu_wordsplit(flts, &ws, MU_WRDSF_DEFFLAGS); rc = mu_stream_copy(dst, src, 0, NULL);
if (!(rc == 0))
#line 716 mu_stream_unref(src);
switch (rc) {
case 0:
break;
case EILSEQ:
( (
#line 716 #line 1006
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_wordsplit: % env_throw_bi(env, mfe_ilseq, "message_body_to_stream", "illegal byte sequ
s",mu_wordsplit_strerror(&ws)) ence")
#line 716 #line 1006
);
#line 1008
break;
default:
(
#line 1011
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_stream_copy:
%s",mu_strerror(rc))
#line 1011
);
#line 1014
}
}
#line 1016
env_function_cleanup_flush(env, NULL);
#line 1016
return;
#line 1016
}
void
#line 1018
bi_message_content_type(eval_environ_t env)
#line 1018
#line 1018
#line 1018 "msg.bi"
{
#line 1018
#line 1018
#line 1018
#line 1018
long nmsg;
#line 1018
#line 1018
get_numeric_arg(env, 0, &nmsg);
#line 1018
#line 1018
#line 1018
adjust_stack(env, 1);
#line 1018
#line 1018
#line 1018
if (builtin_module_trace(BUILTIN_IDX_msg))
#line 1018
prog_trace(env, "message_content_type %lu",nmsg);;
#line 1018
{
int rc;
char *buf;
mu_content_type_t ct;
#line 1023
#line 1023
struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 1023
struct mf_message *mp;
#line 1023
#line 1023
if (!(nmsg >= 0 && nmsg < nmsgs))
#line 1023
(
#line 1023
env_throw_bi(env, mfe_range, "message_content_type", _("invalid message d
escriptor"))
#line 1023
) )
#line 719 #line 1023
; ;
rc = mu_filter_chain_create(&flt, dst, MU_FILTER_ENCODE, #line 1023
MU_STREAM_WRITE, mp = mtab + nmsg;
ws.ws_wordc, ws.ws_wordv); #line 1023
mu_wordsplit_free(&ws); if (!(mp->msg))
if (!(rc == 0)) #line 1023
#line 724
( (
#line 724 #line 1023
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_filter_chain env_throw_bi(env, mfe_failure, "message_content_type", _("message not ope
_create(\"%s\"): %s",flts,mu_strerror(rc)) n"))
#line 724 #line 1023
) )
#line 728 #line 1023
;
mu_stream_unref(dst);
dst = flt;
}
if (!mp->bstr) { #line 1023
rc = mu_body_get_streamref(mp->body, &mp->bstr); ;
#line 1023
if (!mp->hdr) {
#line 1023
int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 1023
if (!(rc == 0)) if (!(rc == 0))
#line 735 #line 1023
( (
#line 735 #line 1023
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_body_get_str env_throw_bi(env, mfe_failure, "message_content_type", "mu_message_get_he
eam: %s",mu_strerror(rc)) ader: %s",mu_strerror(rc))
#line 735 #line 1023
) )
#line 738 #line 1023
; ;
#line 1023
}
#line 1023
;
rc = mu_header_aget_value_unfold(mp->hdr, MU_HEADER_CONTENT_TYPE, &buf);
switch (rc) {
case 0:
break;
case MU_ERR_NOENT:
#line 1031
do {
#line 1031
pushs(env, "text/plain");
#line 1031
goto endlab;
#line 1031
} while (0);
default:
(
#line 1034
env_throw_bi(env, mfe_failure, "message_content_type", "mu_header_aget_va
lue_unfold: %s",mu_strerror(rc))
#line 1034
);
#line 1037
} }
rc = mu_stream_copy(dst, mp->bstr, 0, NULL);
#if MAILUTILS_VERSION_MAJOR > 3 || MAILUTILS_VERSION_MINOR >= 10
rc = mu_content_type_parse_ext(buf, NULL,
MU_CONTENT_TYPE_RELAXED |
MU_CONTENT_TYPE_PARAM, &ct);
#else
rc = mu_content_type_parse(buf, NULL, &ct);
#endif
free(buf);
if (!(rc == 0)) if (!(rc == 0))
#line 741 #line 1047
( (
#line 741 #line 1047
env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_stream_copy: env_throw_bi(env, mfe_failure, "message_content_type", "mu_content_type_p
%s",mu_strerror(rc)) arse_ext: %s",mu_strerror(rc))
#line 741 #line 1047
) )
#line 744 #line 1049
; ;
mu_stream_close(dst);
mu_stream_unref(dst);
}
#line 748 heap_obstack_begin(env);
#line 1052
do {
#line 1052
char *__s = ct->type;
#line 1052
heap_obstack_grow(env, __s, strlen(__s));
#line 1052
} while (0);
do { char __c = '/'; heap_obstack_grow(env, &__c, 1); } while(0);
#line 1054
do {
#line 1054
char *__s = ct->subtype;
#line 1054
heap_obstack_grow(env, __s, strlen(__s));
#line 1054
} while (0);
mu_content_type_destroy(&ct);
do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0);
#line 1057
do {
#line 1057
push(env, (STKVAL) (heap_obstack_finish(env)));
#line 1057
goto endlab;
#line 1057
} while (0);
}
endlab:
#line 1059
env_function_cleanup_flush(env, NULL); env_function_cleanup_flush(env, NULL);
#line 748 #line 1059
return; return;
#line 748 #line 1059
} }
#line 982 "../../src/builtin/snarf.m4" #line 982 "../../src/builtin/snarf.m4"
#line 982 #line 982
#line 982 #line 982
#line 982 #line 982
void void
skipping to change at line 3135 skipping to change at line 3592
#line 523 "msg.bi" #line 523 "msg.bi"
va_builtin_install_ex("message_read_line", bi_message_read_line, 0, dtype_string , 1, 0, 0|0, dtype_number); va_builtin_install_ex("message_read_line", bi_message_read_line, 0, dtype_string , 1, 0, 0|0, dtype_number);
#line 550 "msg.bi" #line 550 "msg.bi"
va_builtin_install_ex("message_body_rewind", bi_message_body_rewind, 0, dtype_un specified, 1, 0, 0|0, dtype_number); va_builtin_install_ex("message_body_rewind", bi_message_body_rewind, 0, dtype_un specified, 1, 0, 0|0, dtype_number);
#line 558 "msg.bi" #line 558 "msg.bi"
va_builtin_install_ex("message_read_body_line", bi_message_read_body_line, 0, dt ype_string, 1, 0, 0|0, dtype_number); va_builtin_install_ex("message_read_body_line", bi_message_read_body_line, 0, dt ype_string, 1, 0, 0|0, dtype_number);
#line 585 "msg.bi" #line 585 "msg.bi"
va_builtin_install_ex("message_to_stream", bi_message_to_stream, 0, dtype_unspec ified, 3, 1, 0|0, dtype_number, dtype_number, dtype_string); va_builtin_install_ex("message_to_stream", bi_message_to_stream, 0, dtype_unspec ified, 3, 1, 0|0, dtype_number, dtype_number, dtype_string);
#line 642 "msg.bi" #line 642 "msg.bi"
va_builtin_install_ex("message_from_stream", bi_message_from_stream, 0, dtype_nu mber, 2, 1, 0|0, dtype_number, dtype_string); va_builtin_install_ex("message_from_stream", bi_message_from_stream, 0, dtype_nu mber, 2, 1, 0|0, dtype_number, dtype_string);
#line 694 "msg.bi" #line 948 "msg.bi"
va_builtin_install_ex("message_body_to_stream", bi_message_body_to_stream, 0, dt ype_unspecified, 3, 1, 0|0, dtype_number, dtype_number, dtype_string); va_builtin_install_ex("message_body_to_stream", bi_message_body_to_stream, 0, dt ype_unspecified, 3, 1, 0|0, dtype_number, dtype_number, dtype_string);
#line 1018 "msg.bi"
va_builtin_install_ex("message_content_type", bi_message_content_type, 0, dtype_
string, 1, 0, 0|0, dtype_number);
#line 982 "../../src/builtin/snarf.m4" #line 982 "../../src/builtin/snarf.m4"
#line 982 #line 982
mf_add_runtime_params(msg_cfg_param); mf_add_runtime_params(msg_cfg_param);
#line 982 #line 982
#line 982 #line 982
} }
#line 982 "../../src/builtin/snarf.m4" #line 982 "../../src/builtin/snarf.m4"
 End of changes. 76 change blocks. 
96 lines changed or deleted 564 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)