コード例 #1
0
static int printitem(void* rec, const char* key, const char* value) {
    /* rec is a userdata pointer.  We'll pass the request_rec in it */
    request_rec* r = rec ;
    ap_rprintf(r, "<tr><th scope=\"row\">%s</th><td>%s</td></tr>\n",
        ap_escape_html(r->pool, key), ap_escape_html(r->pool, value)) ;
    /* Zero would stop iterating; any other return value continues */
    return 1 ;
    }
コード例 #2
0
ファイル: html.c プロジェクト: monnerat/mod_badge
static void
badge_emit_text(request_rec * r, const char * label, const char * value,
	int rdonly, const char * name, int pwflg, int errflg)

{
	/**
	***	Generate the given text value as an html table row, either
	***		as normal text or as an input field according to
	***		the `rdonly' flag.
	**/

	if (!value)
		value = "";
	else
		value = ap_escape_html(r->pool, value);

	ap_rvputs(r, "<tr><td>", label, "</td><td", badge_arg_err(errflg),
	    ">", NULL);

	if (rdonly)
		ap_rvputs(r, value, "</td></tr>\n", NULL);
	else
		ap_rvputs(r, "<input type=\"", pwflg? "password": "******",
		    "\" name=\"", name, "\" value=\"", value,
		    "\" /></td></tr>\n", NULL);
}
コード例 #3
0
ファイル: log.c プロジェクト: wsIThp/xiaoxin-project
AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level,
                               apr_status_t status, const request_rec *r,
                               const char *fmt, ...)
{
    va_list args;

    va_start(args, fmt);
    log_error_core(file, line, level, status, r->server, NULL, r, NULL, fmt,
                   args);

    /*
     * IF APLOG_TOCLIENT is set,
     * AND the error level is 'warning' or more severe,
     * AND there isn't already error text associated with this request,
     * THEN make the message text available to ErrorDocument and
     * other error processors.
     */
    va_end(args);
    va_start(args,fmt);
    if ((level & APLOG_TOCLIENT)
        && ((level & APLOG_LEVELMASK) <= APLOG_WARNING)
        && (apr_table_get(r->notes, "error-notes") == NULL)) {
        apr_table_setn(r->notes, "error-notes",
                       ap_escape_html(r->pool, apr_pvsprintf(r->pool, fmt,
                                                             args)));
    }
    va_end(args);
}
コード例 #4
0
ファイル: html.c プロジェクト: monnerat/mod_badge
static void
badge_emit_timestamp(request_rec * r, const char * fromto, time_t value,
	int rdonly, badge_timestamp * ts, int errflags, int yearerr,
	int montherr, int dayerr, int hourerr, int minerr, int secerr)

{
	apr_time_exp_t exptime;
	apr_time_t aprtime;
	apr_size_t len;
	char buf[100];

	/**
	***	Emit a timestamp in an html table row, either as normal text
	***		from `value' or as input fields with values from `*ts'
	***		according to the `rdonly' flag.
	**/

	ap_rvputs(r, "<tr><td>Valid ", fromto, "</td><td>", NULL);

	if (rdonly) {
		apr_time_ansi_put(&aprtime, value);
		apr_time_exp_tz(&exptime, aprtime, 0);
		apr_strftime(buf, &len, sizeof buf - 1, "%c", &exptime);
		buf[len] = '\0';
		ap_rvputs(r, ap_escape_html(r->pool, buf), NULL);
		}
	else {
		ap_rvputs(r, "Y<input type=\"text\" name=\"", fromto,
		    "-year\" value=\"",
		    ts->year? ap_escape_html(r->pool, ts->year): "",
		    "\"", badge_arg_err(errflags & yearerr), " />", NULL);
		badge_emit_range_select(r, "M", fromto,
		    "month", 1, 12, ts->month, errflags & montherr);
		badge_emit_range_select(r, "D", fromto,
		    "day", 1, 31, ts->day, errflags & dayerr);
		badge_emit_range_select(r, "H", fromto,
		    "hour", 0, 23, ts->hour, errflags & hourerr);
		badge_emit_range_select(r, "M", fromto,
		    "min", 0, 59, ts->min, errflags & minerr);
		badge_emit_range_select(r, "S", fromto,
		    "sec", 0, 59, ts->sec, errflags & secerr);
		}

	ap_rvputs(r, "</td></tr>\n", NULL);
}
コード例 #5
0
/*============================================================================
 *============================================================================
 * This is the beginning of the cgi filter code moved from mod_include. This
 *   is the code required to handle the "exec" SSI directive.
 *============================================================================
 *============================================================================*/
