1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 1999 - 2022 */
6 /* Copyright (c) 1998 Malcolm Beattie */
7 /* SPDX-License-Identifier: GPL-2.0-or-later */
9 /* Modified by PH to get rid of the "na" usage, March 1999.
10 Modified further by PH for general tidying for Exim 4.
11 Threaded Perl support added by Stefan Traby, Nov 2002
15 /* This Perl add-on can be distributed under the same terms as Exim itself. */
16 /* See the file NOTICE for conditions of use and distribution. */
25 #define EXIM_TRUE TRUE
28 #define EXIM_FALSE FALSE
31 #define EXIM_DEBUG DEBUG
39 #define ERRSV (GvSV(errgv))
42 /* Some people like very old perl versions, so avoid any build side-effects. */
49 # define EXTERN_C extern
52 EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
55 static PerlInterpreter *interp_perl = 0;
64 croak("Usage: Exim::expand_string(string)");
66 str = expand_string(US SvPV(ST(0), len));
67 ST(0) = sv_newmortal();
69 sv_setpv(ST(0), CCS str);
70 else if (!f.expand_string_forcedfail)
71 croak("syntax error in Exim::expand_string argument: %s",
72 expand_string_message);
80 croak("Usage: Exim::debug_write(string)");
81 debug_printf("%s", US SvPV(ST(0), len));
89 croak("Usage: Exim::log_write(string)");
90 log_write(0, LOG_MAIN, "%s", US SvPV(ST(0), len));
93 static void xs_init(pTHX)
95 char *file = __FILE__;
96 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
97 newXS("Exim::expand_string", xs_expand_string, file);
98 newXS("Exim::debug_write", xs_debug_write, file);
99 newXS("Exim::log_write", xs_log_write, file);
103 init_perl(uschar *startup_code)
106 static char *argv[4] = { "exim-perl" };
110 if (opt_perl_taintmode) argv[argc++] = "-T";
111 argv[argc++] = "/dev/null";
114 assert(sizeof(argv)/sizeof(argv[0]) > argc);
116 if (interp_perl) return 0;
117 interp_perl = perl_alloc();
118 perl_construct(interp_perl);
119 perl_parse(interp_perl, xs_init, argc, argv, 0);
120 perl_run(interp_perl);
124 /*********************************************************************/
125 /* These lines by PH added to make "warn" output go to the Exim log; I
126 hope this doesn't break anything. */
129 "$SIG{__WARN__} = sub { my($s) = $_[0];"
131 "Exim::log_write($s) };", 0);
133 perl_eval_sv(sv, G_SCALAR|G_DISCARD|G_KEEPERR);
135 if (SvTRUE(ERRSV)) return US SvPV(ERRSV, len);
136 /*********************************************************************/
138 sv = newSVpv(CS startup_code, 0);
140 perl_eval_sv(sv, G_SCALAR|G_DISCARD|G_KEEPERR);
142 if (SvTRUE(ERRSV)) return US SvPV(ERRSV, len);
144 setlocale(LC_ALL, "C"); /* In case it got changed */
155 perl_destruct(interp_perl);
156 perl_free(interp_perl);
162 call_perl_cat(gstring * yield, uschar **errstrp, uschar *name, uschar **arg)
172 *errstrp = US"the Perl interpreter has not been started";
179 while (*arg != NULL) XPUSHs(newSVpv(CS (*arg++), 0));
181 items = perl_call_pv(CS name, G_SCALAR|G_EVAL);
187 *errstrp = US SvPV(ERRSV, len);
195 str = US SvPV(sv, len);
196 yield = string_catn(yield, str, (int)len);
200 setlocale(LC_ALL, "C"); /* In case it got changed */
207 /******************************************************************************/
210 static void * perl_functions[] = {
211 [PERL_STARTUP] = init_perl,
212 [PERL_CAT] = call_perl_cat,
215 misc_module_info perl_module_info =
219 .dyn_magic = MISC_MODULE_MAGIC,
222 .functions = perl_functions,
223 .functions_count = nelem(perl_functions),