+
+ /* check cache */
+ if ((DT->dircache.clim < 1) || (!(path = domaintree_cache_get(DT, r->request_time, host)))) {
+ /* build path */
+ if (!(path = domaintree_path(r->pool, DT, host))) {
+ return DECLINED;
+ }
+
+ /* apply any aliases */
+ if (apr_table_elts(DT->aliases.faketable)->nelts) {
+ domaintree_fake(r->pool, DT, &path);
+ }
+
+ /* add to cache */
+ if (DT->dircache.clim > 0) {
+ domaintree_cache_set(DT, r->request_time, host, path);
+ }
+ }
+
+ /* compose virtual docroot */
+ docroot = struniqchr(apr_pstrcat(r->pool, DT->prefix, "/", path, "/", DT->suffix, "/", NULL), '/');
+
+ /* stat docroot */
+ if (DT->statroot > 0) {
+ apr_finfo_t sb;
+
+ switch (apr_stat(&sb, docroot, APR_FINFO_MIN, r->pool)) {
+ case APR_SUCCESS:
+ case APR_INCOMPLETE:
+ ap_log_error(DT_LOG_DBG "stat path = %s (success)", docroot);
+ break;
+
+ default:
+ ap_log_error(DT_LOG_DBG "stat path = %s (failure)", docroot);
+ return DECLINED;
+ }
+ }
+
+ /* set virtual docroot */
+ apr_table_set(r->subprocess_env, "VIRTUAL_DOCUMENT_ROOT", docroot);
+
+#ifdef HAVE_UNIX_SUEXEC
+ /* set suexec note */
+ {
+ const char *username, *separator;
+
+ if (domaintree_test(DT, docroot, DT->suexec->nelts, DT->suexec->elts, TEST_IS_BOS, NULL, &username)) {
+ if ((separator = strchr(username, '/'))) {
+ username = apr_pstrndup(r->pool, username, separator-username);
+ } else {
+ username = apr_pstrdup(r->pool, username);
+ }
+ apr_table_setn(r->notes, "mod_domaintree.suexec", username);
+ }
+ }
+#endif
+