static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f,
                                apr_bucket_brigade *bb, char *s)
{
    request_rec *r = f->r;
    request_rec *rr = ap_sub_req_lookup_uri(s, r, f->next);
    int rr_status;

    if (rr->status != HTTP_OK) {
        ap_destroy_sub_req(rr);
        return APR_EGENERAL;
    }

    /* No hardwired path info or query allowed */
    if ((rr->path_info && rr->path_info[0]) || rr->args) {
        ap_destroy_sub_req(rr);
        return APR_EGENERAL;
    }
    if (rr->finfo.filetype != APR_REG) {
        ap_destroy_sub_req(rr);
        return APR_EGENERAL;
    }

    /* Script gets parameters of the *document*, for back compatibility */
    rr->path_info = r->path_info;       /* hard to get right; see mod_cgi.c */
    rr->args = r->args;

    /* Force sub_req to be treated as a CGI request, even if ordinary
     * typing rules would have called it something else.
     */
    ap_set_content_type(rr, CGI_MAGIC_TYPE);

    /* Run it. */
    rr_status = ap_run_sub_req(rr);
    if (ap_is_HTTP_REDIRECT(rr_status)) {
        const char *location = apr_table_get(rr->headers_out, "Location");

        if (location) {
            char *buffer;

            location = ap_escape_html(rr->pool, location);
            buffer = apr_pstrcat(ctx->pool, "<a href=\"", location, "\">",
                                 location, "</a>", NULL);

            APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(buffer,
                                    strlen(buffer), ctx->pool,
                                    f->c->bucket_alloc));
        }
    }

    ap_destroy_sub_req(rr);

    return APR_SUCCESS;
}
コード例 #6
0
ファイル: status.c プロジェクト: svn2github/subversion
/* A bit like mod_status: add a location:

     <Location /svn-status>
       SetHandler svn-status
     </Location>

  and then point a browser at http://server/svn-status.
*/
int dav_svn__status(request_rec *r)
{
  svn_cache__info_t *info;
  svn_string_t *text_stats;
  apr_array_header_t *lines;
  int i;

  if (r->method_number != M_GET || strcmp(r->handler, "svn-status"))
    return DECLINED;

  info = svn_cache__membuffer_get_global_info(r->pool);
  text_stats = svn_cache__format_info(info, FALSE, r->pool);
  lines = svn_cstring_split(text_stats->data, "\n", FALSE, r->pool);

  ap_set_content_type(r, "text/html; charset=ISO-8859-1");

  ap_rvputs(r,
            DOCTYPE_HTML_3_2
            "<html><head>\n"
            "<title>Apache SVN Status</title>\n"
            "</head><body>\n"
            "<h1>Apache SVN Cache Status for ",
            ap_escape_html(r->pool, ap_get_server_name(r)),
            " (via ",
            r->connection->local_ip,
            ")</h1>\n<dl>\n<dt>Server Version: ",
            ap_get_server_description(),
            "</dt>\n<dt>Current Time: ",
            ap_ht_time(r->pool, apr_time_now(), DEFAULT_TIME_FORMAT, 0),
            "</dt>\n", SVN_VA_NULL);

#if defined(WIN32) || (defined(HAVE_UNISTD_H) && defined(HAVE_GETPID))
  /* On Unix the server is generally multiple processes and this
     request only shows the status of the single process that handles
     the request. Ideally we would iterate over all processes but that
     would need some MPM support, so we settle for simply showing the
     process ID. */
  ap_rprintf(r, "<dt>Server process id: %d</dt>\n", (int)getpid());
#endif

  for (i = 0; i < lines->nelts; ++i)
    {
      const char *line = APR_ARRAY_IDX(lines, i, const char *);
      ap_rvputs(r, "<dt>", line, "</dt>\n", SVN_VA_NULL);
    }

  ap_rvputs(r, "</dl></body></html>\n", SVN_VA_NULL);

  return 0;
}
コード例 #7
0
ファイル: mod_xmlent.c プロジェクト: CloCkWeRX/Evergreen
/* Handles the character data */
static void XMLCALL charHandler( void* userData, const XML_Char* s, int len ) {
	ap_filter_t* filter = (ap_filter_t*) userData;
	char data[len+1];
	memset( data, '\0', sizeof(data) );
	memcpy( data, s, len );

	xmlEntConfig* config = ap_get_module_config( 
			filter->r->per_dir_config, &xmlent_module );

	if( xmlEntInScript && ! config->escapeScript ) {
		_fwrite( filter, "%s", data );

	} else {
		char* escaped = ap_escape_html(filter->r->pool, data);
		_fwrite( filter, "%s", escaped );
	} 
}
コード例 #8
0
ファイル: mod_idlchunk.c プロジェクト: atz/OpenILS-Evergreen
/* cycles through the attributes attached to an element */
static void printAttr( ap_filter_t* filter, const char** atts ) {
	if(!atts) return;
	int i;
	for( i = 0; atts[i] && atts[i+1]; i++ ) {
		const char* name = atts[i];
		const char* value = atts[i+1];
		char* escaped = ap_escape_html(filter->r->pool, value); 

		/* we make a big assumption here that if the string contains a ', 
		 * then the original attribute was wrapped in "s - so recreate that */
		if( strchr( escaped, '\'' ) ) {
			OSRF_UTILS_REPLACE_CHAR(escaped,'"','\'');
			_fwrite( filter, " %s=\"%s\"", name, escaped );

		} else {
			OSRF_UTILS_REPLACE_CHAR(escaped,'\'','"');
			_fwrite( filter, " %s='%s'", name, escaped );
		}

		i++;
	}
}
コード例 #9
0
ファイル: mod_speling.c プロジェクト: svn2github/apache-httpd
static int check_speling(request_rec *r)
{
    spconfig *cfg;
    char *good, *bad, *postgood, *url;
    apr_finfo_t dirent;
    int filoc, dotloc, urlen, pglen;
    apr_array_header_t *candidates = NULL;
    apr_dir_t          *dir;

    cfg = ap_get_module_config(r->per_dir_config, &speling_module);
    if (!cfg->enabled) {
        return DECLINED;
    }

    /* We only want to worry about GETs */
    if (r->method_number != M_GET) {
        return DECLINED;
    }

    /* We've already got a file of some kind or another */
    if (r->finfo.filetype != APR_NOFILE) {
        return DECLINED;
    }

    /* Not a file request */
    if (r->proxyreq || !r->filename) {
        return DECLINED;
    }

    /* This is a sub request - don't mess with it */
    if (r->main) {
        return DECLINED;
    }

    /*
     * The request should end up looking like this:
     * r->uri: /correct-url/mispelling/more
     * r->filename: /correct-file/mispelling r->path_info: /more
     *
     * So we do this in steps. First break r->filename into two pieces
     */

    filoc = ap_rind(r->filename, '/');
    /*
     * Don't do anything if the request doesn't contain a slash, or
     * requests "/"
     */
    if (filoc == -1 || strcmp(r->uri, "/") == 0) {
        return DECLINED;
    }

    /* good = /correct-file */
    good = apr_pstrndup(r->pool, r->filename, filoc);
    /* bad = mispelling */
    bad = apr_pstrdup(r->pool, r->filename + filoc + 1);
    /* postgood = mispelling/more */
    postgood = apr_pstrcat(r->pool, bad, r->path_info, NULL);

    urlen = strlen(r->uri);
    pglen = strlen(postgood);

    /* Check to see if the URL pieces add up */
    if (strcmp(postgood, r->uri + (urlen - pglen))) {
        return DECLINED;
    }

    /* url = /correct-url */
    url = apr_pstrndup(r->pool, r->uri, (urlen - pglen));

    /* Now open the directory and do ourselves a check... */
    if (apr_dir_open(&dir, good, r->pool) != APR_SUCCESS) {
        /* Oops, not a directory... */
        return DECLINED;
    }

    candidates = apr_array_make(r->pool, 2, sizeof(misspelled_file));

    dotloc = ap_ind(bad, '.');
    if (dotloc == -1) {
        dotloc = strlen(bad);
    }

    while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dir) == APR_SUCCESS) {
        sp_reason q;

        /*
         * If we end up with a "fixed" URL which is identical to the
         * requested one, we must have found a broken symlink or some such.
         * Do _not_ try to redirect this, it causes a loop!
         */
        if (strcmp(bad, dirent.name) == 0) {
            apr_dir_close(dir);
            return OK;
        }

        /*
         * miscapitalization errors are checked first (like, e.g., lower case
         * file, upper case request)
         */
        else if (strcasecmp(bad, dirent.name) == 0) {
            misspelled_file *sp_new;

            sp_new = (misspelled_file *) apr_array_push(candidates);
            sp_new->name = apr_pstrdup(r->pool, dirent.name);
            sp_new->quality = SP_MISCAPITALIZED;
        }

        /*
         * simple typing errors are checked next (like, e.g.,
         * missing/extra/transposed char)
         */
        else if ((cfg->check_case_only == 0)
                 && ((q = spdist(bad, dirent.name)) != SP_VERYDIFFERENT)) {
            misspelled_file *sp_new;

            sp_new = (misspelled_file *) apr_array_push(candidates);
            sp_new->name = apr_pstrdup(r->pool, dirent.name);
            sp_new->quality = q;
        }

        /*
         * The spdist() should have found the majority of the misspelled
         * requests.  It is of questionable use to continue looking for
         * files with the same base name, but potentially of totally wrong
         * type (index.html <-> index.db).
         *
         * If you're using MultiViews, and have a file named foobar.html,
         * which you refer to as "foobar", and someone tried to access
         * "Foobar", without CheckBasenameMatch, mod_speling won't find it,
         * because it won't find anything matching that spelling.
         * With the extension-munging, it would locate "foobar.html".
         */
        else if ((cfg->check_case_only == 0) &&
                 (cfg->check_basename_match == 1)) {
            /*
             * Okay... we didn't find anything. Now we take out the hard-core
             * power tools. There are several cases here. Someone might have
             * entered a wrong extension (.htm instead of .html or vice
             * versa) or the document could be negotiated. At any rate, now
             * we just compare stuff before the first dot. If it matches, we
             * figure we got us a match. This can result in wrong things if
             * there are files of different content types but the same prefix
             * (e.g. foo.gif and foo.html) This code will pick the first one
             * it finds. Better than a Not Found, though.
             */
            int entloc = ap_ind(dirent.name, '.');
            if (entloc == -1) {
                entloc = strlen(dirent.name);
            }

            if ((dotloc == entloc)
                && !strncasecmp(bad, dirent.name, dotloc)) {
                misspelled_file *sp_new;

                sp_new = (misspelled_file *) apr_array_push(candidates);
                sp_new->name = apr_pstrdup(r->pool, dirent.name);
                sp_new->quality = SP_VERYDIFFERENT;
            }
        }
    }
    apr_dir_close(dir);

    if (candidates->nelts != 0) {
        /* Wow... we found us a mispelling. Construct a fixed url */
        char *nuri;
        const char *ref;
        misspelled_file *variant = (misspelled_file *) candidates->elts;
        int i;

        ref = apr_table_get(r->headers_in, "Referer");

        qsort((void *) candidates->elts, candidates->nelts,
              sizeof(misspelled_file), sort_by_quality);

        /*
         * Conditions for immediate redirection:
         *     a) the first candidate was not found by stripping the suffix
         * AND b) there exists only one candidate OR the best match is not
         *        ambiguous
         * then return a redirection right away.
         */
        if (variant[0].quality != SP_VERYDIFFERENT
            && (candidates->nelts == 1
                || variant[0].quality != variant[1].quality)) {

            nuri = ap_escape_uri(r->pool, apr_pstrcat(r->pool, url,
                                                     variant[0].name,
                                                     r->path_info, NULL));
            if (r->parsed_uri.query)
                nuri = apr_pstrcat(r->pool, nuri, "?", r->parsed_uri.query, NULL);

            apr_table_setn(r->headers_out, "Location",
                          ap_construct_url(r->pool, nuri, r));

            ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS,
                          r,
                          ref ? "Fixed spelling: %s to %s from %s"
                              : "Fixed spelling: %s to %s%s",
                          r->uri, nuri,
                          (ref ? ref : ""));

            return HTTP_MOVED_PERMANENTLY;
        }
        /*
         * Otherwise, a "[300] Multiple Choices" list with the variants is
         * returned.
         */
        else {
            apr_pool_t *p;
            apr_table_t *notes;
            apr_pool_t *sub_pool;
            apr_array_header_t *t;
            apr_array_header_t *v;


            if (r->main == NULL) {
                p = r->pool;
                notes = r->notes;
            }
            else {
                p = r->main->pool;
                notes = r->main->notes;
            }

            if (apr_pool_create(&sub_pool, p) != APR_SUCCESS)
                return DECLINED;

            t = apr_array_make(sub_pool, candidates->nelts * 8 + 8,
                              sizeof(char *));
            v = apr_array_make(sub_pool, candidates->nelts * 5,
                              sizeof(char *));

            /* Generate the response text. */

            *(const char **)apr_array_push(t) =
                          "The document name you requested (<code>";
            *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, r->uri);
            *(const char **)apr_array_push(t) =
                           "</code>) could not be found on this server.\n"
                           "However, we found documents with names similar "
                           "to the one you requested.<p>"
                           "Available documents:\n<ul>\n";

            for (i = 0; i < candidates->nelts; ++i) {
                char *vuri;
                const char *reason;

                reason = sp_reason_str[(int) (variant[i].quality)];
                /* The format isn't very neat... */
                vuri = apr_pstrcat(sub_pool, url, variant[i].name, r->path_info,
                                  (r->parsed_uri.query != NULL) ? "?" : "",
                                  (r->parsed_uri.query != NULL)
                                      ? r->parsed_uri.query : "",
                                  NULL);
                *(const char **)apr_array_push(v) = "\"";
                *(const char **)apr_array_push(v) = ap_escape_uri(sub_pool, vuri);
                *(const char **)apr_array_push(v) = "\";\"";
                *(const char **)apr_array_push(v) = reason;
                *(const char **)apr_array_push(v) = "\"";

                *(const char **)apr_array_push(t) = "<li><a href=\"";
                *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, vuri);
                *(const char **)apr_array_push(t) = "\">";
                *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, vuri);
                *(const char **)apr_array_push(t) = "</a> (";
                *(const char **)apr_array_push(t) = reason;
                *(const char **)apr_array_push(t) = ")\n";

                /*
                 * when we have printed the "close matches" and there are
                 * more "distant matches" (matched by stripping the suffix),
                 * then we insert an additional separator text to suggest
                 * that the user LOOK CLOSELY whether these are really the
                 * files she wanted.
                 */
                if (i > 0 && i < candidates->nelts - 1
                    && variant[i].quality != SP_VERYDIFFERENT
                    && variant[i + 1].quality == SP_VERYDIFFERENT) {
                    *(const char **)apr_array_push(t) =
                                   "</ul>\nFurthermore, the following related "
                                   "documents were found:\n<ul>\n";
                }
            }
            *(const char **)apr_array_push(t) = "</ul>\n";

            /* If we know there was a referring page, add a note: */
            if (ref != NULL) {
                *(const char **)apr_array_push(t) =
                               "Please consider informing the owner of the "
                               "<a href=\"";
                *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, ref);
                *(const char **)apr_array_push(t) = "\">referring page</a> "
                               "about the broken link.\n";
            }


            /* Pass our apr_table_t to http_protocol.c (see mod_negotiation): */
            apr_table_setn(notes, "variant-list", apr_array_pstrcat(p, t, 0));

            apr_table_mergen(r->subprocess_env, "VARIANTS",
                            apr_array_pstrcat(p, v, ','));

            apr_pool_destroy(sub_pool);

            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                         ref ? "Spelling fix: %s: %d candidates from %s"
                             : "Spelling fix: %s: %d candidates%s",
                         r->uri, candidates->nelts,
                         (ref ? ref : ""));

            return HTTP_MULTIPLE_CHOICES;
        }
    }

    return OK;
}
コード例 #10
0
ファイル: util_script.c プロジェクト: Alivx/apache2nginx
AP_DECLARE(void) ap_add_common_vars(request_rec *r)
{
    apr_table_t *e;
    server_rec *s = r->server;
    conn_rec *c = r->connection;
    const char *rem_logname;
    char *env_path;
#if defined(WIN32) || defined(OS2) || defined(BEOS)
    char *env_temp;
#endif
    const char *host;
    const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
    const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
    int i;
    apr_port_t rport;

    /* use a temporary apr_table_t which we'll overlap onto
     * r->subprocess_env later
     * (exception: if r->subprocess_env is empty at the start,
     * write directly into it)
     */
    if (apr_is_empty_table(r->subprocess_env)) {
        e = r->subprocess_env;
    }
    else {
        e = apr_table_make(r->pool, 25 + hdrs_arr->nelts);
    }

    /* First, add environment vars from headers... this is as per
     * CGI specs, though other sorts of scripting interfaces see
     * the same vars...
     */

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key) {
            continue;
        }

        /* A few headers are special cased --- Authorization to prevent
         * rogue scripts from capturing passwords; content-type and -length
         * for no particular reason.
         */

        if (!strcasecmp(hdrs[i].key, "Content-type")) {
            apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
        }
        else if (!strcasecmp(hdrs[i].key, "Content-length")) {
            apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
        }
        /*
         * You really don't want to disable this check, since it leaves you
         * wide open to CGIs stealing passwords and people viewing them
         * in the environment with "ps -e".  But, if you must...
         */
