1 /* $Cambridge: exim/src/src/perl.c,v 1.5 2006/07/14 14:32:09 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) 1998 Malcolm Beattie */
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. */
20 #define EXIM_TRUE TRUE
23 #define EXIM_FALSE FALSE
26 #define EXIM_DEBUG DEBUG
34 #define ERRSV (GvSV(errgv))
37 /* Some people like very old perl versions, so avoid any build side-effects. */
44 # define EXTERN_C extern
47 EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
50 static PerlInterpreter *interp_perl = 0;
59 croak("Usage: Exim::expand_string(string)");
61 str = expand_string(US SvPV(ST(0), len));
62 ST(0) = sv_newmortal();
64 sv_setpv(ST(0), (const char *) str);
65 else if (!expand_string_forcedfail)
66 croak("syntax error in Exim::expand_string argument: %s",
67 expand_string_message);
75 croak("Usage: Exim::debug_write(string)");
76 debug_printf("%s", US SvPV(ST(0), len));
84 croak("Usage: Exim::log_write(string)");
85 log_write(0, LOG_MAIN, "%s", US SvPV(ST(0), len));
88 static void xs_init(pTHX)
90 char *file = __FILE__;
91 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
92 newXS("Exim::expand_string", xs_expand_string, file);
93 newXS("Exim::debug_write", xs_debug_write, file);
94 newXS("Exim::log_write", xs_log_write, file);
98 init_perl(uschar *startup_code)
101 static char *argv[3] = { "exim-perl", "/dev/null", 0 };
105 if (interp_perl) return 0;
106 interp_perl = perl_alloc();
107 perl_construct(interp_perl);
108 perl_parse(interp_perl, xs_init, argc, argv, 0);
109 perl_run(interp_perl);
113 /*********************************************************************/
114 /* These lines by PH added to make "warn" output go to the Exim log; I
115 hope this doesn't break anything. */
118 "$SIG{__WARN__} = sub { my($s) = $_[0];"
120 "Exim::log_write($s) };", 0);
122 perl_eval_sv(sv, G_SCALAR|G_DISCARD|G_KEEPERR);
124 if (SvTRUE(ERRSV)) return US SvPV(ERRSV, len);
125 /*********************************************************************/
127 sv = newSVpv(CS startup_code, 0);
129 perl_eval_sv(sv, G_SCALAR|G_DISCARD|G_KEEPERR);
131 if (SvTRUE(ERRSV)) return US SvPV(ERRSV, len);
133 setlocale(LC_ALL, "C"); /* In case it got changed */
143 perl_destruct(interp_perl);
144 perl_free(interp_perl);
149 call_perl_cat(uschar *yield, int *sizep, int *ptrp, uschar **errstrp,
150 uschar *name, uschar **arg)
160 *errstrp = US"the Perl interpreter has not been started";
167 while (*arg != NULL) XPUSHs(newSVpv(CS (*arg++), 0));
169 items = perl_call_pv(CS name, G_SCALAR|G_EVAL);
175 *errstrp = US SvPV(ERRSV, len);
183 str = US SvPV(sv, len);
184 yield = string_cat(yield, sizep, ptrp, str, (int)len);
188 setlocale(LC_ALL, "C"); /* In case it got changed */