#include "mod_perl.h" #include "mod_perl_xs.h" #if MODULE_MAGIC_NUMBER >= MMN_132 #define HAVE_LOG_RERROR 1 #else #define HAVE_LOG_RERROR 0 #endif static void perl_cv_alias(char *to, char *from) { GV *gp = gv_fetchpv(to, TRUE, SVt_PVCV); GvCV(gp) = perl_get_cv(from, TRUE); } static void ApacheLog(int level, SV *sv, SV *msg) { dTHR; char *file = NULL; int line = 0; char *str; SV *svstr = Nullsv; int lmask = level & APLOG_LEVELMASK; server_rec *s; request_rec *r = NULL; if(sv_isa(sv, "Apache::Log::Request") && SvROK(sv)) { r = (request_rec *) SvIV((SV*)SvRV(sv)); s = r->server; } else if(sv_isa(sv, "Apache::Log::Server") && SvROK(sv)) { s = (server_rec *) SvIV((SV*)SvRV(sv)); } else { croak("Argument is not an Apache or Apache::Server object"); } if((lmask == APLOG_DEBUG) && (s->loglevel >= APLOG_DEBUG)) { SV *caller; bool old_T = tainting; tainting = FALSE; caller = perl_eval_pv("[ (caller)[1,2] ]", TRUE); tainting = old_T; file = SvPV(*av_fetch((AV *)SvRV(caller), 0, FALSE),na); line = (int)SvIV(*av_fetch((AV *)SvRV(caller), 1, FALSE)); } if((s->loglevel >= lmask) && SvROK(msg) && (SvTYPE(SvRV(msg)) == SVt_PVCV)) { dSP; ENTER;SAVETMPS; PUSHMARK(sp); (void)perl_call_sv(msg, G_SCALAR); SPAGAIN; svstr = POPs; ++SvREFCNT(svstr); PUTBACK; FREETMPS;LEAVE; str = SvPV(svstr,na); } else str = SvPV(msg,na); if(r && HAVE_LOG_RERROR) { #if HAVE_LOG_RERROR > 0 ap_log_rerror(file, line, APLOG_NOERRNO|level, r, "%s", str); #endif } else { ap_log_error(file, line, APLOG_NOERRNO|level, s, "%s", str); } SvREFCNT_dec(msg); if(svstr) SvREFCNT_dec(svstr); } #define join_stack_msg \ SV *msgstr; \ if(items > 2) { \ msgstr = newSV(0); \ do_join(msgstr, &sv_no, MARK+1, SP); \ } \ else { \ msgstr = ST(1); \ ++SvREFCNT(msgstr); \ } #define MP_AP_LOG(l,s) \ { \ join_stack_msg; \ ApacheLog(l, s, msgstr); \ } #define Apache_log_emerg(s) \ MP_AP_LOG(APLOG_EMERG, s) #define Apache_log_alert(s) \ MP_AP_LOG(APLOG_ALERT, s) #define Apache_log_crit(s) \ MP_AP_LOG(APLOG_CRIT, s) #define Apache_log_error(s) \ MP_AP_LOG(APLOG_ERR, s) #define Apache_log_warn(s) \ MP_AP_LOG(APLOG_WARNING, s) #define Apache_log_notice(s) \ MP_AP_LOG(APLOG_NOTICE, s) #define Apache_log_info(s) \ MP_AP_LOG(APLOG_INFO, s) #define Apache_log_debug(s) \ MP_AP_LOG(APLOG_DEBUG, s) MODULE = Apache::Log PACKAGE = Apache PROTOTYPES: DISABLE BOOT: perl_cv_alias("Apache::log", "Apache::Log::log"); perl_cv_alias("Apache::Server::log", "Apache::Log::log"); perl_cv_alias("emergency", "emerg"); perl_cv_alias("critical", "crit"); av_push(perl_get_av("Apache::Log::Request::ISA",TRUE), newSVpv("Apache::Log",11)); av_push(perl_get_av("Apache::Log::Server::ISA",TRUE), newSVpv("Apache::Log",11)); items = items; /*avoid warning*/ MODULE = Apache::Log PACKAGE = Apache::Log PREFIX=Apache_log_ void Apache_log_log(sv) SV *sv PREINIT: void *retval; char *pclass = "Apache::Log::Request"; CODE: if(!SvROK(sv)) croak("Argument is not a reference"); if(sv_derived_from(sv, "Apache")) { retval = (void*)sv2request_rec(sv, "Apache", cv); } else if(sv_derived_from(sv, "Apache::Server")) { pclass = "Apache::Log::Server"; retval = (void *) SvIV((SV*)SvRV(sv)); } else { croak("Argument is not an Apache or Apache::Server object"); } ST(0) = sv_newmortal(); sv_setref_pv(ST(0), pclass, (void*)retval); void Apache_log_emerg(s, ...) SV *s void Apache_log_alert(s, ...) SV *s void Apache_log_crit(s, ...) SV *s void Apache_log_error(s, ...) SV *s void Apache_log_warn(s, ...) SV *s void Apache_log_notice(s, ...) SV *s void Apache_log_info(s, ...) SV *s void Apache_log_debug(s, ...) SV *s MODULE = Apache::Log PACKAGE = Apache::Server PROTOTYPES: DISABLE BOOT: #ifdef newCONSTSUB { HV *stash = gv_stashpv("Apache::Log", TRUE); newCONSTSUB(stash, "EMERG", newSViv(APLOG_EMERG)); newCONSTSUB(stash, "ALERT", newSViv(APLOG_ALERT)); newCONSTSUB(stash, "CRIT", newSViv(APLOG_CRIT)); newCONSTSUB(stash, "ERR", newSViv(APLOG_ERR)); newCONSTSUB(stash, "WARNING", newSViv(APLOG_WARNING)); newCONSTSUB(stash, "NOTICE", newSViv(APLOG_NOTICE)); newCONSTSUB(stash, "INFO", newSViv(APLOG_INFO)); newCONSTSUB(stash, "DEBUG", newSViv(APLOG_DEBUG)); } #endif int loglevel(server, ...) Apache::Server server CODE: get_set_IV(server->loglevel); OUTPUT: RETVAL