#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
        else if (!strcasecmp(hdrs[i].key, "Authorization")
                 || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
            continue;
        }
#endif
        else {
            apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
        }
    }

    if (!(env_path = getenv("PATH"))) {
        env_path = DEFAULT_PATH;
    }
    apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path));

#ifdef WIN32
    if ((env_temp = getenv("SystemRoot")) != NULL) {
        apr_table_addn(e, "SystemRoot", env_temp);
    }
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("PATHEXT")) != NULL) {
        apr_table_addn(e, "PATHEXT", env_temp);
    }
    if ((env_temp = getenv("WINDIR")) != NULL) {
        apr_table_addn(e, "WINDIR", env_temp);
    }
#endif

#ifdef OS2
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("ETC")) != NULL) {
        apr_table_addn(e, "ETC", env_temp);
    }
    if ((env_temp = getenv("DPATH")) != NULL) {
        apr_table_addn(e, "DPATH", env_temp);
    }
    if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
        apr_table_addn(e, "PERLLIB_PREFIX", env_temp);
    }
#endif

#ifdef BEOS
    if ((env_temp = getenv("LIBRARY_PATH")) != NULL) {
        apr_table_addn(e, "LIBRARY_PATH", env_temp);
    }
#endif

    apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
    apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner());
    apr_table_addn(e, "SERVER_NAME",
                   ap_escape_html(r->pool, ap_get_server_name(r)));
    apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip);  /* Apache */
    apr_table_addn(e, "SERVER_PORT",
                  apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
    host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL);
    if (host) {
        apr_table_addn(e, "REMOTE_HOST", host);
    }
    apr_table_addn(e, "REMOTE_ADDR", c->remote_ip);
    apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
    apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
    apr_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */

    rport = c->remote_addr->port;
    apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));

    if (r->user) {
        apr_table_addn(e, "REMOTE_USER", r->user);
    }
    else if (r->prev) {
        request_rec *back = r->prev;

        while (back) {
            if (back->user) {
                apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user);
                break;
            }
            back = back->prev;
        }
    }
    if (r->ap_auth_type) {
        apr_table_addn(e, "AUTH_TYPE", r->ap_auth_type);
    }
    rem_logname = ap_get_remote_logname(r);
    if (rem_logname) {
        apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname));
    }

    /* Apache custom error responses. If we have redirected set two new vars */

    if (r->prev) {
        if (r->prev->args) {
            apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
        }
        if (r->prev->uri) {
            apr_table_addn(e, "REDIRECT_URL", r->prev->uri);
        }
    }

    if (e != r->subprocess_env) {
      apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
    }
}
コード例 #11
0
ファイル: factory.c プロジェクト: monnerat/mod_badge
int
badge_factory_handler(request_rec * r)

