Apache2-ModLogConfig

 view release on metacpan or  search on metacpan

ModLogConfig.xs  view on Meta::CPAN


  /* fetch/init per-server hash */
  shash=apr_hash_get(ghash, &s, sizeof(s));
  if( !shash ) {
    shash=apr_hash_make(pconf);
    apr_hash_set(ghash, apr_pmemdup(pconf, &s, sizeof(s)), sizeof(s), shash);
  }

  apr_hash_set(shash, w->name, strlen(w->name), w);

  return w;
}

static apr_status_t
writer(request_rec *r, void *handle, const char **strs,
       int *strl, int nelts, apr_size_t len)
{
  writer_t *w=handle;

  switch(w->type) {
  case 0:
    return old_writer(r, w->handle, strs, strl, nelts, len);
  case 1:
    {
      int status, i;
      MP_dTHX;
      AV *av=newAV();

      av_extend(av, nelts);
      av_store(av, 0, modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r));
      for(i=0; i<nelts; i++) av_store(av, i+1, newSVpvn(strs[i], strl[i]));

      if((status=modperl_callback(aTHX_ w->handle, r->pool, r,
				  r->server, av))!=OK) {
	modperl_errsv(aTHX_ status, r, r->server);
      }

      SvREFCNT_dec(av);

      MP_uTHX;
    }
    return OK;
  }

  return OK;
}

static const char*
log_perl(request_rec *r, char *a)
{
  if( a && *a ) {
    I32 count;
    MP_dTHX;
    dSP;
    SV *sv;

    ENTER; SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(sv_2mortal(modperl_ptr2obj(aTHX_ "Apache2::RequestRec", r)));

    PUTBACK;
    count=call_pv(a, G_SCALAR|G_EVAL);
    SPAGAIN;

    if( SvTRUE(ERRSV) ) {
      (void)POPs;		/* G_SCALAR leaves exactly one value:
				 * undef here */
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
		    "'%s' log format handler died: %s",
		    HND_KEY, SvPVX(ERRSV));
      a="";
    } else if( count==1 ) {
      STRLEN len;
      sv=POPs;
      a=SvPVbyte(sv, len);
      a=apr_pstrmemdup(r->pool, a, len);
    } else {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
		    "'%s' log format handler died: internal error - "
		    "multiple return values (must not happen)", HND_KEY);
      while( count-- ) (void)POPs;
    }

    PUTBACK;
    FREETMPS; LEAVE;

    MP_uTHX;
    return a;
  } else {
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
		  "invalid empty function in '%s' log format specification",
		  HND_KEY);
    return "";
  }
}

struct writer_pair {
  ap_log_writer_init *wi;
  ap_log_writer *w;
};

# define VER(a,b,c) (1000000*(a)+1000*(b)+c)
# define AP_VER VER(AP_SERVER_MAJORVERSION_NUMBER,  \
		    AP_SERVER_MINORVERSION_NUMBER,  \
		    AP_SERVER_PATCHLEVEL_NUMBER)

static int
openlogs(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
  APR_OPTIONAL_FN_TYPE(ap_log_set_writer_init) *set_writer_init;
  APR_OPTIONAL_FN_TYPE(ap_log_set_writer) *set_writer;

  set_writer_init = APR_RETRIEVE_OPTIONAL_FN(ap_log_set_writer_init);
  set_writer      = APR_RETRIEVE_OPTIONAL_FN(ap_log_set_writer);

  if( !set_writer_init || !set_writer ) {
    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
		 "ap_log_set_writer_init() or ap_log_set_writer() not found, "
		 "you have probably loaded a wrong mod_log_config");
    return DECLINED;
  }

  W("V=%d", AP_VER);

# if AP_VER <= 2002017

  /* We cannot rely here on apache cleaning up properly on restart.
   * Unfortunately there is a bug at least up to httpd 2.2.17 that prevents
   * the writer_init() and writer() values in mod_log_config to be
   * reinitialized to the default values when compiled statically in. So, it
   * may happen here that set_writer_init() returns our writer_init instead
   * of mod_log_config's.
   *
   *   see also https://issues.apache.org/bugzilla/show_bug.cgi?id=50861
   *
   * Further, there is no way to store the values in global variables
   * here because the shared lib is unloaded during restart and hence all
   * globals are reset.
   *
   * To solve the problem we store the original values as userdata in the
   * process pool. Fortunately, that one is accessible here. */

  {
    ap_module_symbol_t *mod;



( run in 0.959 second using v1.01-cache-2.11-cpan-39bf76dae61 )