{
	apr_array_header_t * keys;
	badge_entry * * bep;
	badge_entry * e;
	badge_data b;
	badge_timestamp from;
	badge_timestamp to;
	const char * key_file;
	const char * verify;
	const char * badge;
	int errflags;
	char * myself;
	int i;

	keys = badge_unique_key_files(r->pool,
	    ap_get_module_config(r->per_dir_config, &badge_module));

	/**
	***	Check parameters: if all are OK, display the result page.
	***	Else show the input form.
	***
	***	Parameters:
	***		from-year	UTC YYYY
	***		from-month	UTC MM
	***		from-day	UTC DD
	***		from-hour	UTC HH
	***		from-min	UTC MM
	***		from-sec	UTC SS
	***		to-year		UTC YYYY
	***		to-month	UTC MM
	***		to-day		UTC DD
	***		to-hour		UTC HH
	***		to-min		UTC MM
	***		to-sec		UTC SS
	***		key-file	Key/certificate file path name.
	***		path-prefix	Path prefix replacement.
	***		username	Auth user name.	optional
	***		password	Password	optional
	***		verify		Password	(should match).
	**/

	badge_parse_query(r,
	    "from-year",	&from.year,	1,
	    "from-month",	&from.month,	1,
	    "from-day",		&from.day,	1,
	    "from-hour",	&from.hour,	1,
	    "from-min",		&from.min,	1,
	    "from-sec",		&from.sec,	1,
	    "to-year",		&to.year,	1,
	    "to-month",		&to.month,	1,
	    "to-day",		&to.day,	1,
	    "to-hour",		&to.hour,	1,
	    "to-min",		&to.min,	1,
	    "to-sec",		&to.sec,	1,
	    "key-file",		&key_file,	1,
	    "path-prefix",	&b.path,	1,
	    "username",		&b.user,	1,
	    "password",		&b.passwd,	0,
	    "verify",		&verify,	0,
	    NULL);

	/**
	***	Check validity of arguments.
	**/

	errflags = 0;
	e = NULL;

	if (r->args) {
		errflags |= badge_get_time_arg(&b.from, &from,
		    BADGE_FROM_YEAR, BADGE_FROM_MONTH, BADGE_FROM_DAY,
		    BADGE_FROM_HOUR, BADGE_FROM_MIN, BADGE_FROM_SEC);
		errflags |= badge_get_time_arg(&b.to, &to,
		    BADGE_TO_YEAR, BADGE_TO_MONTH, BADGE_TO_DAY,
		    BADGE_TO_HOUR, BADGE_TO_MIN, BADGE_TO_SEC);

		if (!errflags && b.from > b.to)
			errflags |= BADGE_FROM_YEAR | BADGE_FROM_MONTH |
			    BADGE_FROM_DAY | BADGE_FROM_HOUR |
			    BADGE_FROM_MIN | BADGE_FROM_SEC |
			    BADGE_TO_YEAR | BADGE_TO_MONTH |
			    BADGE_TO_DAY | BADGE_TO_HOUR |
			    BADGE_TO_MIN | BADGE_TO_SEC;

		if (!b.path || !*b.path)
			errflags |= BADGE_PATH_PREFIX;

		bep = (badge_entry * *) keys->elts;

		if (key_file) {
			errflags |= BADGE_KEY_FILE;

			for (i = 0; i < keys->nelts; i++) {
				if (!strcmp(key_file, (e = *bep)->sslfile)) {
					errflags &= ~BADGE_KEY_FILE;
					break;
					}

				bep++;
				}
			}
		else if (keys->nelts == 1)
			key_file = (e = *bep)->sslfile;
		else
			errflags |= BADGE_KEY_FILE;

		if (!b.user)
			b.user = "";

		if (strchr(b.user, ':'))
			errflags |= BADGE_USERNAME;

		if (!b.passwd)
			b.passwd = "";

		if (!verify)
			verify = "";

		if (strcmp(b.passwd, verify))
			errflags |= BADGE_PASSWORD;

		if (!*b.user && *b.passwd)
			errflags |= BADGE_USERNAME | BADGE_PASSWORD;
		}

	/**
	***	Start the output page.
	**/

	myself = ap_escape_html(r->pool, r->uri);
	ap_set_content_type(r, "text/html");
	ap_rvputs(r, DOCTYPE_HTML_4_0S,
	    "<html>\n",
	    " <head>\n",
	    "  <title>Generate a badge</title>\n",
	    "  <style type=\"text/css\">\n",
	    "   <!--\n",
	    "    .err { background-color: red; }\n",
	    "   -->\n",
	    "  </style>\n",
	    " </head>\n",
	    " <body>\n",
	    "<h1>Generate a badge</h1>\n", NULL);

	/**
	***	If we do have all necessary information, generate a badge.
	**/

	if (!errflags && b.path) {
		b.path = badge_canonicalize_path(r->pool, NULL, b.path) + 1;
		badge = badge_encode(r->pool, &b, e);
		}
	else {
		badge = NULL;
		ap_rvputs(r,
		    "<form method=\"get\" action=\"", myself, "\">\n", NULL);
		}

	/**
	***	Display badge data or input form.
	**/

	badge_show(r, &b, badge, key_file, verify, &from, &to, keys, errflags);

	if (!badge) {
		if (errflags)
			ap_rvputs(r, "<br /><p><span", badge_arg_err(1),
			    ">Please fix the highlighted field(s) and",
			    " retry</span></p>\n", NULL);

		ap_rvputs(r,
		    "<input type=\"submit\" value=\"Generate\" />",
		    "</form>\n", NULL);
		}
	else
		ap_rvputs(r,
		    "<a href=\"", ap_escape_html(r->pool, r->uri),
		    "\">Generate another badge</a>\n", NULL);

	ap_rvputs(r, " </body>\n", "</html>\n", NULL);
	return OK;
}
コード例 #12
0
ファイル: util_script.c プロジェクト: MichealYangGitHub/C
AP_DECLARE(void) ap_add_common_vars(request_rec *r)
{
    apr_table_t *e;
    server_rec *s = r->server;
    conn_rec *c = r->connection;
    core_dir_config *conf =
        (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
    const char *env_temp;
    const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
    const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
    int i;
    apr_port_t rport;
    char *q;

    /* use a temporary apr_table_t which we'll overlap onto
     * r->subprocess_env later
     * (exception: if r->subprocess_env is empty at the start,
     * write directly into it)
     */
    if (apr_is_empty_table(r->subprocess_env)) {
        e = r->subprocess_env;
    }
    else {
        e = apr_table_make(r->pool, 25 + hdrs_arr->nelts);
    }

    /* First, add environment vars from headers... this is as per
     * CGI specs, though other sorts of scripting interfaces see
     * the same vars...
     */

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key) {
            continue;
        }

        /* A few headers are special cased --- Authorization to prevent
         * rogue scripts from capturing passwords; content-type and -length
         * for no particular reason.
         */

        if (!strcasecmp(hdrs[i].key, "Content-type")) {
            apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
        }
        else if (!strcasecmp(hdrs[i].key, "Content-length")) {
            apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
        }
        /*
         * You really don't want to disable this check, since it leaves you
         * wide open to CGIs stealing passwords and people viewing them
         * in the environment with "ps -e".  But, if you must...
         */
#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
        else if (!strcasecmp(hdrs[i].key, "Authorization")
                 || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
            if (conf->cgi_pass_auth == AP_CGI_PASS_AUTH_ON) {
                add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
            }
        }
#endif
        else
            add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
    }

    env_temp = apr_table_get(r->subprocess_env, "PATH");
    if (env_temp == NULL) {
        env_temp = getenv("PATH");
    }
    if (env_temp == NULL) {
        env_temp = DEFAULT_PATH;
    }
    apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp));

#if defined(WIN32)
    env2env(e, "SystemRoot");
    env2env(e, "COMSPEC");
    env2env(e, "PATHEXT");
    env2env(e, "WINDIR");
#elif defined(OS2)
    env2env(e, "COMSPEC");
    env2env(e, "ETC");
    env2env(e, "DPATH");
    env2env(e, "PERLLIB_PREFIX");
#elif defined(BEOS)
    env2env(e, "LIBRARY_PATH");
#elif defined(DARWIN)
    env2env(e, "DYLD_LIBRARY_PATH");
#elif defined(_AIX)
    env2env(e, "LIBPATH");
#elif defined(__HPUX__)
    /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
    env2env(e, "SHLIB_PATH");
    env2env(e, "LD_LIBRARY_PATH");
#else /* Some Unix */
    env2env(e, "LD_LIBRARY_PATH");
#endif

    apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
    apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner());
    apr_table_addn(e, "SERVER_NAME",
                   ap_escape_html(r->pool, ap_get_server_name_for_url(r)));
    apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip);  /* Apache */
    apr_table_addn(e, "SERVER_PORT",
                  apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
    add_unless_null(e, "REMOTE_HOST",
                    ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL));
    apr_table_addn(e, "REMOTE_ADDR", r->useragent_ip);
    apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
    apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r));
    apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r));
    apr_table_addn(e, "CONTEXT_DOCUMENT_ROOT", ap_context_document_root(r));
    apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
    if (apr_table_get(r->notes, "proxy-noquery") && (q = ap_strchr(r->filename, '?'))) {
        *q = '\0';
        apr_table_addn(e, "SCRIPT_FILENAME", apr_pstrdup(r->pool, r->filename));
        *q = '?';
    }
    else {
        apr_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */
    }

    rport = c->client_addr->port;
    apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));

    if (r->user) {
        apr_table_addn(e, "REMOTE_USER", r->user);
    }
    else if (r->prev) {
        request_rec *back = r->prev;

        while (back) {
            if (back->user) {
                apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user);
                break;
            }
            back = back->prev;
        }
    }
    add_unless_null(e, "AUTH_TYPE", r->ap_auth_type);
    env_temp = ap_get_remote_logname(r);
    if (env_temp) {
        apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, env_temp));
    }

    /* Apache custom error responses. If we have redirected set two new vars */

    if (r->prev) {
        /* PR#57785: reconstruct full URL here */
        apr_uri_t *uri = &r->prev->parsed_uri;
        if (!uri->scheme) {
            uri->scheme = (char*)ap_http_scheme(r->prev);
        }
        if (!uri->port) {
            uri->port = ap_get_server_port(r->prev);
            uri->port_str = apr_psprintf(r->pool, "%u", uri->port);
        }
        if (!uri->hostname) {
            uri->hostname = (char*)ap_get_server_name_for_url(r->prev);
        }
        add_unless_null(e, "REDIRECT_QUERY_STRING", r->prev->args);
        add_unless_null(e, "REDIRECT_URL",
                        apr_uri_unparse(r->pool, uri, 0));
    }

    if (e != r->subprocess_env) {
        apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
    }
}
コード例 #13
0
ファイル: article.c プロジェクト: allthingsgo/mod_virgule
/**
 * article_generic_submit_serve: Submit article or reply.
 * @vr: The #VirguleReq context.
 * @title: Title, as raw text.
 * @lead: Lead, as raw text.
 * @body: Body, as raw text.
 * @olddate: Null for new posts. Original post date for edit of existing post
 * @oldkey: Null for new posts. Original article/reply key for edits
 * @submit_type: "article" or "reply".
 * @key_base: Base pathname of db key.
 * @key_suffix: Suffix of db key, after article number.
 * @art_num_str: The article number being replied to, or NULL if article.
 *
 * Submits article or reply.
 *
 * Return value: Response code.
 *
 * ToDo: There are a lot potential conflicts between char and xmlChar 
 * pointers that should be resolved to make the code more consistent.
 **/
static int
article_generic_submit_serve (VirguleReq *vr,
			      const char *topic,
			      const char *title, 
			      const char *lead, 
			      const char *body,
			      const char *olddate,
			      const char *oldkey,
			      const char *submit_type,
			      const char *key_base, 
			      const char *key_suffix,
			      const char *art_num_str)
{
  apr_pool_t *p = vr->r->pool;
  apr_table_t *args;
  Buffer *b = NULL;
  const Topic **t;
  const char *date;
  char *key;
  xmlDoc *doc;
  xmlNode *root;
  xmlNode *tree;
  int status;
  char *str = NULL;
  char *lead_error, *body_error;
  char *nice_title;
  char *nice_lead;
  char *nice_body;

  virgule_auth_user (vr);
  if (vr->u == NULL)
    return virgule_send_error_page (vr, vERROR, "forbidden", "You can't post <x>an article</x> because you're not logged in.");

  if (!virgule_req_ok_to_reply (vr))
    return virgule_send_error_page (vr, vERROR, "forbidden", "You can't post because you're not certified. Please see the <a href=\"%s/certs.html\">certification overview</a> for more details.", vr->prefix);

  date = virgule_iso_now (p);

  if (title == NULL || title[0] == 0)
    return virgule_send_error_page (vr, vERROR, "Need title", "Your <x>%s</x> needs a title. Go back and try again.", submit_type);
  if (!strcmp (submit_type, "article") && (lead == NULL || lead[0] == 0))
    return virgule_send_error_page (vr, vERROR, "Need lead", "Your <x>article</x> needs a lead. Go back and try again.");
  if (!strcmp (submit_type, "reply") && (body == NULL || body[0] == 0))
    return virgule_send_error_page (vr, vERROR, "Need body", "Your reply needs a body. Go back and try again.");

  nice_title = virgule_nice_text (p, title);
  nice_lead = lead == NULL ? "" : virgule_nice_htext (vr, lead, &lead_error);
  nice_body = body == NULL ? "" : virgule_nice_htext (vr, body, &body_error);

  args = virgule_get_args_table (vr);
  if(olddate != NULL)
    apr_table_set (args, "preview", "Preview");
  else
    olddate = apr_table_get (args, "olddate");
  if(oldkey == NULL)
    oldkey = apr_table_get (args, "oldkey");

  if (apr_table_get (args, "preview"))
    {
      /* render a preview */
      if (virgule_set_temp_buffer (vr) != 0)
        return HTTP_INTERNAL_SERVER_ERROR;

      b = vr->b;

      if (!strcmp (submit_type, "reply"))
	{
          str = apr_pstrdup (p, "Reply preview");
	  virgule_render_cert_level_begin (vr, vr->u, CERT_STYLE_MEDIUM);
	  virgule_buffer_printf (b, "<font size=+2><b>%s</b></font><br>\n", nice_title);
	  virgule_render_cert_level_end (vr, CERT_STYLE_MEDIUM);
	  virgule_buffer_printf (b, "<p>%s</p>\n", nice_body);
	  virgule_buffer_puts (b, "<hr>\n");
	  virgule_buffer_printf (b, "<p>Edit your reply:</p>\n"
			 "<form method=\"POST\" action=\"replysubmit.html\" accept-charset=\"UTF-8\">\n"
			 "<p><x>Article</x> title: <br>\n"
			 "<input type=\"text\" name=\"title\" value=\"%s\" size=\"40\" maxlength=\"60\"></p>\n"
			 "<p>Body of <x>article</x>: <br>\n"
			 "<textarea name=\"body\" cols=\"72\" rows=\"16\" wrap=\"hard\">%s"
			 "</textarea></p>\n"
			 "<input type=\"hidden\" name=\"art_num\" value=\"%s\">\n"
			 "<p><input type=\"submit\" name=\"post\" value=\"Post\">\n"
			 "<input type=\"submit\" name=\"preview\" value=\"Preview\">\n"
			 "</form>\n",
			 virgule_str_subst (p, title, "\"", "&quot;"),
			 ap_escape_html (p, body),
			 art_num_str);
	  
	  virgule_render_acceptable_html (vr);
	}
      else if (!strcmp (submit_type, "article"))
	{
          str = apr_pstrdup (p, "<x>Article</x>  preview");
	  if(vr->priv->use_article_topics)
	    {
	      virgule_buffer_puts (b, "<table><tr><td>");
              article_render_topic (vr, (char *)topic);
              virgule_buffer_puts (b, "</td><td>");
	    }
          virgule_render_cert_level_begin (vr, vr->u, CERT_STYLE_LARGE);
          virgule_buffer_printf (b, "<span class=\"article-title\">%s</span>",nice_title);
          virgule_render_cert_level_end (vr, CERT_STYLE_LARGE);
	  
	  if(vr->priv->use_article_topics)
            virgule_buffer_puts (b, "</td></tr></table>\n");

	  virgule_buffer_printf (b, "<p>%s</p>\n", nice_lead);
	  virgule_buffer_printf (b, "<p>%s</p>\n", nice_body);
	  virgule_buffer_puts (b, "<hr>\n");
	  virgule_buffer_puts (b, "<p>Edit your <x>article</x>:</p>\n"
		"<form method=\"POST\" action=\"postsubmit.html\" accept-charset=\"UTF-8\">\n");

          if(olddate && oldkey)
	    {
	      virgule_buffer_printf (b, "<input type=\"hidden\" name=\"olddate\" value=\"%s\" />\n", olddate);
	      virgule_buffer_printf (b, "<input type=\"hidden\" name=\"oldkey\" value=\"%s\" />\n", oldkey);
	    }
	    
	  if(vr->priv->use_article_topics)
	    {
	      virgule_buffer_puts (b, "<p><b><x>Article</x> topic</b>:<br>\n <select name=\"topic\">\n");

              for (t = vr->priv->topics; *t; t++)
	        virgule_buffer_printf (b, "<option%s>%s</option>\n",
		  strcmp((*t)->desc,topic) ? "" : " selected",(*t)->desc);

	      virgule_buffer_puts (b, " </select></p>\n");
	    }

	  virgule_buffer_printf (b,
			 "<p><b><x>Article</x> title</b>:<br>\n"
			 "<input type=\"text\" name=\"title\" value=\"%s\" size=\"40\" maxlength=\"%i\"></p>\n"
	        	 "<p><b><x>Article</x> lead</b>. This should be a one paragraph summary "
	    		 "of the story complete with links to the original "
	    		 "sources when appropriate.<br>"			 
			 "<textarea name=\"lead\" cols=72 rows=6 wrap=hard>%s"
			 "</textarea> </p>\n",
			 virgule_str_subst (p, title, "\"", "&quot;"),
			 vr->priv->article_title_maxsize,
			 ap_escape_html (p, lead));
	  if (lead_error != NULL)
	    virgule_buffer_printf (b, "<p><b>Warning:</b> %s</p>\n", lead_error);

	  virgule_buffer_printf (b,"<p><b><x>Article</x> Body</b>. This should "
	    		 "contain the body of your article and may be as long as "
			 "needed. If your entire article is only one paragraph, "
			 "put it in the lead field above and leave this one empty<br>"
			 "<textarea name=\"body\" cols=72 rows=16 wrap=hard>%s"
			 "</textarea></p>\n"
			 "<p><b>Warning:</b> Please proof read your article "
			 "and verify spelling and any html markup before posting. "
			 "Click the <b>Preview</b> button to see changes. Once "
			 "you click the <b>Post</b> button your article will be "
			 "posted and changes are no longer possible."
			 "<p><input type=\"submit\" name=post value=\"Post\">\n"
			 "<input type=\"submit\" name=preview value=\"Preview\">\n"
			 "</form>\n",
			 ap_escape_html (p, (body ? body : "")));
	  if (body_error != NULL)
	    virgule_buffer_printf (b, "<p><b>Warning:</b> %s </p>\n", body_error);

	  virgule_render_acceptable_html (vr);

	}
	virgule_set_main_buffer (vr);
	return virgule_render_in_template (vr, "/templates/default.xml", "content", str);
    }

  key = apr_psprintf (p, "%s/_%d%s",
		      key_base,
		      oldkey ? atoi (oldkey) : virgule_db_dir_max (vr->db, key_base) + 1,
		      key_suffix);

  doc = virgule_db_xml_doc_new (p);
  root = xmlNewDocNode (doc, NULL, (xmlChar *)"article", NULL);
  doc->xmlRootNode = root;

  if(olddate != NULL)
    {
      xmlNewChild (root, NULL, (xmlChar *)"date", (xmlChar *)olddate);
      xmlNewChild (root, NULL, (xmlChar *)"update", (xmlChar *)date);
    }
  else
    {
      tree = xmlNewChild (root, NULL, (xmlChar *)"date", (xmlChar *)date);
    }
  tree = xmlNewChild (root, NULL, (xmlChar *)"author", (xmlChar *)vr->u);

  tree = xmlNewChild (root, NULL, (xmlChar *)"title", NULL);
  xmlAddChild (tree, xmlNewDocText (doc, (xmlChar *)nice_title));

  if(vr->priv->use_article_topics)
    {
      tree = xmlNewChild (root, NULL, (xmlChar *)"topic", NULL);
      xmlAddChild (tree, xmlNewDocText (doc, (xmlChar *)topic));
    }

  if (lead && lead[0])
    {
      tree = xmlNewChild (root, NULL, (xmlChar *)"lead", NULL);
      xmlAddChild (tree, xmlNewDocText (doc, (xmlChar *)nice_lead));
    }

  if (body != NULL && body[0])
    {
      tree = xmlNewChild (root, NULL, (xmlChar *)"body", NULL);
      xmlAddChild (tree, xmlNewDocText (doc, (xmlChar *)nice_body));
    }

  /* sanity-check edit qualifications before saving */
  if (olddate || oldkey) 
    {
      char *a, *d;
      time_t t;
      xmlNodePtr r;
      int art_num = atoi (oldkey);
      char *k = apr_psprintf (vr->r->pool, "articles/_%d/article.xml", art_num);
      xmlDocPtr old = virgule_db_xml_get (vr->r->pool, vr->db, k);
      if (old == NULL)
        return virgule_send_error_page (vr, vERROR, "not found", "The specified <x>article</x> does not exist.");
      r = xmlDocGetRootElement (old);

      /* verify the article is not too old to edit */
      d = virgule_xml_find_child_string (r, "date", NULL);
      t = virgule_virgule_to_time_t (vr, d);
      if (t + (vr->priv->article_days_to_edit * 86400) < time (NULL))
        return virgule_send_error_page (vr, vERROR, "forbidden", "This <x>article</x> is too old to be edited.");

      /* verify this user can edit this article */
      a = virgule_xml_find_child_string (r, "author", NULL);
      if (strcmp (vr->u, a))
        return virgule_send_error_page (vr, vERROR, "forbidden", "Only <x>articles</x> posted by you may be edited.");
    }

  status = virgule_db_xml_put (p, vr->db, key, doc);

  if (status)
    return virgule_send_error_page (vr, vERROR,
			    "database",
			    "There was an error storing the <x>%s</x>. This means there's something wrong with the site.", submit_type);

  if (!strcmp (submit_type, "reply"))
    apr_table_add (vr->r->headers_out, "refresh", 
		  apr_psprintf(p, "0;URL=/article/%s.html#lastread", art_num_str));
  else 
    apr_table_add (vr->r->headers_out, "refresh", 
		  apr_psprintf(p, "0;URL=/article/%d.html", 
		              oldkey ? atoi (oldkey) : virgule_db_dir_max (vr->db, key_base)));

  str = apr_psprintf (p, "Ok, your <x>%s</x> was posted. Thanks!", submit_type);
  return virgule_send_error_page (vr, vINFO, "Posted", str);
}
コード例 #14
0
ファイル: util_script.c プロジェクト: kame/apache13-ipv6
API_EXPORT(void) ap_add_common_vars(request_rec *r)
{
    table *e;
    server_rec *s = r->server;
    conn_rec *c = r->connection;
    const char *rem_logname;
    char *env_path;
#if defined(WIN32) || defined(OS2)
    char *env_temp;
#endif
    const char *host;
    array_header *hdrs_arr = ap_table_elts(r->headers_in);
    table_entry *hdrs = (table_entry *) hdrs_arr->elts;
    int i;
    char servbuf[NI_MAXSERV];

    /* use a temporary table which we'll overlap onto
     * r->subprocess_env later
     */
    e = ap_make_table(r->pool, 25 + hdrs_arr->nelts);

    /* First, add environment vars from headers... this is as per
     * CGI specs, though other sorts of scripting interfaces see
     * the same vars...
     */

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key) {
	    continue;
	}

	/* A few headers are special cased --- Authorization to prevent
	 * rogue scripts from capturing passwords; content-type and -length
	 * for no particular reason.
	 */

	if (!strcasecmp(hdrs[i].key, "Content-type")) {
	    ap_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
	}
	else if (!strcasecmp(hdrs[i].key, "Content-length")) {
	    ap_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
	}
	/*
	 * You really don't want to disable this check, since it leaves you
	 * wide open to CGIs stealing passwords and people viewing them
	 * in the environment with "ps -e".  But, if you must...
	 */
#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
	else if (!strcasecmp(hdrs[i].key, "Authorization") 
		 || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
	    continue;
	}
#endif
	else {
	    ap_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
	}
    }

    if (!(env_path = ap_pstrdup(r->pool, getenv("PATH")))) {
	env_path = DEFAULT_PATH;
    }

#ifdef WIN32
    if (env_temp = getenv("SystemRoot")) {
        ap_table_addn(e, "SystemRoot", env_temp);         
    }
    if (env_temp = getenv("COMSPEC")) {
        ap_table_addn(e, "COMSPEC", env_temp);            
    }
    if (env_temp = getenv("WINDIR")) {
        ap_table_addn(e, "WINDIR", env_temp);
    }
#endif

#ifdef OS2
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        ap_table_addn(e, "COMSPEC", env_temp);            
    }
    if ((env_temp = getenv("ETC")) != NULL) {
        ap_table_addn(e, "ETC", env_temp);            
    }
    if ((env_temp = getenv("DPATH")) != NULL) {
        ap_table_addn(e, "DPATH", env_temp);            
    }
    if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
        ap_table_addn(e, "PERLLIB_PREFIX", env_temp);            
    }
#endif

    ap_table_addn(e, "PATH", env_path);
    ap_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
    ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version());
    ap_table_addn(e, "SERVER_NAME", 
		  ap_escape_html(r->pool,ap_get_server_name(r)));
    ap_table_addn(e, "SERVER_ADDR", r->connection->local_ip);	/* Apache */
    ap_table_addn(e, "SERVER_PORT",
		  ap_psprintf(r->pool, "%u", ap_get_server_port(r)));
    host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST);
    if (host) {
	ap_table_addn(e, "REMOTE_HOST", host);
    }
    ap_table_addn(e, "REMOTE_ADDR", c->remote_ip);
    ap_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));	/* Apache */
    ap_table_addn(e, "SERVER_ADMIN", s->server_admin);	/* Apache */
    ap_table_addn(e, "SCRIPT_FILENAME", r->filename);	/* Apache */

    servbuf[0] = '\0';
    if (!getnameinfo((struct sockaddr *)&c->remote_addr,
#ifndef HAVE_SOCKADDR_LEN
		     SA_LEN((struct sockaddr *)&c->remote_addr),
#else
		     c->remote_addr.ss_len,
#endif
		     NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
	ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
    }

    if (c->user) {
	ap_table_addn(e, "REMOTE_USER", c->user);
    }
    if (c->ap_auth_type) {
	ap_table_addn(e, "AUTH_TYPE", c->ap_auth_type);
    }
    rem_logname = ap_get_remote_logname(r);
    if (rem_logname) {
	ap_table_addn(e, "REMOTE_IDENT", ap_pstrdup(r->pool, rem_logname));
    }

    /* Apache custom error responses. If we have redirected set two new vars */

    if (r->prev) {
        if (r->prev->args) {
	    ap_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
	}
	if (r->prev->uri) {
	    ap_table_addn(e, "REDIRECT_URL", r->prev->uri);
	}
    }

    ap_overlap_tables(r->subprocess_env, e, AP_OVERLAP_TABLES_SET);
}
コード例 #15
0
ファイル: mod_proxy_balancer.c プロジェクト: haggaie/httpd
/* Manages the loadfactors and member status
 */
static int balancer_handler(request_rec *r)
{
    void *sconf = r->server->module_config;
    proxy_server_conf *conf = (proxy_server_conf *)
        ap_get_module_config(sconf, &proxy_module);
    proxy_balancer *balancer, *bsel = NULL;
    proxy_worker *worker, *wsel = NULL;
    apr_table_t *params = apr_table_make(r->pool, 10);
    int access_status;
    int i, n;
    const char *name;

    /* is this for us? */
    if (strcmp(r->handler, "balancer-manager"))
        return DECLINED;
    r->allowed = (AP_METHOD_BIT << M_GET);
    if (r->method_number != M_GET)
        return DECLINED;

    if (r->args) {
        char *args = apr_pstrdup(r->pool, r->args);
        char *tok, *val;
        while (args && *args) {
            if ((val = ap_strchr(args, '='))) {
                *val++ = '\0';
                if ((tok = ap_strchr(val, '&')))
                    *tok++ = '\0';
                /*
                 * Special case: workers are allowed path information
                 */
                if ((access_status = ap_unescape_url(val)) != OK)
                    if (strcmp(args, "w") || (access_status !=  HTTP_NOT_FOUND))
                        return access_status;
                apr_table_setn(params, args, val);
                args = tok;
            }
            else
                return HTTP_BAD_REQUEST;
        }
    }
    
    /* Check that the supplied nonce matches this server's nonce;
     * otherwise ignore all parameters, to prevent a CSRF attack. */
    if ((name = apr_table_get(params, "nonce")) == NULL 
        || strcmp(balancer_nonce, name) != 0) {
        apr_table_clear(params);
    }

    if ((name = apr_table_get(params, "b")))
        bsel = ap_proxy_get_balancer(r->pool, conf,
            apr_pstrcat(r->pool, "balancer://", name, NULL));
    if ((name = apr_table_get(params, "w"))) {
        proxy_worker *ws;

        ws = ap_proxy_get_worker(r->pool, conf, name);
        if (bsel && ws) {
            worker = (proxy_worker *)bsel->workers->elts;
            for (n = 0; n < bsel->workers->nelts; n++) {
                if (strcasecmp(worker->name, ws->name) == 0) {
                    wsel = worker;
                    break;
                }
                ++worker;
            }
        }
    }
    /* First set the params */
    /*
     * Note that it is not possible set the proxy_balancer because it is not
     * in shared memory.
     */
    if (wsel) {
        const char *val;
        if ((val = apr_table_get(params, "lf"))) {
            int ival = atoi(val);
            if (ival >= 1 && ival <= 100) {
                wsel->s->lbfactor = ival;
                if (bsel)
                    recalc_factors(bsel);
            }
        }
        if ((val = apr_table_get(params, "wr"))) {
            if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ)
                strcpy(wsel->s->route, val);
            else
                *wsel->s->route = '\0';
        }
        if ((val = apr_table_get(params, "rr"))) {
            if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ)
                strcpy(wsel->s->redirect, val);
            else
                *wsel->s->redirect = '\0';
        }
        if ((val = apr_table_get(params, "dw"))) {
            if (!strcasecmp(val, "Disable"))
                wsel->s->status |= PROXY_WORKER_DISABLED;
            else if (!strcasecmp(val, "Enable"))
                wsel->s->status &= ~PROXY_WORKER_DISABLED;
        }
        if ((val = apr_table_get(params, "ls"))) {
            int ival = atoi(val);
            if (ival >= 0 && ival <= 99) {
                wsel->s->lbset = ival;
             }
        }

    }
    if (apr_table_get(params, "xml")) {
        ap_set_content_type(r, "text/xml");
        ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", r);
        ap_rputs("<httpd:manager xmlns:httpd=\"http://httpd.apache.org\">\n", r);
        ap_rputs("  <httpd:balancers>\n", r);
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++) {
            ap_rputs("    <httpd:balancer>\n", r);
            ap_rvputs(r, "      <httpd:name>", balancer->name, "</httpd:name>\n", NULL);
            ap_rputs("      <httpd:workers>\n", r);
            worker = (proxy_worker *)balancer->workers->elts;
            for (n = 0; n < balancer->workers->nelts; n++) {
                ap_rputs("        <httpd:worker>\n", r);
                ap_rvputs(r, "          <httpd:scheme>", worker->scheme,
                          "</httpd:scheme>\n", NULL);
                ap_rvputs(r, "          <httpd:hostname>", worker->hostname,
                          "</httpd:hostname>\n", NULL);
               ap_rprintf(r, "          <httpd:loadfactor>%d</httpd:loadfactor>\n",
                          worker->s->lbfactor);
                ap_rputs("        </httpd:worker>\n", r);
                ++worker;
            }
            ap_rputs("      </httpd:workers>\n", r);
            ap_rputs("    </httpd:balancer>\n", r);
            ++balancer;
        }
        ap_rputs("  </httpd:balancers>\n", r);
        ap_rputs("</httpd:manager>", r);
    }
    else {
        ap_set_content_type(r, "text/html; charset=ISO-8859-1");
        ap_rputs(DOCTYPE_HTML_3_2
                 "<html><head><title>Balancer Manager</title></head>\n", r);
        ap_rputs("<body><h1>Load Balancer Manager for ", r);
        ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);
        ap_rvputs(r, "<dl><dt>Server Version: ",
                  ap_get_server_description(), "</dt>\n", NULL);
        ap_rvputs(r, "<dt>Server Built: ",
                  ap_get_server_built(), "\n</dt></dl>\n", NULL);
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++) {

            ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r);
            ap_rvputs(r, balancer->name, "</h3>\n\n", NULL);
            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
                "<th>StickySession</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"
                "</tr>\n<tr>", r);
            if (balancer->sticky) {
                ap_rvputs(r, "<td>", balancer->sticky, NULL);
            }
            else {
                ap_rputs("<td> - ", r);
            }
            ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
                apr_time_sec(balancer->timeout));
            ap_rprintf(r, "<td>%d</td>\n", balancer->max_attempts);
            ap_rprintf(r, "<td>%s</td>\n",
                       balancer->lbmethod->name);
            ap_rputs("</table>\n<br />", r);
            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
                "<th>Worker URL</th>"
                "<th>Route</th><th>RouteRedir</th>"
                "<th>Factor</th><th>Set</th><th>Status</th>"
                "<th>Elected</th><th>To</th><th>From</th>"
                "</tr>\n", r);

            worker = (proxy_worker *)balancer->workers->elts;
            for (n = 0; n < balancer->workers->nelts; n++) {
                char fbuf[50];
                ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=",
                          balancer->name + sizeof("balancer://") - 1, "&w=",
                          ap_escape_uri(r->pool, worker->name),
                          "&nonce=", balancer_nonce, 
                          "\">", NULL);
                ap_rvputs(r, worker->name, "</a></td>", NULL);
                ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route),
                          NULL);
                ap_rvputs(r, "</td><td>",
                          ap_escape_html(r->pool, worker->s->redirect), NULL);
                ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
                ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset);
                if (worker->s->status & PROXY_WORKER_DISABLED)
                   ap_rputs("Dis ", r);
                if (worker->s->status & PROXY_WORKER_IN_ERROR)
                   ap_rputs("Err ", r);
                if (worker->s->status & PROXY_WORKER_STOPPED)
                   ap_rputs("Stop ", r);
                if (worker->s->status & PROXY_WORKER_HOT_STANDBY)
                   ap_rputs("Stby ", r);
                if (PROXY_WORKER_IS_USABLE(worker))
                    ap_rputs("Ok", r);
                if (!PROXY_WORKER_IS_INITIALIZED(worker))
                    ap_rputs("-", r);
                ap_rputs("</td>", r);
                ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected);
                ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
                ap_rputs("</td><td>", r);
                ap_rputs(apr_strfsize(worker->s->read, fbuf), r);
                ap_rputs("</td></tr>\n", r);

                ++worker;
            }
            ap_rputs("</table>\n", r);
            ++balancer;
        }
        ap_rputs("<hr />\n", r);
        if (wsel && bsel) {
            ap_rputs("<h3>Edit worker settings for ", r);
            ap_rvputs(r, wsel->name, "</h3>\n", NULL);
            ap_rvputs(r, "<form method=\"GET\" action=\"", NULL);
            ap_rvputs(r, r->uri, "\">\n<dl>", NULL);
            ap_rputs("<table><tr><td>Load factor:</td><td><input name=\"lf\" type=text ", r);
            ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbfactor);
            ap_rputs("<tr><td>LB Set:</td><td><input name=\"ls\" type=text ", r);
            ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbset);
            ap_rputs("<tr><td>Route:</td><td><input name=\"wr\" type=text ", r);
            ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->route),
                      NULL);
            ap_rputs("\"></td></tr>\n", r);
            ap_rputs("<tr><td>Route Redirect:</td><td><input name=\"rr\" type=text ", r);
            ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->redirect),
                      NULL);
            ap_rputs("\"></td></tr>\n", r);
            ap_rputs("<tr><td>Status:</td><td>Disabled: <input name=\"dw\" value=\"Disable\" type=radio", r);
            if (wsel->s->status & PROXY_WORKER_DISABLED)
                ap_rputs(" checked", r);
            ap_rputs("> | Enabled: <input name=\"dw\" value=\"Enable\" type=radio", r);
            if (!(wsel->s->status & PROXY_WORKER_DISABLED))
                ap_rputs(" checked", r);
            ap_rputs("></td></tr>\n", r);
            ap_rputs("<tr><td colspan=2><input type=submit value=\"Submit\"></td></tr>\n", r);
            ap_rvputs(r, "</table>\n<input type=hidden name=\"w\" ",  NULL);
            ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->name), "\">\n", NULL);
            ap_rvputs(r, "<input type=hidden name=\"b\" ", NULL);
            ap_rvputs(r, "value=\"", bsel->name + sizeof("balancer://") - 1,
                      "\">\n", NULL);
            ap_rvputs(r, "<input type=hidden name=\"nonce\" value=\"", 
                      balancer_nonce, "\">\n", NULL);
            ap_rvputs(r, "</form>\n", NULL);
            ap_rputs("<hr />\n", r);
        }
        ap_rputs(ap_psignature("",r), r);
        ap_rputs("</body></html>\n", r);
    }
    return OK;
}
コード例 #16
0
ファイル: html.c プロジェクト: monnerat/mod_badge
void
badge_show(request_rec * r, const badge_data * b, const char * badge,
	const char * key_file, const char * verify, badge_timestamp * from,
	badge_timestamp * to, apr_array_header_t * keys, int errstatus)

{
	int isform;
	badge_entry * * bep;
	const char * cp;
	int i;

	/**
	***	Display badge data or input form.
	**/

	isform = !badge;
	ap_rvputs(r, "<table border=\"0\"><tbody>\n", NULL);

	/**
	***	Key file path entry.
	**/

	ap_rvputs(r, "<tr><td>Key file path</td>\n",
	    "<td", badge_arg_err(errstatus & BADGE_KEY_FILE), ">", NULL);

	if (!isform)
		ap_rvputs(r, ap_escape_html(r->pool, key_file), NULL);
	else {
		bep = (badge_entry * *) keys->elts;

		if (!key_file)
			key_file = (*bep)->sslfile;

		if (keys->nelts == 1) {
			cp = ap_escape_html(r->pool, key_file);
			ap_rvputs(r, "<input type=\"hidden\" name=\"key-file\"",
			    " value=\"", cp, "\" />", cp, NULL);
			}
		else {
			ap_rvputs(r, "<select name=\"key-file\">\n", NULL);

			for (i = 0; i < keys->nelts; i++) {
				ap_rvputs(r, " <option",
				    strcmp(key_file, (*bep)->sslfile)? "":
				    " selected=\"yes\"", ">",
				    ap_escape_html(r->pool, (*bep)->sslfile),
				    "</option>\n", NULL);
				bep++;
				}

			ap_rvputs(r, "</select>", NULL);
			}
		}

	ap_rvputs(r, "</td></tr>\n", NULL);

	/**
	***	Replacement path entry.
	**/

	badge_emit_text(r, "Replacement path prefix", b->path, !isform,
	    "path-prefix", 0, errstatus & BADGE_PATH_PREFIX);

	/**
	***	"Valid from" timestamp entry.
	**/

	badge_emit_timestamp(r, "from", b->from, !isform, from, errstatus,
	    BADGE_FROM_YEAR, BADGE_FROM_MONTH, BADGE_FROM_DAY,
	    BADGE_FROM_HOUR, BADGE_FROM_MIN, BADGE_FROM_SEC);

	/**
	***	"Valid to" timestamp entry.
	**/

	badge_emit_timestamp(r, "to", b->to, !isform, to, errstatus,
	    BADGE_TO_YEAR, BADGE_TO_MONTH, BADGE_TO_DAY,
	    BADGE_TO_HOUR, BADGE_TO_MIN, BADGE_TO_SEC);

	/**
	***	User name entry.
	**/

	if (isform || (b->user && *b->user))
		badge_emit_text(r, "Authentication user", b->user, !isform,
		    "username", 0, errstatus & BADGE_USERNAME);

	/**
	***	Password entry.
	**/

	if (isform || (b->user && *b->user))
		badge_emit_text(r, "Password",
		    !badge? b->passwd: b->passwd && *b->passwd? "set": "unset",
		    !isform, "password", 1, errstatus & BADGE_PASSWORD);

	/**
	***	Password verify entry.
	**/

	if (isform)
		badge_emit_text(r, "Verify password", verify, 0,
		    "verify", 1, errstatus & BADGE_PASSWORD);

	/**
	***	If a badge has been generated, show it.
	**/

	if (badge) {
		ap_rvputs(r, "<tr><td colspan=\"2\">&nbsp;</td></tr>\n", NULL);
		badge_emit_text(r, "Badge", badge, 1, "", 0, 0);
		}

	ap_rvputs(r, "</tbody></table>\n", NULL);
}
コード例 #17
0
ファイル: template.c プロジェクト: diroussel/lua-web-tools
/*
 * Renders a template.
 */
static apr_status_t render_template (render_rec *d) {
        int i, cnt;
        template_node_t *n;
        apr_status_t status;
	const char *str;
	apr_array_header_t *t_save;

	d->depth++;
	if (d->depth > TEMPLATE_MAX_DEPTH) {
		d->err = apr_psprintf(d->pool, "template depth exceeds %d",
				TEMPLATE_MAX_DEPTH);
		return APR_EGENERAL;
	}

	i = 0;
	while (i < d->t->nelts) {
		n = ((template_node_t *) d->t->elts) + i;
		switch (n->type) {
		case TEMPLATE_TJUMP:
			i = n->jump_next;
			break;

		case TEMPLATE_TIF:
			if ((status = evaluate_exp(d, n->if_index, 1))
					!= APR_SUCCESS) {
				return status;
			} 
			if (lua_toboolean(d->L, -1)) {
				i++;
			} else {
				i = n->if_next;
			}
			lua_pop(d->L, 1);
			break;

		case TEMPLATE_TFOR_INIT:
			if ((status = evaluate_exp(d, n->for_init_index, 3))
					!= APR_SUCCESS) {
				return status;
			}
			i++;
			break;

		case TEMPLATE_TFOR_NEXT:
			lua_pushvalue(d->L, -3);
			lua_pushvalue(d->L, -3);
			lua_pushvalue(d->L, -3);
			cnt = n->for_next_names->nelts;
			if (lua_pcall(d->L, 2, cnt, d->errfunc) != 0) {
				return runtime_error(d);
			}
			if (lua_isnil(d->L, -cnt)) {
				lua_pop(d->L, 3 + cnt);
				i = n->for_next_next;
			} else {
				lua_pushvalue(d->L, -cnt);
				lua_replace(d->L, -1 - cnt - 1);
				while (cnt > 0) {
					cnt--;
					lua_setglobal(d->L, ((const char **)
							n->for_next_names
							->elts)[cnt]);
				}
				i++;
			}
			break;

		case TEMPLATE_TSET:
			cnt = n->set_names->nelts;
			if ((status = evaluate_exp(d, n->set_index, cnt))
					!= APR_SUCCESS) {
				return status;
			}
			while (cnt > 0) {
				cnt--;
				lua_setglobal(d->L, ((const char **)
						n->set_names->elts)[cnt]);
			}
			i++;
			break;
 
		case TEMPLATE_TINCLUDE:
			if ((status = evaluate_exp_str(d, n->include_index))
					!= APR_SUCCESS) {
				return status;
			}
			str = lua_tostring(d->L, -1);
			lua_pop(d->L, 1);
			t_save = d->t;
			d->t = (apr_array_header_t *) apr_hash_get(d->templates,
					str, strlen(str));
			if (d->t == NULL) {
				if ((status = lwt_template_parse(str, d->L,
						n->include_flags, d->pool,
						&d->t, &d->err))
						!= APR_SUCCESS) {
					return status;
				}
				apr_hash_set(d->templates, str, strlen(str),
						d->t);
			}
			if ((status = render_template(d)) != APR_SUCCESS) {
				return status;
			}
			d->t = t_save;
			i++;
			break;			

		case TEMPLATE_TSUB:
			lua_rawgeti(d->L, LUA_REGISTRYINDEX, n->sub_index);
			switch (lua_pcall(d->L, 0, 1, d->errfunc)) {
			case 0:
				if (lua_isstring(d->L, -1)) {
					str = lua_tostring(d->L, -1);
				} else if (lua_isnil(d->L, -1) && (n->sub_flags
						& TEMPLATE_FSUPNIL)) {
					str = "";
				} else {
					str = apr_psprintf(d->pool, "(%s)",
							luaL_typename(d->L,
							-1));
				}
				break;

			case LUA_ERRRUN:
				if (n->sub_flags & TEMPLATE_FSUPERR) {
					str = "";
				} else {
					return runtime_error(d);
				}
				break;

			default:
				return runtime_error(d);
			}
			lua_pop(d->L, 1);
			if (n->sub_flags & TEMPLATE_FESCURL) {
				str = lwt_util_escape_uri(d->pool, str);
			}
			if (n->sub_flags & TEMPLATE_FESCXML) {
				str = ap_escape_html(d->pool, str);
			}
			if (n->sub_flags & TEMPLATE_FESCJS) {
				str = lwt_util_escape_js(d->pool, str);
			}
			fputs(str, d->f);
			i++;
			break;

		case TEMPLATE_TRAW:
			fwrite(n->raw_str, n->raw_len, 1, d->f);
			i++;
			break;
		}
	}

	d->depth--;

	return APR_SUCCESS;
}